[Catalyst] best practices for handling forms?

Hernan Lopes hernanlopes at gmail.com
Mon Sep 20 23:12:59 GMT 2010


correction:
you can pass a reference to $c->stash(template =3D> \'foobas'), so you end =
up
with:
 $c->stash( template =3D> \$form->render, current_view =3D> 'Ajax', );

On Mon, Sep 20, 2010 at 8:09 PM, Hernan Lopes <hernanlopes at gmail.com> wrote:

> perl Catalyst Forms with Formhandler and Thickbox:
>
> You know you dont always need a template.tt2 file... this is useful with
> ajax (especially with thickbox) so you can pass a scalar as template, so =
you
> end up with:
>  $c->stash( template =3D> $form->render, current_view =3D> 'Ajax', );
> 1. You could create an Ajax view.
> 2. Or you can set body content directly.
> This way you skip creating TT files for forms and render them directly in=
to
> the $c->res->body or $c->stash( template =3D> \'foo baz')
> If you use something like thickbox, you can render any $form directly into
> a modal.
> Its very handy!
>
> For example:
>
>
> __PACKAGE__->config(
>     action =3D> {
>         edit =3D> { Chained =3D> 'base', Args =3D> 1, },
>     },
> );
>
> sub base : Chained('/') PathPart('foobar') CaptureArgs(0) {}
>
> sub edit :Action {
>   my ( $self, $c, $foobar_id ) =3D @_;
>   my $form =3D HTML::FormHandler->new(
>     schema =3D> 'DBSchema::Foo',
>     params =3D> $c->req->params,
>     field_list =3D> $self->form_fields($c),
>       );
>     if( $c->req->method eq 'POST' && $form->process() ) {
>       ...
>       } else {
>   #OPTION 1 (create an Ajax View and create a wrapper for it. Then render
> the form into stash template var):
>         $c->stash(
>           template =3D> \$form->render,
>           current_view =3D> 'Ajax',
>           );
>   #OPTION 2 (set your content type and charset and render the form into t=
he
> body, needs no view/TT files):
>         $c->res->content_type('text/html charset=3Dutf-8');
>         $c->res->body($form->render);
>         }
>   }
>
>
>
>
> sub form_fields {
>     return [
>         field_one =3D> {
>         type =3D> 'Text',
>         label =3D> '...',
>         css_class =3D> '...',
>         maxlength =3D> 160,
>         required =3D> 1,
>         required_message =3D> 'Required Text',
>         },
>         submit =3D> {
>           type =3D> 'Submit',
>           value =3D> 'Save',
>           css_class =3D> '...',
>          },
>     ];
> }
>
>
>
> and DRY on edit & update unless necessary...
> 1. If there is an argument its "update?"
> 2. Else, when it has no args then its "edit/new" ?
>
> use your foregin_key_id and $form('foregin_key_id')->value =3D '...' to s=
et
> it , then formhandler will know whether to update or create a new entry.
>
> Take care,
> hernan
>
>
>
>
>
>
> On Mon, Sep 20, 2010 at 6:48 PM, E R <pc88mxer at gmail.com> wrote:
>
>> Hi,
>>
>> I am curious what everyone thinks as being the best practices for
>> handling forms in Catalyst. Are there any Catalyst applications you
>> have run across which are good examples of how to use Catalyst's
>> features to handle forms?
>>
>> To illustrate what I am getting at, below is typical Rails (v2)
>> controller code which implements updating the attributes of an object:
>>
>>   def edit
>>      @book =3D Book.find(params[:id])
>>      @subjects =3D Subject.find(:all)
>>   end
>>   def update
>>      @book =3D Book.find(params[:id])
>>      if @book.update_attributes(params[:book])
>>         flash[:notice] =3D 'Book successfully updated.'
>>         redirect_to :action =3D> 'show', :id =3D> @book
>>      else
>>         @subjects =3D Subject.find(:all)
>>         render :action =3D> 'edit'
>>      end
>>   end
>>
>> In Catalyst, this would be appear something like (and please correct
>> me if I have made any errors here):
>>
>> sub edit  :Args(1) {
>>  my ($self, $c, $id) =3D @_;
>>  ... set up $c->stash for template 'edit' ...
>>  # no need to set $c->stash->{template} - will be set from the current
>> action
>> }
>>
>> sub update :Args(1) {
>>  my ($self, $c, $id) =3D @_;
>>  ...process form...
>>  if (form is valid) {
>>    ...perform updates...
>>    $c->flash->{notice} =3D 'Book successfully updated.';
>>    $c->res->redirect('show', $id);
>>  } else {
>>    ... set up $c->stash for 'edit' template ...
>>    $c->stash->{template} =3D 'edit';
>>  }
>> }
>>
>> Any comments on this architecture? Is there a better way? My main proble=
ms
>> are:
>>
>> 1. The code ... set up $c->stash for 'edit' template ... is duplicated
>> in both edit and update (which is also true for the Rails code).
>>
>> 2. Having the template name defaulted from the current action is nice,
>> but that means we have to explicitly set it in the update method. Is
>> it better to always explicitly set the template name in a controller
>> method? Then update could perform a $c->detach('edit', $id) or would
>> you use $c->go('edit', $id)?
>>
>> Thanks,
>> ER
>>
>> _______________________________________________
>> List: Catalyst at lists.scsys.co.uk
>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive:
>> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site: http://dev.catalyst.perl.org/
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20100920/5243d=
2e9/attachment.htm


More information about the Catalyst mailing list