Ohh, by the way, if you need to write html into the form, you can also do it without any TT view file. <br><br>With Formhandler it is very simple, just use the field of type 'Display', for example:<br> has_field 'display0' => (<br>
type => 'Display',<br> html => '<br><div class="clear"><h1 class="formtitle">Your Personal Data</h1></div><br><script>foo bar baz</script><br>
' <br> );<br><br><br><br><br><div class="gmail_quote">On Mon, Sep 20, 2010 at 8:09 PM, Hernan Lopes <span dir="ltr"><<a href="mailto:hernanlopes@gmail.com">hernanlopes@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">perl Catalyst Forms with Formhandler and Thickbox:<br><br>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:<br>
$c->stash( template => $form->render, current_view => 'Ajax', );<br>1. You could create an Ajax view.<br>2. Or you can set body content directly. <br>This way you skip creating TT files for forms and render them directly into the $c->res->body or $c->stash( template => \'foo baz')<br>
If you use something like thickbox, you can render any $form directly into a modal. <br>Its very handy!<br><br>For example:<br><br><br>__PACKAGE__->config(<br> action => {<br> edit => { Chained => 'base', Args => 1, },<br>
},<br>);<br><br>sub base : Chained('/') PathPart('foobar') CaptureArgs(0) {}<br><br>sub edit :Action {<br> my ( $self, $c, $foobar_id ) = @_;<br> my $form = HTML::FormHandler->new(<br> schema => 'DBSchema::Foo',<br>
params => $c->req->params,<br> field_list => $self->form_fields($c),<br> );<br> if( $c->req->method eq 'POST' && $form->process() ) {<br> ...<br> } else {<br>
#OPTION 1 (create an Ajax View and create a wrapper for it. Then render the form into stash template var):<br> $c->stash(<br> template => \$form->render,<br> current_view => 'Ajax',<br>
);<br> #OPTION 2 (set your content type and charset and render the form into the body, needs no view/TT files):<br> $c->res->content_type('text/html charset=utf-8');<br> $c->res->body($form->render);<br>
}<br> }<br><br><br><br><br>sub form_fields {<br> return [<br> field_one => {<br> type => 'Text',<br> label => '...',<br> css_class => '...',<br>
maxlength => 160,<br>
required => 1,<br> required_message => 'Required Text',<br> },<br> submit => {<br> type => 'Submit',<br> value => 'Save',<br> css_class => '...',<br>
},<br> ];<br>}<br><br><br><br>and DRY on edit & update unless necessary... <br>1. If there is an argument its "update?" <br>2. Else, when it has no args then its "edit/new" ? <br><br>use your foregin_key_id and $form('foregin_key_id')->value = '...' to set it , then formhandler will know whether to update or create a new entry.<br>
<br>Take care,<br><font color="#888888">hernan</font><div><div></div><div class="h5"><br><br><br><br><br><br><div class="gmail_quote">On Mon, Sep 20, 2010 at 6:48 PM, E R <span dir="ltr"><<a href="mailto:pc88mxer@gmail.com" target="_blank">pc88mxer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hi,<br>
<br>
I am curious what everyone thinks as being the best practices for<br>
handling forms in Catalyst. Are there any Catalyst applications you<br>
have run across which are good examples of how to use Catalyst's<br>
features to handle forms?<br>
<br>
To illustrate what I am getting at, below is typical Rails (v2)<br>
controller code which implements updating the attributes of an object:<br>
<br>
def edit<br>
@book = Book.find(params[:id])<br>
@subjects = Subject.find(:all)<br>
end<br>
def update<br>
@book = Book.find(params[:id])<br>
if @book.update_attributes(params[:book])<br>
flash[:notice] = 'Book successfully updated.'<br>
redirect_to :action => 'show', :id => @book<br>
else<br>
@subjects = Subject.find(:all)<br>
render :action => 'edit'<br>
end<br>
end<br>
<br>
In Catalyst, this would be appear something like (and please correct<br>
me if I have made any errors here):<br>
<br>
sub edit :Args(1) {<br>
my ($self, $c, $id) = @_;<br>
... set up $c->stash for template 'edit' ...<br>
# no need to set $c->stash->{template} - will be set from the current action<br>
}<br>
<br>
sub update :Args(1) {<br>
my ($self, $c, $id) = @_;<br>
...process form...<br>
if (form is valid) {<br>
...perform updates...<br>
$c->flash->{notice} = 'Book successfully updated.';<br>
$c->res->redirect('show', $id);<br>
} else {<br>
... set up $c->stash for 'edit' template ...<br>
$c->stash->{template} = 'edit';<br>
}<br>
}<br>
<br>
Any comments on this architecture? Is there a better way? My main problems are:<br>
<br>
1. The code ... set up $c->stash for 'edit' template ... is duplicated<br>
in both edit and update (which is also true for the Rails code).<br>
<br>
2. Having the template name defaulted from the current action is nice,<br>
but that means we have to explicitly set it in the update method. Is<br>
it better to always explicitly set the template name in a controller<br>
method? Then update could perform a $c->detach('edit', $id) or would<br>
you use $c->go('edit', $id)?<br>
<br>
Thanks,<br>
ER<br>
<br>
_______________________________________________<br>
List: <a href="mailto:Catalyst@lists.scsys.co.uk" target="_blank">Catalyst@lists.scsys.co.uk</a><br>
Listinfo: <a href="http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst" target="_blank">http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst</a><br>
Searchable archive: <a href="http://www.mail-archive.com/catalyst@lists.scsys.co.uk/" target="_blank">http://www.mail-archive.com/catalyst@lists.scsys.co.uk/</a><br>
Dev site: <a href="http://dev.catalyst.perl.org/" target="_blank">http://dev.catalyst.perl.org/</a><br>
</blockquote></div><br>
</div></div></blockquote></div><br>