When rendering, FormHandler loops through the sorted fields in the form and executes the 'render' method on each field. Fields in FormHandler forms, particularly those that interface with a database, are usually structured in a way that matches the data structure. This doesn't always fit with the way that you want to display the form.
'Blocks' provide an alternative way of structuring the display. A 'block' is a fairly basic object that contains a 'render' method. The standard block class, HTML::FormHandler::Widget::Block, has Moose attributes to set the HTML tag, the label, the classes, etc, plus a 'render_list' which contains the names of a list of fields or other blocks to render.
You create a block with 'has_block':
has_block 'comment' => ( tag => 'p', content => 'This is a comment', class => ['comment'] );
Blocks can contain lists of fields:
has_block 'fset1' => ( tag => 'fieldset', render_list => ['foo', 'bar'] );
In order to use blocks when rendering instead of fields, you need to provide the form with a 'render_list' too (in addition to any render_lists that might exist in the blocks).
sub build_render_list { ['fset1', 'comment', 'a_field' 'submit_btn' ] }
A complete form that renders using blocks:
package MyApp::Test::Form; use HTML::FormHandler::Moose; extends 'HTML::FormHandler'; sub build_render_list {['abc', 'def', 'ghi', 'submit_btn']} has_field 'foo'; has_field 'bar'; has_field 'flim'; has_field 'flam'; has_field 'fee'; has_field 'fie'; has_field 'fo'; has_field 'fum'; has_field 'submit_btn'; has_block 'abc' => ( tag => 'fieldset', render_list => ['foo', 'fo'] ); has_block 'def' => ( render_list => ['bar', 'fum'], label => "My DEF Block", label_class => ['block', 'label'] ); has_block 'ghi' => ( render_list => ['flim', 'flam'], wrapper => 0 );
More flexible form rendering in Perl with FormHandler....