Rene Terstegen
Rene Terstegen

Reputation: 8046

Symfony2: Order form fields

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

Answers (3)

Pavel Galaton
Pavel Galaton

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

Alex
Alex

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

sampleNull
sampleNull

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

Related Questions