HTML::FormBuilder::Validation - An extension of the Form object, to allow for javascript-side validation of inputs and also server-side validation after the form is POSTed
First, create the Form object. The keys in the HASH reference is the attributes of the form.
# Form attributes require to create new form object my $form_attributes = { 'name' => 'name_test_form', 'id' => 'id_test_form', 'method' => 'post', 'action' => "http://www.domain.com/contact.cgi", 'class' => 'formObject', }; my $form_obj = new HTML::FormBuilder::Validation(data => $form_attributes); my $fieldset = $form_obj->add_fieldset({});
This is quite similar to creating input field in Form object. Likewise you can add validation to HASH reference as the attribute of input field.
Below you can see the sample included four types of validation:
1. regexp: Just write the reqular expression that should be apply to the value
2. min_amount: Needs both type=min_amount and also minimum amount that declared in amount
3. max_amount: Just like min_amount
4. checkbox_checked: Ensure checkbox is checked by user
5. custom: Just the javascript function call with parameters should be given to. It only specifies client side validation.
my $input_field_amount = { 'label' => { 'text' => 'Amount', 'for' => 'amount', 'optional' => '0', }, 'input' => { 'type' => 'text', 'id' => 'amount', 'name' => 'amount', 'maxlength' => 40, 'value' => '', }, 'error' => { 'text' => '', 'id' => 'error_amount', 'class' => 'errorfield', }, 'validation' => [ { 'type' => 'regexp', 'regexp' => '\w+', 'err_msg' => 'Not empty', }, { 'type' => 'regexp', 'regexp' => '\d+', 'err_msg' => 'Must be digit', }, { 'type' => 'min_amount', 'amount' => 50, 'err_msg' => 'Too little', }, { 'type' => 'max_amount', 'amount' => 500, 'err_msg' => 'Too much', }, { 'type' => 'custom', 'function' => 'custom_amount_validation()', 'err_msg' => 'It is not good', }, ], }; my $terms_and_condition_checkbox = { 'label' => { 'text' => 'I have read & agree to the terms & condition of the site', 'for' => 'tnc', }, 'input' => { 'type' => 'checkbox', 'id' => 'tnc', 'name' => 'tnc', 'value' => '1', # optional }, 'error' => { 'id' => 'error_tnc', 'class' => 'errorfield', }, 'validation' => [ { 'type' => 'checkbox_checked', 'err_msg' => 'In order to proceed, you need to agree to the terms & condition', }, ], };
Below is another example with two different fields. In this matter we need to indicate the id of each field in validation attributes.
my $select_curr = { 'id' => 'select_text_curr', 'name' => 'select_text_curr', 'type' => 'select', 'options' => '<option value=""></option><option value="USD">USD</option><option value="EUR">EUR</option>', }; my $input_amount = { 'id' => 'select_text_amount', 'name' => 'select_text_amount', 'type' => 'text', 'value' => '' }; my $input_field_select_text = { 'label' => { 'text' => 'select_text', 'for' => 'select_text', }, 'input' => [ $select_curr, $input_amount ], 'error' => { 'text' => '', 'id' => 'error_select_text', 'class' => 'errorfield', }, 'validation' => [ { 'type' => 'regexp', 'id' => 'select_text_curr', 'regexp' => '\w+', 'err_msg' => 'Must be select', }, { 'type' => 'regexp', 'id' => 'select_text_amount', 'regexp' => '\d+', 'err_msg' => 'Must be digits', }, { 'type' => 'min_amount', 'id' => 'select_text_amount', 'amount' => 50, 'err_msg' => 'Too little', }, ], }; my $general_error_field = { 'error' => { 'text' => '', 'id' => 'error_general', 'class' => 'errorfield' }, };
Here is just add fields to the form object like before.
$form_obj->add_field($fieldset_index, $general_error_field); $form_obj->add_field($fieldset_index, $input_field_amount); $form_obj->add_field($fieldset_index, $input_field_select_text);
This javascript code will be run before onsubmit return false
$form_obj->onsubmit_js_error("\$('#residence').attr('disabled', true);"); $form_obj->onsubmit_js_error('onsubmit_error_disable_fields()');
Custom javascript validation should be defined and assigned to the form object. Note that, the name and parameters should be the same as the way you indicate function call in validation attributes.
You can see a sample below:
my $custom_javascript = qq~ function custom_amount_validation() { var input_amount = document.getElementById('amount'); if (input_amount.value == 100) { return false; } return true; }~;
The custom server side validation is quite similar to javascript. A reference to a subrotine should be pass to form object.
my $custom_server_side_sub_ref = sub { if ($form_obj->get_field_value('name') eq 'felix') { $form_obj->set_field_error_message('name', 'felix is not allow to use this page'); $form_obj->set_field_error_message('error_general', 'There is an error !!!'); } }; $form_obj->set_server_side_checks($custom_server_side_sub_ref);
Somewhere in cgi files you can just print the result of build().
print $form_obj->build();
In submit you need to fill form values, use set_input_fields(\%input) and pass %input HASH and then show what ever you want in result of validation. Just like below:
if (not $form_obj->validate()) { print '<h1>Test Form</h1>'; print $form_obj->build(); } else { print '<h1>Success !!!</h1>'; } code_exit();
The tag that error happened during validation
The custom server side subroutine that will be run on server side.
javasript code to run during onsubmit error by javasript validation
$form_validation_obj->set_input_fields({username => $username});
assign value to the input fields
$form_validation_obj->validate();
validate form input and return true or false
$form_validation_obj->is_error_found_in($input_element_id);
check the erorr is founded in the input element or not
for plain CGI or other framework, read Dancer example below.
create form HTML and store csrftoken in session
my $form = HTML::FormBuilder::Validation->new(data => $form_attributes, csrftoken => 1); ... my $html = $form->build; # save csrf token in session or cookie session(__csrftoken => $form->csrftoken);
validate csrftoken on form submit
my $csrftoken = session('__csrftoken'); my $form = HTML::FormBuilder::Validation->new(data => $form_attributes, csrftoken => $csrftoken); $form->validate_csrf() or die 'CSRF failed.'; # or call if ( $form->validate() ) { # it calls validate_csrf inside # Yap! it's ok } else { # NOTE we do not have error for csrf on form HTML build # show form again with $form->build }
if you're using Mojolicious and have DefaultHelpers plugin enabled, it's simple to add csrftoken in Validation->new as below:
my $form = HTML::FormBuilder::Validation->new(data => $form_attributes, csrftoken => $c->csrf_token);
Mojolicious $c->csrf_token will handle the session part for you.
Chylli mailto:chylli@binary.com
BUILDARGS, add_field, add_fieldset, after_form, build_confirmation_button_with_all_inputs_hidden, csrftoken, data, fieldsets, get_field_error_message, get_field_value, set_field_value
classes, localize
BUILDALL, DEMOLISHALL, does, meta
Fayland Lam mailto:fayland@binary.com
Tee Shuwn Yuan mailto:shuwnyuan@binary.com
To install HTML::FormBuilder, copy and paste the appropriate command in to your terminal.
cpanm
cpanm HTML::FormBuilder
CPAN shell
perl -MCPAN -e shell install HTML::FormBuilder
For more information on module installation, please visit the detailed CPAN module installation guide.