Подтвердить что ты не робот

Symfony2 изменяет параметры поля встроенной формы

Мой вопрос в основном заключается в том, можно ли изменить опцию поля встроенного для родительской формы?

Чтобы проиллюстрировать проблему, рассмотрите это; У меня есть класс типа родительской формы:

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType())
        ;
    }

и класс типа дочерней формы, который находится в отдельном комплекте, и я бы предпочел не редактировать, например:

class AppleFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('qty', 'integer', array('label' => 'rubbish label')
        ;
    }

и я хочу изменить метку qty на что-то еще, но я хочу сделать это только в FruitForm, а не везде, где используется AppleForm. Я надеялся, что смогу сделать что-то вроде:

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType(), array('qty' => array('label' => 'better label')))
        ;
    }

или

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType())
        ;

        $builder->get('apple')->get('qty')->setOption('label', 'better label');
    }

но ни один из них (и ряд других попыток) не все мне удалось. Не существует метода setOption, который я вижу.

Кто-нибудь знает, как это сделать?

Спасибо

4b9b3361

Ответ 1

Я также хотел изменить параметры, очевидный вариант "изменить ярлык" для существующего поля из FOSUserBundle. Я знаю, что могу сделать это в Twig или с переводами.

@redbirdo указал мне в правильном направлении: "похоже, что добавление поля с тем же именем заменит его". Здесь решение:

$field = $builder->get('username');         // get the field
$options = $field->getOptions();            // get the options
$type = $field->getType()->getName();       // get the name of the type
$options['label'] = "Login Name";           // change the label
$builder->add('username', $type, $options); // replace the field

Ответ 2

Попробуйте что-то вроде этого:

class AppleFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('qty', 'integer', array('label' => $options['qtyLabel'])
        ;
    }

    public function getDefaultOptions()
    {
        return array(
            'qtyLabel' = 'rubbish label';
        );
    }
}

и

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType(), array('qtyLabel' => 'better label'))
        ;
    }
}

Ответ 3

Большое спасибо @Peter Wooster. В Symfony 3.0 мне пришлось использовать что-то немного другое:

У меня есть настраиваемый тип ввода полей типа:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('my_field', ChoiceType::class, [
        // Some options here...
        'multiple' => false,
    ]);
}

И в другом настраиваемом виде формы мне нужно расширить тип выше и изменить некоторые параметры:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    parent::buildForm($builder, $options);

    $myField = $builder->get('my_field');
    $fieldOptions = $myField->getOptions();
    // Retrieve the FormType. That is the part that is different.
    $fieldType = get_class($myField->getType()->getInnerType());
    $fieldOptions['multiple'] = true;
    // I can obviously put the name 'my_field' directly here
    $builder->add($myField->getName(), $fieldType, $fieldOptions);
}

Благодаря вышеприведенным ответам, я надеюсь, что моя помощь!

Ответ 4

Я в том случае, когда я не могу получить доступ к коду компоновщика форм, но должен переопределить параметры поля, чтобы добавить 'required' => true.

Расширение @peter-wooster и @thedamnedrhino отвечают на вопрос о symfony на github (https://github.com/symfony/symfony/issues/11188), в итоге я получаю этот кусок код.

$field = $form->get('combinaisons');
$options = $field->getConfig()->getOptions();
$type = $field->getConfig()->getType()->getName();
$options['required'] = true;
unset($options['em']);
$form->add('combinaisons', $type, $options); 

Это отлично работает с symfony/symfony: 2.3.21, doctrine/doctrine-bundle: 1.2.0 и doctrine/orm: 2.3.6

Ответ 5

Изменение вида часто намного легче для такого рода изменений.

$view->vars['label'] = 'New label';

Обычно ваше представление будет родительской формой, поэтому оно может выглядеть так: измените значение "Дата" > "Дата публикации":

$view = $form->createView(...);
$view->children['date']->vars['label'] = 'Publication date';

Если ваша форма инкапсулирована в свой собственный тип, вы можете использовать функцию finishView:

public function finishView(FormView $view, FormInterface $form, array $options)
{
    $view->children['date']->vars['label'] = 'Publication date';
}

Так как большая часть того, что наконец передается в механизм шаблонов для рендеринга, находится в форме прямого массива, на данный момент вы можете столкнуться с довольно большим количеством вещей.