CGI-AutoForm

 view release on metacpan or  search on metacpan

lib/CGI/AutoForm.pm  view on Meta::CPAN

An example where you might use just alt_mask_field instead of the set (of fields (mask_table_name, mask_field_name, id_field_name) is perhaps
if you have a table COUNTRY with fields (country, user_mask) where country is the country code and user_mask is the country name
and a field in ARTIST (ARTIST.ORIGIN_COUNTRY) you'd simply set UI_TABLE_COLUMN.ALT_MASK_FIELD to 'COUNTRY' where field_name = C<ORIGIN_COUNTRY>
and table_name = C<ARTIST> and the magic will happen.

If the underlying RDBMS is MySQL some additional magic parses allowed values for C<SET> and C<ENUM> data types to obtain
this pick list (no related table with a foreign key is necessary).

If using a form control that demands a discreet set of values where none of the above conditions apply,
you must specify the list (see $pick_list under C<create_field>).

This magic provides a great deal of convenience and security not only for translating ID values for human operators
but also for enforcing a discreet set of allowable values for certain form fields.

=head2 Tabular data groups

If passing a true value for $tabular to C<add_group>, that group's data (via C<add_record>) will be displayed
in a tabular form - one column for each field in the record (read-only). This is how you display multiple records in a data group.
The only fields that will be shown in a tabular view are the ones with a non-empty value for C<UI_TABLE_COLUMN.BRIEF_HEADING>.

If $tabular is false (the default), a vertical form with a field heading and field value on each line is produced;
each use HTML C<table> elements however (see B<Form preparation, HTML generation & customization> for details).

=head2 Form preparation, HTML generation & customization

Once the data group(s) of the form object have been defined, C<prepare>
will generate the HTML, which should be inserted into the BODY section
of an HTML document (presumably using a templating system).
The structure of the generated HTML follows:

 Form Heading
 <form>
   <div>Data Group1 Heading</div>
   <table>
   tabular view of search results (see below)
    -or-
   vertical view of data group1 fields (see below)
   </table>
   [<div>Data Group2 Heading...</div>
   ...]
 </form>

 for the tabular view of a data group:
 <thead><tr><th>Field1 name</th>[<th>Field2 name</th>...]</tr></thead>
 <tr><td>Value1</td>[<td>Value2</td>...]</tr>
 ...

 for the vertical view of a data group (updatable/insertable groups):
 <tr><td><label>field name</label></td><td>field value/form control</td></tr>
 ...

See C<prepare> for further details of the layout.
See the Cruddy! demo for the default layout:

L<http://www.thesmbexchange.com/cruddy/index.html>

The HTML generated by C<prepare> can be influenced by a number of attributes
of the form object and group/field sub-object(s) (manipulate via hash keys, only some accessor methods have been defined as yet).
To get the $field sub-object (hashref) try C<$group-E<gt>{field_hash}{FIELD_NAME}> (see also C<field_hash>).
Some of the following attributes may have content already so it is best to append to them, rather
than assign/replace their values. C<prepare> also accepts some callbacks to allow further customization.
Unless otherwise noted, custom content is expected to be HTML (encode with HTML entities, etc, see C<escape>).

=over

=item $form->{top_message}

Content displayed at the very top of the form.

=item $form->{heading} (or $form->heading())

Header content near the top of the form describing the form. Will be enclosed in an C<h2> block.

=item $form->{heading2}

Sub-header content near the top of the form.

=item $form->{verr_msg}

Error message displayed near the top of the form when there are validation errors (see C<validate_query>).

=item $form->{noscript}

Content enclosed in a C<noscript> block.

=item $form->{name} (or $form->name())

Will be used in the C<name> attribute of the C<form> element.

=item $form->{action} (or $form->action() this needs to be set somewhere in your code)

Will be used in the C<action> attribute of the C<form> element.

=item $form->{submit_value} (or $form->submit_value())

Will be used in the C<value> attribute of the submit button.
The value will be HTML-escaped (don't encode with HTML entities).

=item $form->{submit_button_attrs}

Appended to the list of attributes of the C<input> button controls (submit, reset, etc).

=item $group->{heading}

Header content at the top of the data group describing that group.

=item $group->{GT}

Appended to the list of attributes of the outermost C<table> element of each group.

=item $group->{js}

A block of javascript added to the HTML block of each data group.

=item $form->{head_html}

=item $form->{tail_html}

=item $group->{head_html}

=item $group->{tail_html}

lib/CGI/AutoForm.pm  view on Meta::CPAN

                $ret .= $self->field_group_html($field_s->[1],$group,'CONFIRM') unless $group->{tabular};
                return $ret;
            }
            else { die "A horrible death"; }
        }
        elsif (substr($field_s->[0]{FORM_ELEMENT_NAME},-6) eq '_MONTH')
        {
            # Must be a date group
            $val .= '<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0"><TR>';
            $val .= $self->date_group_html($field_s);
            $val .= '</TR></TABLE>';
            $field_s = $field_s->[0];
        }
        elsif ($self->group_usage() eq $CGI::AutoForm::SEARCH_GROUP)
        {
            # Must be a plain search range with 'TEXT' controls
            $val = $self->search_range_html($field_s,$group);
            $field_s = $field_s->[0];
        }
        elsif ($field_s->[0]{FIELD_GROUP} eq 'CONFIRM')
        {
            my $ret = $self->field_group_html($field_s->[0],$group);
            $ret .= $self->field_group_html($field_s->[1],$group,'CONFIRM') unless $group->{tabular};
            return $ret;
        }
        else { die "A horrible death"; }
    }
    else
    {
        $val = $self->field_html($field_s);
    }
    
    if ($group->{tabular})
    {
        return '' unless length($field_s->{BRIEF_HEADING});
        if ($head_rec)
        {
            $head = $self->escape($field_s->{BRIEF_HEADING});
##at could also support TABULAR_TH_ATTRS, TABULAR_TD_ATTRS, etc management by adding it to UI_TABLE_COLUMN and pod up
            $$head_rec .= qq[<TH CLASS="TABULAR_TH" $group->{TABULAR_TH_ATTRS} $field_s->{TABULAR_TH_ATTRS}>$head</TH>];
        }
        $val = &{$self->{val_callback}}($val,$field_s,$self) if ref($self->{val_callback});
        if ($tail_rec && $group->{TABULAR_TD_TAIL_STYLE})
        {
            $field_s->{TABULAR_TD_STYLE} .= $group->{TABULAR_TD_TAIL_STYLE};
        }
        my $style = '';
        if ($field_s->{TABULAR_TD_STYLE})
        {
            $style = qq[style="$field_s->{TABULAR_TD_STYLE}"];
        }
        return "<TD" . ($field_s->{VALID_ERROR} ? ' CLASS="VERR TABULAR_TD"' : ' CLASS="TABULAR_TD"') . " $field_s->{TABULAR_TD_ATTRS}" .
            ($tail_rec ? ' '. $group->{TABULAR_TD_TAIL_ATTRS} : '') . " $style>" . (length($val) ? $val : '&nbsp;' ) . "</TD>";
    }
    else
    {
        my $valerr = $self->escape($field_s->{VALID_ERROR});
        $head = $self->escape($field_s->{HEADING});
        $head = $self->_process_field_head($field_s,$head,$group);

        # all callbacks must be responsible for escaping any added HTML
        $val = &{$self->{val_callback}}($val,$field_s,$self) if ref($self->{val_callback});

        my $class;
        $class .= "$label_class_add " if $label_class_add;
        $class .= "REQ " if $field_s->{REQUIRED} eq 'Y';
        $class .= "VERR " if $valerr;
        chop($class);
        $class = qq[ CLASS="$class" ] if $class;
        $headadd = qq[<P>$headadd</P>] if $headadd;

        # this can be overridden on-the-fly also
        $valerr = qq[<FONT COLOR="RED" CLASS="VERR"><SPAN CLASS="VERR">$valerr</SPAN></FONT>]
            if $valerr;

        my $ret = qq[<TD CLASS="VFL" $self->{VFL}><LABEL$class>$head $valerr</LABEL>$headadd</TD><TD CLASS="VFE" $self->{VFE}>&nbsp;$val</TD>];
        $ret = &{$self->{rec_callback}}($ret,$field_s,$group,$self) if ref($self->{rec_callback}) eq 'CODE';
        return qq[<TR CLASS="VFR" $self->{VFR}>$ret</TR>];
    }
}

# If callback differs, don't add alert_summary
sub _process_field_head
{
    my ($self,$field_s,$head,$group) = @_;
    # {head_callback} does not apply to tabular headings
    if (ref($self->{head_callback}))
    {
        my $call_head = &{$self->{head_callback}}($head,$field_s,$self);
        return $call_head if $head ne $call_head;
    }
    else
    {
        $head = qq[$head:&nbsp;];
        my $usage = $self->group_usage();
        if (!$self->readonly() && $field_s->{REQUIRED} eq 'Y' && ($usage eq $CGI::AutoForm::INSERT_GROUP || $usage eq $CGI::AutoForm::EDIT_GROUP))
        {
            $head .= '*';
            $self->{ast_foot}++;
        }
    }
    if (length($field_s->{HELP_SUMMARY}))
    {
        my $sum = $field_s->{HELP_SUMMARY};
        $sum =~ s/\"/\\"/gs;
        $sum =~ s/\r?\n/\\n/gs;
        my $func_name = $field_s->{FORM_ELEMENT_NAME};
        $func_name =~ s/\./_/gs;
        $func_name = "${func_name}_ALRT_SUM";
        $group->{js} .= qq[function $func_name(){alert("$sum");}\n];
        $head = qq[<A CLASS="AS" HREF="javascript:$func_name();">$head </A>];
    }
    return $head;
}

=pod

=item C<require_js>

 $form->require_js();



( run in 1.009 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )