How to repopulate a form from the request
Overview
The default value given to a form field usually depends either on the Model (if the form is displayed for the first time) and on the previous entry by the user (if the form is displayed for the second time). Handling these cases by hand can be cumbersome, especially since some form controls have a specific way of passing their value in the request parameters. That's why symfony handles the form repopulation (the process to fill in form controls from the request) with a special filter called the sfFillInFormFilter. There are two ways to use this filter, depending on whether the form has a validation or not.
Repopulation on a form without validation
The simplest example of a form that needs repopulation is a full-text search engine with a single text input.
<?php echo form_tag('product/find', 'method=get') ?>
<?php echo input_tag('word', 'Enter a word') ?>
<?php echo submit_tag('Search') ?>
</form>
When the user types a word and submits a query to the search engine (in this example, the product/find action), the form is usually displayed again in the result page, and the rules of user-friendly interfaces make that this form should display the word previously entered by the user. You could handle it manually by specifying a value for the input tag:
<?php echo input_tag('word', $sf_params->get('word', 'Enter a word')) ?>
But try to imagine more complicated cases, where the default value comes from the server, or where you have a radiobutton tag or a select tag. Handling all that becomes long and painful in the long run, especially if you have forms with a large number of controls.
Symfony can handle repopulation automatically. To enable that behaviour, you just need to add a filters.yml in your module config/ folder and enable the sfFillInFormFilter:
myFillInFormFilter:
class: sfFillInFormFilter
When displaying the form, symfony will check if the request contains parameters matching the form elements names and use them to fill the input tag automatically.
Repopulation of a form with validation
If you defined a validation file for a form (see how in the form validation chapter), you probably want the form to be displayed again with error messages and the value entered by the user when the validation fails. Instead of adding a filter.yml like above, you can directly declare the use of the sfFillInFormFilter in the validation file.
For instance, if a product form calls an add action, its validation uses a validate/add.yml file. To enable repopulation in the form on failed validation, add the following lines to the add.yml file:
fillin:
enabled: on
Filter parameters
The sfFillInFormFilter accepts additional parameters for the cases when you want to refine its action. The syntax is the same for a declaration in the filters.yml and in a validation file: just add a param: key to the filter declaration.
Page with multiple forms
If you want to restrict the action of the filter to a given form, for instance if your page contains more than one form, pass the name of the form to be repopulated as a parameter. For instance, a form named 'search':
// in the template
<?php echo form_tag('product/find', 'name=search') ?>
Is targeted in a filter.yml by:
myFillInFormFilter:
class: sfFillInFormFilter
param:
name: search # name of the form
If you prefer a validation file, the syntax is:
fillin:
enabled: on
param:
name: search # name of the form
Converters
You may want to modify the data entered by the user before inserting and displaying it as values in the form. For instance, you may wish to remove any password from the request, to force the user to re-enter it (the same applies for captchas). Or you could desire to apply htmlentities() to the content of a textarea, to avoid scripting issues. This is all done through a converters: parameter, where you can specify a PHP function to be applied to one or more of the form inputs:
myFillInFormFilter:
class: sfFillInFormFilter
param:
converters:
htmlentities: [word]
serialize: [site_url]
empty_string: [captcha, password]
As you can see, you can use existing PHP functions as converters or a function that you defined youself:
public function empty_string()
{
return '';
}
|