You're not currently signed in.

Managing forms in Jifty

a simple form might look like this:

<% Jifty->web->form->start %>
<% Jifty->web->form->next_page(url => '/next/page.html') %>
... form elements placed here...
<% Jifty->web->form->submit(label => 'Save form') %>
<% Jifty->web->form->end %>

There are some things to know:

  • Every form begins with ...form->start. Technically, using this constuct places a <form> tag in the generated HTML code. Forms cannot get nested, the use of start will implicitly terminate a form that already is open.

  • Every form of such a kind uses POST as its methods and calls the same URL from which it was called. As a result of a POST request, all actions that are assigned to the form will first run their validation and then run ordinally. All actions are processed in their requested order. Using the optional next_page construct on a form will implicitly create a Redirect action that is typically run at as the last action. However, the redirect will only happen if the form validation was successful.

  • Using an action inside the form will typically add the action to the processing queue.

The start() method may accept additional parameters:

  • name=>'...' give some additional name to the form which is added as a HTML attribute inside the <form> tag.

  • call=>continuation_id will modify the behavior of this form. All buttons in this form will act as continuation calls to the given continuation ID. !!!Write more!!!

  • Using the method ...form->submit() will place a Jifty::Web::Form::Field::Button into the HTML output. All parameters of the submit() call will be forwarded to the constructor of the button. Additional parameters may get supplied:

  • Calling ...form->end will close the HTML <form> tag and internally mark the form as being closed. Any subsequent start call will again open a new form.

Populating the form with fields

One way to get fields into the form is to use an action in connection with the template. To do that, you could place some code inside the <%init> section of your template:

<%init>
my $action = Jifty->web->new_action(class=>'NameOfAction');
</%init>

Doing this will look inside your application or in the usual search locations for an action class with the given name and instantiate an object in that class. Additional parameters might be:

  • moniker=>'moniker_name' specifying this parameter gives a 'nickname' to this action. This 'nickname' may get used later to refer to the form's arguments or to allow redisplay of sticky fields.

  • order=>number forces this action to get processed in a certain order. Normally, actions are processed in the order they are defined.

  • arguments=>{hashref} Hereby, you may specify arguments for the action or the form's fields.

In case this action provides a schema or provides a (depricated) arguments method, you may use the fields defined here to render the form elements easily. A form may also get constructed on a model's record. See actions or (models)[JiftyModelIntro]for more details about how to define a schema.

A field may get displayed as easy as:

<% $action->form_field('fieldname') %>

If you are lazy, you may display all fields an action knows about like that:

% foreach my $field_name ($action->argument_names) {
    <% $action->form_field($field_name) %>
% }

If you are even more lazy, you may mis-use the sort_order to filter out certain fields you do not like to see in the frontend, but in the administration mode. To get this done, you simply use negative sort_order values for fields you like to get masked out.

% foreach my $field_name ($action->argument_names) {
%    next if ($action->arguments->{$field_name}->{sort_order}<0);
    <% $action->form_field($field_name) %>
% }

Adding function buttons to a form

One typical use of a function button is to use $action->button to get some action done.

Some typical uses might look like:

<% Jifty->web->link(label=>'link label',
                    url => '/location/to/jump',
                ) %>

<% $action->button(label=> 'button label',
                   onclick => { submit       => $action, },
                ) %>

Commonly used parameters:

  • label=>'text' defines the label of the link or button. By default the string given here is automatically html-escaped.

  • escape_label=>boolean defines if displaying the label is to be escaped. The default value is true. If you plan to use fancy unicode characters as entities like label=>'&#10000;' (will display a pencil symbol) you will have to set this parameter to a true value.

  • tooltip=>'text' give some tooltip to this link or button.

  • url=>'url' names the location to jump to when this link is followed.

  • as_button, as_link specifies a hint on how the rendering should occur. Normally a button will get rendered as a button, a link as a link.

  • submit=>$action or submit=>[list of actions] tells which action(s) (or none if the list is empty) to submit if not done automatically ($action->button). The action might be given either as an action-object or the moniker-name.

  • parameters=>{} defines parameters that are sent to the destination page or region and are treated like ordinary GET/POST parameters. These parameters may easily get accesed with a Mason <%args> section in the template or with Jifty->web->request->argument() inside perl code. If you plan to use a onclick parameter, the parameters given here will be ignored. See JavaScript event handlers below to read more about that.

  • preserve_state=>boolean keeps state variables when true. Defaults to true only on AJAX actions.

  • onclick=>... will trigger certain actions on the JavaScript side by installing a 'onClick' handler on the button placed. Using the onclick semantics here will allow a page (or a page region) to still work on a browser that is not JavaScript capable. Using this handler may have several shapes:

  • "some javascript code as string" This is a way of directly placing some javascript code in the onclick handler. However then, no fallback on no-Javascript browsers will be possible. If you do that, think if you will need a return false; statement at the end...

  • { hash with certain keywords } By using the right key-value pairs you will trigger some predefined behavior. See JavaScript Event Handlers below.

  • [ list with both things above ] This construct allows to use more than one thing to happen when the button is clicked. The listed items are executed in sequence.

Inside the hashref the following keys are accepted:

  • append=>'path', prepend=>'path', replace_with=>'path' adds the HTML-code from the given path before, after or instead of the region. if replace_with is given with an undef value, the region is deleted.

  • refresh=>'region' just refreshes the region by reloading the last known URL.

  • refresh_self reload current region

  • delete=>'region' delete a region.

  • region=>'region' forces the action to be just get performed in that region.

  • submit=>$action or submit=>[...] submit the action(s). By default, the action is disabled afterwards

  • disable=>boolean allow to control the disable behaviour of submit

  • confirm=>'string_message' allow to bring up a Javascript alert with the given message before action is performed. The action is only performed if "OK" is clicked.

  • element=>... CSS2 selector of an element to be used by append, prepend,... e.g. $region->parent->get_element('div.divname') will find a div with class 'divname' in the parent of the current region.

  • args=>{} arguments to the destination template that are accessible in the destination template by defining a <%args> section specifying the transported arguments.

  • toggle=>boolean switch displaying status from displayed to invisible

  • effect=>'...' and effect_args=>... trigger some effect to run at button click. Keep in mind that most effects do run asyncronously and may not get shown in a situation where the current page or region will disappear.

some examples of buttons

a simple button replacing the current region:

<% $action->button(label=> 'button label',
                   onclick => { submit       => $action,
                                replace_with => "/fragments/xxx",
                                args         => { id=>$id },
                            },
                  ) %>

a graphically looking button inserting a region in front of another region:

<% Jifty->web->link(label=>'&#9997;',
                    tooltip=>'new item',
                    escape_label=>0,
                    onclick => {
                        region=> "insertbefore",
                        prepend => "/fragments/edit_element",
                        args => {id=>$id, operation=>'xxx',},
                    },
                ) %>

A link only jumping to a url after confirmation:

<% Jifty->web->link(label=>'delete',
                    url=> "/jump/to/x.html",
                    onclick => {confirm => 'really delete this element?'},
                ) %>