Reputation: 8046
Consider this piece of code:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text')
->add('description', 'textarea')
->add('status', 'choice', array('choices' => array('online' => 'online', 'offline' => 'offline')))
->add('save', 'submit');
}
But when I render this form I get it in the order
description
name
status
How can I change this besides writing the form template by hand.
Upvotes: 0
Views: 3032
Reputation: 593
Had same issue today with the form elements ordering.
Ended up with a trait that will override finishView method and reorder items in children property of a FormView:
trait OrderedTrait
{
abstract function getFieldsOrder();
public function finishView(FormView $view, FormInterface $form, array $options)
{
/** @var FormView[] $fields */
$fields = [];
foreach ($this->getFieldsOrder() as $field) {
if ($view->offsetExists($field)) {
$fields[$field] = $view->offsetGet($field);
$view->offsetUnset($field);
}
}
$view->children = $fields + $view->children;
parent::finishView($view, $form, $options);
}
}
Then in type implement getFieldsOrder method:
use OrderedTrait;
function getFieldsOrder()
{
return [
'first',
'second',
'next',
'etc.',
];
}
Upvotes: 4
Reputation: 1573
You are hoping to control the render order from your PHP, but in reality, your PHP ought not know about, nor care about, how information is rendered. The order of rendering is handled in the template, preferably via twig, as it is the template's responsibility to handle this. It is a straightforward process, and gives you plenty of control. The following Twig template ought to fix your order:
{{form_start(nameOfFormVariablePassedFromController}}
{{form_label(nameOfFormVariablePassedFromController.name)}}
{{form_widget(nameOfFormVariablePassedFromController.name)}}
{{form_label(nameOfFormVariablePassedFromController.description)}}
{{form_widget(nameOfFormVariablePassedFromController.description)}}
{{form_label(nameOfFormVariablePassedFromController.status)}}
{{form_widget(nameOfFormVariablePassedFromController.status)}}
{{form_widget(nameOfFormVariablePassedFromController.save)}}
{{form_end(nameOfFormVariablePassedFromController}}
It is easy to add classes to these labels and widgets for styling, by adding extra arguments. I can help with this if you need further clarification.
Upvotes: 0
Reputation: 126
You can use https://github.com/egeloen/ivory-ordered-form/ bundle. Maybe someday it will be integrated into core. For now, symfony Form component doesn't have any order option.
Upvotes: 2