1NAME 2 Catalyst::Plugin::FormBuilder - (DEPRECATED) Catalyst FormBuilder Plugin 3 4SYNOPSIS 5 # Please see Catalyst::Controller::FormBuilder instead 6 7 package MyApp; 8 use Catalyst qw/FormBuilder/; 9 10 package MyApp::Controller::Example; 11 use base 'Catalyst::Controller'; 12 13 # 14 # The simplest example looks for edit.fb to create 15 # a form, based on the presence of the ":Form" attribute. 16 # Use Local/Global/Private/etc to scope methods like normal. 17 # 18 sub edit : Local Form { 19 my ($self, $c, @args) = @_; 20 $c->form->field(name => 'email', validate => 'EMAIL'); 21 $c->form->messages('/locale/messages.fr'); 22 } 23 24 # 25 # This example references edit still, since we are 26 # just switching to a readonly view. The layout will be 27 # the same, but fields are rendered as static HTML. 28 # Note that the Catalyst action URL remains /books/view 29 # 30 sub view : Local Form('/books/edit') { 31 my ($self, $c) = @_; 32 $c->form->static(1); # set form to readonly 33 } 34 35DEPRECATION NOTICE 36 This module has been deprecated in favor of 37 Catalyst::Controller::FormBuilder. Please do not use it in new code. It 38 has known compatibility issues and is absolutely not supported by 39 anyone. It remains only in case you have existing code that relies on 40 it. 41 42DESCRIPTION 43 This plugin merges the functionality of CGI::FormBuilder with Catalyst 44 and Template Toolkit. This gives you access to all of FormBuilder's 45 niceties, such as controllable field stickiness, multilingual support, 46 and Javascript generation. For more details, see CGI::FormBuilder or the 47 website at: 48 49 http://www.formbuilder.org 50 51 FormBuilder usage within Catalyst is straightforward. Since Catalyst 52 handles page rendering, you don't call FormBuilder's "render()" method, 53 as you would normally. Instead, you simply add a ":Form" attribute to 54 each method that you want to associate with a form. This will give you 55 access to a FormBuilder "$c->form" object within that controller method: 56 57 # An editing screen for books 58 sub edit : Local Form { 59 # The file books/edit.fb is loaded automatically 60 $c->form->method('post'); # set form method 61 } 62 63 The out-of-the-box setup is to look for a form configuration file that 64 follows the CGI::FormBuilder::Source::File format (essentially YAML), 65 named for the current action url. So, if you were serving "/books/edit", 66 this plugin would look for: 67 68 root/forms/books/edit.fb 69 70 (The path is configurable.) If no source file is found, then it is 71 assumed you'll be setting up your fields manually. In your controller, 72 you will have to use the "$c->form" object to create your fields, 73 validation, and so on. 74 75 Here is an example "edit.fb" file: 76 77 # Form config file root/forms/books/edit.fb 78 name: books_edit 79 method: post 80 fields: 81 title: 82 label: Book Title 83 type: text 84 size: 40 85 required: 1 86 author: 87 label: Author's Name 88 type: text 89 size: 80 90 validate: NAME 91 required: 1 92 isbn: 93 label: ISBN# 94 type: text 95 size: 20 96 validate: /^(\d{10}|\d{13})$/ 97 required: 1 98 desc: 99 label: Description 100 type: textarea 101 cols: 80 102 rows: 5 103 country: 104 label: Country of Origin 105 type: select 106 required: 1 107 108 submit: Save New Book 109 110 This will automatically create a complete form for you, using the 111 specified fields. Note that the "root/forms" path is configurable; this 112 path is used by default to integrate with the "TTSite" helper. 113 114 Within your controller, you can call any method that you would on a 115 normal "CGI::FormBuilder" object on the "$c->form" object. To manipulate 116 the field named "desc", simply call the "field()" method: 117 118 # Change our desc field dynamically 119 $c->form->field(name => 'desc', 120 label => 'Book Description', 121 required => 1); 122 123 To populate field options for "country", you might use something like 124 this to iterate through the database: 125 126 $c->form->field(name => 'country', 127 options => [ map { [$_->id, $_->name] } 128 $c->model('MyApp::Country')->all ], 129 other => 1, # create "Other:" box 130 ); 131 132 This would create a select list with the last element as "Other:" to 133 allow the addition of more countries. See CGI::FormBuilder for methods 134 available to the form object. 135 136 The FormBuilder methodolody is to handle both rendering and validation 137 of the form. As such, the form will "loop back" onto the same controller 138 method. Within your controller, you would then use the standard 139 FormBuilder submit/validate check: 140 141 if ($c->form->submitted && $c->form->validate) { 142 $c->forward('/books/save'); 143 } 144 145 This would forward to "/books/save" if the form was submitted and passed 146 field validation. Otherwise, it would automatically re-render the form 147 with invalid fields highlighted, leaving the database unchanged. 148 149 To render the form in your template, you can use "render" to get a 150 default table-based form: 151 152 <!-- root/src/books/edit.tt --> 153 [% form.render %] 154 155 You can also get fine-tuned control over your form layout from within 156 your template. 157 158TEMPLATES 159 The simplest way to get your form into HTML is to reference the 160 "form.render" method, as shown above. However, frequently you want more 161 control. 162 163 From within your template, you can reference any of FormBuilder's 164 methods to manipulate form HTML, JavaScript, and so forth. For example, 165 you might want exact control over fields, rendering them in a "<div>" 166 instead of a table. You could do something like this: 167 168 <!-- root/src/books/edit.tt --> 169 <head> 170 <title>[% form.title %]</title> 171 [% form.jshead %]<!-- javascript --> 172 </head> 173 <body> 174 [% form.start %] 175 <div id="form"> 176 [% FOREACH field IN form.fields %] 177 <div id="[%- field.name -%]"> 178 <div class="label"> 179 [% field.required 180 ? qq(<span class="required">$field.label</span>) 181 : field.label 182 %] 183 </div> 184 <div class="field"> 185 [% field.tag %] 186 [% IF field.invalid %] 187 <span class="error"> 188 Missing or invalid entry, please try again. 189 </error> 190 [% END %] 191 </div> 192 </div> 193 [% END %] 194 <div id="submit">[% form.submit %]</div> 195 <div id="reset">[% form.reset %]</div> 196 <div id="state"> 197 [% # The following two tags include state information %] 198 [% form.statetags %] 199 [% form.keepextras %] 200 [% form.end %] 201 </div> 202 </div><!-- form --> 203 </body> 204 205 In this case, you would not call "form.render", since that would only 206 result in a duplicate form (once using the above expansion, and a second 207 time using FormBuilder's default rendering). 208 209 Note that the above form could become a generic "form.tt" template which 210 you simply included in all your files, since there is nothing specific 211 to a given form hardcoded in (that's the idea, after all). 212 213 You can also get some ideas based on FormBuilder's native Template 214 Toolkit support at CGI::FormBuilder::Template::TT2. 215 216CONFIGURATION 217 You can set defaults for your forms using Catalyst's config method: 218 219 MyApp->config(form => { 220 method => 'post', 221 stylesheet => 1, 222 messages => '/locale/fr_FR/form_messages.txt', 223 }); 224 225 This accepts the exact same options as FormBuilder's "new()" method 226 (which is alot). See CGI::FormBuilder for a full list of options. 227 228 Two special configuration parameters control how this plugin resolves 229 form config files: 230 231 form_path 232 The path to configuration files. This should be set to an absolute 233 path to prevent problems. Within this plugin, it is set to: 234 235 form_path => File::Spec->catfile($c->config->{home}, 'root', 'forms'); 236 237 This can be a colon-separated list of directories, if you want to 238 specify multiple paths (ie, "/templates1:/template2"). 239 240 form_suffix 241 The suffix that configuration files have. By default, it is "fb". 242 243 In addition, the following FormBuilder options are automatically set for 244 you: 245 246 action 247 This is set to the URL for the current action. FormBuilder is 248 designed to handle a full request cycle, meaning both rendering and 249 submission. If you want to override this, simply use the "$c->form" 250 object: 251 252 $c->form->action('/action/url'); 253 254 The default setting is "$c->req->path". 255 256 cookies 257 Handling these are disabled (use Catalyst). 258 259 debug 260 This is set to correspond with Catalyst's debug setting. 261 262 header 263 This is disabled. Instead, use Catalyst's header routines. 264 265 params 266 This is set to get parameters from Catalyst, using "$c->req". To 267 override this, use the "$c->form" object: 268 269 $c->form->params(\%param_hashref); 270 271 Overriding this is not recommended. 272 273 source 274 This determines which source file is loaded, to setup your form. By 275 default, this is set to the name of the action URL, with ".fb" 276 appended. For example, "edit_form()" would be associated with an 277 "edit_form.fb" source file. 278 279 To override this, include the path as the argument to the method 280 attribute: 281 282 sub edit : Local Form('/books/myEditForm') { } 283 284 If no source file is found, then it is assumed you'll be setting up 285 your fields manually. In your controller, you will have to use the 286 "$c->form" object to create your fields, validation, and so on. 287 288SEE ALSO 289 CGI::FormBuilder, CGI::FormBuilder::Source::File, 290 CGI::FormBuilder::Template::TT2, Catalyst::Manual, Catalyst::Request, 291 Catalyst::Response 292 293AUTHOR 294 Copyright (c) 2006 Nate Wiger <nate@wiger.org>. All Rights Reserved. 295 296 Thanks to Laurent Dami and Roy-Magne Mo for suggestions. 297 298 This library is free software, you can redistribute it and/or modify it 299 under the same terms as Perl itself. 300 301