[Catalyst] best practices for handling forms?

Hernan Lopes hernanlopes at gmail.com
Mon Sep 20 23:32:16 GMT 2010


Ohh, by the way, if you need to write html into the form, you can also do it
without any TT view file.

With Formhandler it is very simple, just use the field of type 'Display',
for example:
    has_field 'display0' =3D> (
         type =3D> 'Display',
         html =3D> '
<div class=3D"clear"><h1 class=3D"formtitle">Your Personal Data</h1></div>
<script>foo bar baz</script>
'
         );




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/5fc12=
e0f/attachment.htm


More information about the Catalyst mailing list