Chandra

 view release on metacpan or  search on metacpan

xs/form.xs  view on Meta::CPAN

    AV *fields;
    I32 i, len;
    SV *html;
    const char *form_id;
    STRLEN form_id_len;
    char *cur_group = NULL;
    int in_fieldset = 0;

    form_id = SvPV(*id_svp, form_id_len);
    fields = (AV *)SvRV(*fields_svp);
    len = av_len(fields);

    html = newSVpvs("<form class=\"chandra-form");
    if (cls_svp && SvOK(*cls_svp)) {
        sv_catpvs(html, " ");
        sv_catsv(html, *cls_svp);
    }
    sv_catpvs(html, "\" id=\"");
    {
        SV *esc_id = _elem_escape_attr(aTHX_ form_id, form_id_len);
        sv_catsv(html, esc_id);
        SvREFCNT_dec(esc_id);
    }
    sv_catpvs(html, "\">");

    for (i = 0; i <= len; i++) {
        SV **fref = av_fetch(fields, i, 0);
        HV *fhv;
        SV **type_svp, **name_svp, **opts_svp, **grp_svp;
        const char *type, *name;
        STRLEN type_len, name_len;
        HV *opts;
        char fid[128];
        int fid_len;
        SV *field_html = NULL;

        if (!fref || !SvROK(*fref)) continue;
        fhv = (HV *)SvRV(*fref);

        type_svp = hv_fetchs(fhv, "type", 0);
        name_svp = hv_fetchs(fhv, "name", 0);
        opts_svp = hv_fetchs(fhv, "opts", 0);
        if (!type_svp || !name_svp) continue;

        type = SvPV(*type_svp, type_len);
        name = SvPV(*name_svp, name_len);
        opts = (opts_svp && SvROK(*opts_svp)) ? (HV *)SvRV(*opts_svp) : newHV();

        /* Generate field id */
        fid_len = my_snprintf(fid, sizeof(fid), "%.*s-%.*s",
                              (int)form_id_len, form_id,
                              (int)name_len, name);

        /* Handle group transitions */
        grp_svp = hv_fetchs(fhv, "group", 0);
        if (grp_svp && SvOK(*grp_svp)) {
            const char *grp = SvPV_nolen(*grp_svp);
            if (!cur_group || !strEQ(cur_group, grp)) {
                if (in_fieldset)
                    sv_catpvs(html, "</fieldset>");
                sv_catpvs(html, "<fieldset class=\"chandra-group\"><legend>");
                {
                    STRLEN glen;
                    const char *g = SvPV(*grp_svp, glen);
                    SV *esc = _elem_escape_html(aTHX_ g, glen);
                    sv_catsv(html, esc);
                    SvREFCNT_dec(esc);
                }
                sv_catpvs(html, "</legend>");
                cur_group = SvPV_nolen(*grp_svp);
                in_fieldset = 1;
            }
        } else {
            if (in_fieldset) {
                sv_catpvs(html, "</fieldset>");
                in_fieldset = 0;
                cur_group = NULL;
            }
        }

        /* Render field by type */
        if (strEQ(type, "text") || strEQ(type, "password") ||
            strEQ(type, "email") || strEQ(type, "number") ||
            strEQ(type, "range") || strEQ(type, "hidden")) {
            field_html = _form_render_input(aTHX_ type, name, name_len,
                                            opts, fid, fid_len);
        } else if (strEQ(type, "select")) {
            field_html = _form_render_select(aTHX_ name, name_len,
                                             opts, fid, fid_len);
        } else if (strEQ(type, "textarea")) {
            field_html = _form_render_textarea(aTHX_ name, name_len,
                                               opts, fid, fid_len);
        } else if (strEQ(type, "checkbox")) {
            field_html = _form_render_checkbox(aTHX_ name, name_len,
                                               opts, fid, fid_len);
        } else if (strEQ(type, "radio")) {
            field_html = _form_render_radio(aTHX_ name, name_len,
                                            opts, fid, fid_len);
        }

        if (field_html) {
            sv_catsv(html, field_html);
            SvREFCNT_dec(field_html);
        }
    }

    if (in_fieldset)
        sv_catpvs(html, "</fieldset>");

    /* Submit button */
    if (submit_svp && SvOK(*submit_svp)) {
        STRLEN slen;
        const char *slbl = SvPV(*submit_svp, slen);
        SV *esc = _elem_escape_html(aTHX_ slbl, slen);
        sv_catpvs(html, "<div class=\"chandra-field chandra-field-submit\">"
                        "<button type=\"submit\" class=\"chandra-submit\">");
        sv_catsv(html, esc);
        sv_catpvs(html, "</button></div>");
        SvREFCNT_dec(esc);
    }

    sv_catpvs(html, "</form>");

    RETVAL = html;
}
OUTPUT:
    RETVAL

 # ---- bind_js() - returns the JavaScript needed for two-way binding ----



( run in 0.798 second using v1.01-cache-2.11-cpan-2398b32b56e )