Iterating over Symfony Forms for Custom Output
by Matt DaumRecently we were working on a project in which we needed to switch from forms auto-formatting themselves ( <?php echo $form;?>) to allow for much more customization in the output. While there is a Symfony Forms for Designers chapter in the forms documentation, it doesn’t help much for iterating over a form object and customizing the output. There is a simple foreach($form as $field) that will iterate over every field in the form. The problem with this is when you have embedded forms and you want to do something different with the formatting on them. This will iterate over all the fields and you will not know when the field is the embedded form or not. So we came up with the following which works:
foreach($form as $field)
{
// If this is true, then that means its an embedded form.
if(get_class($field)=='sfFormFieldSchema')
{
foreach($field as $f)
{
// Don't want to see hidden field labels
if(!$f->isHidden())
echo $f->renderLabel()." ";
echo $f->renderError();
echo $f->render();
}
}
else
{
if(!$field->isHidden())
echo $field->renderLabel()." ";
echo $field->renderError();
echo $field->render();
}
}
This will work fine for a form with as many as single embedded forms. It allows you to easily use the same view for multiple forms and be able to customize their embedded forms easily. If you have only one form that you will be doing this with, and are worried about performance we recommend then not using a foreach loop and doing it by hand, this will save you on performance as you will not have as many if statements in each iteration.
Tags: customization, sfForms, symfony

August 28th, 2009 at 2:55 am
The same but recursive and with support of any level of embedded forms:
isHidden()) {
echo $field->renderRow();
}
}
}
echo $form->renderHiddenFields();
echo $form->renderGlobalErrors();
display_form($form);
?>
August 28th, 2009 at 2:57 am
Oops, it seems that your comment system eat the code !
Check the correct code at http://github.com/dunglas/piy/blob/638f9c5bbfbe883d301bcf2c7bfa94509791d41b/apps/frontend/modules/sfGuardAuth/templates/registerSuccess.php
August 28th, 2009 at 6:10 am
Kevin-
Great example. I’ve posted your code at the bottom of this comment for reference. In our example we actually had a specific layout for the embedded form (first embedded form that is). In this case you could add to your example a $level variable and passed that through each recursion in order to format the form differently per level.
function display_form($form) { foreach($form as $field) { if (get_class($field) == 'sfFormFieldSchema') { display_form($field); } elseif (!$field->isHidden()) { echo $field->renderRow(); } } }December 7th, 2009 at 9:22 am
Great solutions, but I have a question. I`ve some embeded form and submit button is render before first embeded form. How can i change this to render submit after all embeded forms?