Extending Form Validation

59 views
Skip to first unread message

Bad Horsey

unread,
May 23, 2016, 7:33:48 AM5/23/16
to Mojolicious
Hi,

I've just started using Mojolicious and I'm new to quite a few of the concepts.  I'm building a form based app that has templates that extend from a basic from, for example:

basic form ep template

name
email
tel

second form extends basic

accommodation choice
event choice

third form extends basic

quantity

Can I create a form validation object to check required fields that I can extend based on the form submitted? Sorry if that's a stupid question but like I said I’m new to a lot of the concepts and trying to figure out best practices.  I’ve looked at validator docs but I’m a little unsure how to proceed. So if I have:

my $validatorBasic  = Mojolicious::Validator->new;
my $validation = $validatorBasic->validation;

$validation->required(‘name’)->size(50);
$validation->required(‘email’)->size(50);
$validation->required(‘tel’)->size(11);

How could I extend this for second form, third form?  Also is there a helper to check for types like number, email or should I just use like(regex)? 

Really liking Mojolicious btw.  Thanks in advance.

Horsey

Pavel K

unread,
May 24, 2016, 2:28:37 AM5/24/16
to Mojolicious
Hi, Horsey!
I don't sure that is the best practic, but I do it like this:


In controller I have:

sub some_route {
  my $s = shift;
  my $userid = $s->session('userid'); # for example
  my $valid = $s->_validate_it('order_form');
  if ($valid->has_error) {
# render json or somethink that you want, 
     $s->render(json => {message => "No data: " . @{$valid->failed}[0], type => 'alert-info'});# Error!
   } else {
   my $vars = $valid->output;
   $s->render(); # OK!
   }

}

I have method _validate_it() , that is a helper and it look like this:

 $app->helper( _validate_it => sub {
                  my ($self, $form) = @_;
                  my $v = $self->validation;
                  my $out = $VALIDATORS{$form}($v);
                  return $out;
                }
               );  

Hash %VALIDATORS look like this:

my %VALIDATORS = (
                  order_form=> \&_validation_order_form,
                  other_form=> \&_validation_other_form,

);

In this hash I have a link to validation subs (per one sub on form)

where _validation_order_form is a sub like this:

sub _validation_order_form {
  my $v = shift;
  $v->optional('order_id')->like(qr/^[0-9]+/);
  $v->optional('userid')->like(qr/^[0-9]+/);# 

  $v->required('delivery')->in('EXW','CIF','FOB');
  $v->required('temp_id')->like(qr/^[0-9]+/);
  $v->optional('comment');  
  say for @{$v->failed};
  return $v;
}

Helper _validate_it is useful for validating many forms by name, and linking validation sub with nedded form

понедельник, 23 мая 2016 г., 14:33:48 UTC+3 пользователь Bad Horsey написал:

Bad Horsey

unread,
May 24, 2016, 6:42:35 AM5/24/16
to Mojolicious
Thank you, that's really helpful. 

You say that it's not best practice, what would be the best way to do something like this where I have a number of forms, all of which contain the same details such as name and address, but then have different optional sections depending on what the form is for (they are all payment booking forms but for different things).  What would be the best way to build scalable validation in Mojolicious? Like I say I am quite new to this and learning so please excuse any silly questions.

BH

Pavel K

unread,
May 24, 2016, 7:43:46 AM5/24/16
to Mojolicious
Hmm... Can you try to do something like that:


$validation = $validation->input({foo => 'bar', baz => [123, 'yada']});

Smth like this:

post '/my_controller' => sub {
my $hash = $c->req->params->to_hash;
  my $valid = $c->validation->input($hash);
  foreach my $k(keys %{$hash}) {
   $valid->required($k);
  }
  say $c->dumper($valid->failed);
};

вторник, 24 мая 2016 г., 13:42:35 UTC+3 пользователь Bad Horsey написал:

sri

unread,
May 24, 2016, 4:24:47 PM5/24/16
to Mojolicious
basic form ep template

name
email
tel

second form extends basic

accommodation choice
event choice

third form extends basic

quantity

The validation object is tied to the controller, so i'd just make a bunch of methods/helpers that add a bunch of fields to it.


Perhaps have it return the controller instance instead of the validation.

  $c->_basics->_accommodations->_events;
  return $c->render(...) if $c->validation->has_error;

--
sebastian 

sri

unread,
May 24, 2016, 4:26:57 PM5/24/16
to Mojolicious
Also is there a helper to check for types like number, email or should I just use like(regex)?

Mark Jones

unread,
May 25, 2016, 7:25:41 AM5/25/16
to Mojolicious
Thanks both.  I think I'm on the right track now. 

BH
Reply all
Reply to author
Forward
0 new messages