Вопрос

First of all, I am sorry if the question title is a bit odd, but I do not know what else to call it...

I have this form class, which I cannot change:

class ItemDetailType extends AbstractType {


/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
        ->add('name', 'text', array(
            'label' => 'Název'))
        ->add('room', 'entity', array(
                'class' => 'CvutFitIctCtuIdentityBundle:Room',
                'label' => 'Místnost'))
        ->add('person', 'entity', array(
                'class' => 'CvutFitIctCtuIdentityBundle:Person',
                'label' => 'Osoba'))
        ->add('organizationalUnit', 'entity', array(
            'class' => 'CvutFitIctCtuIdentityBundle:OrganizationalUnit',
            'label' => 'Organizační jednotka'))
        ;
    $builder->setAttribute('attr', array());
    if (isset($options['render_submit']) && $options['render_submit'])
        $builder
            ->add('submit', 'submit', array(
                'label' => 'Uložit',
                'attr' => array('class' => 'btn btn-success')))
            ->add('reset', 'reset', array(
                'label' => 'Zrušit',
                'attr' => array('class' => 'btn btn-danger')))
    ;
}

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
            'data_class' => 'Cvut\Fit\BiWt2\InventoryBundle\Entity\Item',
            'render_submit' => true,
            'attr' => array(
                    'role' => 'form',
                    'class' => 'form-horizontal'
            )
    ));
}

/**
 * @return string
 */
public function getName() {
    return 'cvut_fit_biwt2_inventory_form_item';
}
}

But in a template, I have to render only some of the rows (room, person, organizationalUnit and submit), and not render name and reset. This is in the conditions I am obliged to meet, so editing the class is not a valid option.

In controller I create the form like this:

$form = $this->createForm(
    new ItemDetailType, $item, array(
        'action' => $this->generateUrl('items_detail_form', array('id' => $id)),
        'render_submit' => true
    )
);

I tried to render only the desired rows this way, but it only makes the go on top of the form and the remaining two are still rendered under them...

{{ form_start(form) }}
    {{ form_errors(form) }}

    {{ form_row(form.room) }}
    {{ form_row(form.person) }}
    {{ form_row(form.organizationalUnit) }}
    {{ form_row(form.submit) }}
{{ form_end(form) }}

So I am a bit confused now. Is this the correct behavior? If yes, than how do I achieve what I need? The documentation is somewhat brief about this...

Thank you very much!

Это было полезно?

Решение

In symfony2 the default behaviour of:

{{ form_end(form) }}

is render all (even not mentioned before) fields like

{{ form_rest(form) }}

If you want to prevent this behaviour the one option is use:

</form>

or the better way like in this document http://symfony.com/doc/current/reference/forms/twig_reference.html#form-end-view-variables

{{ form_end(form, {'render_rest': false}) }}

Remember to render CSRF token manualy if you do this in that way:

{{ form_widget(form._token) }}

Другие советы

what about using

{% do form.name.setRendered %}
{% do form.reset.setRendered %}

This tell twig that the fields are shown even if they aren't

I am confused as to what exactly do you want to achieve here. But here are some thoughts:

You can create a new form type that extends this one if you want.

class ShorterItemDetailType extends ItemDetailType
{
    public function buildForm(FormBuilderInterface $builder, array $options) {
        // only add the fields you want
    }

    public function getParent() {
        return 'cvut_fit_biwt2_inventory_form_item'
    }

    /**
     * @return string
     */
    public function getName() {
        return 'cvut_fit_biwt2_inventory_form_item_shorter';
    }

}

And in your controller use this one.

$form = $this->createForm(
    new ShorterItemDetailType(), $item, array(
        'action' => $this->generateUrl('items_detail_form', array('id' => $id))
    )
);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top