Как установить значение по умолчанию для поля формы в Symfony2? - PullRequest
131 голосов
/ 27 октября 2011

Есть ли простой способ установить значение по умолчанию для текстового поля формы?

Ответы [ 22 ]

114 голосов
/ 24 января 2014

вы можете установить значение по умолчанию с помощью empty_data

$builder->add('myField', 'number', ['empty_data' => 'Default value'])
98 голосов
/ 27 октября 2011

Можно легко использовать при создании:

->add('myfield', 'text', array(
     'label' => 'Field',
     'empty_data' => 'Default value'
))
62 голосов
/ 07 августа 2013

Я размышлял об этом несколько раз в прошлом, поэтому подумал, что буду записывать различные идеи, которые я использовал / использовал.Что-то может быть полезным, но ни одно из них не является «идеальным» решением Symfony2.

Конструктор В Entity вы можете сделать $ this-> setBar ('default value');но это вызывается каждый раз, когда вы загружаете объект (дБ или нет), и это немного грязно.Тем не менее, он работает для каждого типа поля, так как вы можете создавать даты или все, что вам нужно.

Если операторы в get получают , я бы не стал, но вы могли бы.

return ( ! $this->hasFoo() ) ? 'default' : $this->foo;

Фабрика / экземпляр .Вызов статической функции / вторичного класса, который предоставляет вам объект по умолчанию, предварительно заполненный данными.Например,

function getFactory() {
    $obj = new static();
    $obj->setBar('foo');
    $obj->setFoo('bar');

   return $obj;
}

Не совсем идеально, учитывая, что вам придется поддерживать эту функцию, если вы добавляете дополнительные поля, но это означает, что вы отделяете установщики данных / default и то, что генерируется из БД.Точно так же вы можете иметь несколько getFactories, если вам нужны разные данные по умолчанию.

Расширенные / Отраженные сущности Создать расширяющий объект (например, FooCreate extends Foo), который дает вам данные по умолчанию во время создания (черезконструктор).Аналогично идее Factory / instance, просто другой подход - я лично предпочитаю статические методы.

Установка данных перед формой сборки В конструкторах / сервисе вы знаете, есть ли у вас новая сущность илиесли он был заселен из БД.Поэтому возможно вызвать данные набора для разных полей, когда вы захватываете новую сущность.Например,

if( ! $entity->isFromDB() ) {
     $entity->setBar('default');
     $entity->setDate( date('Y-m-d');
     ...
}
$form = $this->createForm(...)

События формы При создании формы вы устанавливаете данные по умолчанию при создании полей.Вы переопределяете это, используя прослушиватель событий PreSetData.Проблема заключается в том, что вы дублируете рабочую нагрузку формы / дублируете код и усложняете поддержку / понимание.

Расширенные формы Аналогично событиям формы, но вы вызываете другой типв зависимости от того, если это дБ / новый объект.Под этим я подразумеваю, что у вас есть FooType, который определяет вашу форму редактирования, BarType расширяет FooType и устанавливает все данные в поля.В вашем контроллере вы просто выбираете, какой тип формы вызывать.Это отстой, если у вас есть пользовательская тема, хотя и как события, создает слишком много обслуживания для моего вкуса.

Twig Вы можете создать свою собственную тему и по умолчанию данные, используя параметр значения, когдаВы делаете это на основе поля.Ничто не мешает вам обернуть это в тему формы, если вы хотите сохранить ваши шаблоны в чистоте и повторно использовать форму.например,

form_widget(form.foo, {attr: { value : default } });

JS Было бы тривиально заполнить форму функцией JS, если поля пусты.Вы могли бы сделать что-нибудь с заполнителями, например.Хотя это плохая, плохая идея.

Формы как сервис Для одного из моих крупных проектов на основе форм я создал сервис, который генерировал все формы и всю обработкуи т. д. Это произошло потому, что формы должны были использоваться на нескольких контроллерах в нескольких средах, и хотя формы создавались / обрабатывались одинаково, они отображались / взаимодействовали по-разному (например, обработка ошибок, перенаправления и т. д.).Прелесть этого подхода заключалась в том, что вы можете использовать данные по умолчанию, делать все, что вам нужно, обрабатывать ошибки в общем и т. Д., И все это инкапсулировано в одном месте.

Заключение Как я вижу, выснова и снова сталкивайтесь с одной и той же проблемой - где хранятся данные по умолчанию?

  • Если вы храните его на уровне базы данных / доктрины, что произойдет, если вы не хотите сохранять значение по умолчанию каждый раз?
  • Если вы сохраните его на уровне сущности, что произойдет, если выхотите повторно использовать этот объект в другом месте без каких-либо данных в нем?
  • Если вы сохраните его на уровне сущности и добавите новое поле, хотите ли вы, чтобы предыдущие версии имели значение по умолчанию при редактировании?То же самое касается по умолчанию в БД ...
  • Если вы храните его на уровне формы, становится ли это очевидным, когда вы позже захотите сохранить код?
  • Если это в конструкторе, что произойдет, если вы используете форму в нескольких местах?
  • Если вы поднимаете его до уровня JS, значит, вы зашли слишком далеко - данные не должны быть в поле зрения, не говоря уже о JS (и мы игнорируем совместимость, ошибки рендеринга и т. Д.)
  • Сервис отличный, если, как и я, вы используете его в нескольких местах, но для простой формы добавления / редактирования на одном сайте это излишне ...

С этой целью я каждый раз подходил к проблеме по-разному. Например, опция «новостная рассылка» формы регистрации легко (и логически) устанавливается в конструкторе непосредственно перед созданием формы. Когда я создавал коллекции форм, которые были связаны друг с другом (например, какие переключатели в разных типах форм были связаны друг с другом), я использовал прослушиватели событий. Когда я построил более сложную сущность (например, для которой требовались дочерние элементы или много данных по умолчанию), я использовал функцию (например, «getFactory»), чтобы создать элемент по мере необходимости.

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

Удачи! Надеюсь, я дал вам пищу для размышлений, во всяком случае, и не слишком много болтал;)

42 голосов
/ 20 марта 2013

Если вам нужно установить значение по умолчанию и ваша форма связана с сущностью, то вам следует использовать следующий подход:

// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
    ...
    ->add(
        'myField',
        'text',
        array(
            'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
        )
    );
}

В противном случае, myField всегда будет иметь значение по умолчанию, вместо получениязначение от сущности.

19 голосов
/ 27 октября 2011

Вы можете установить значение по умолчанию для связанного поля в классе модели (в определении отображения или установить значение самостоятельно).

Кроме того, FormBuilder дает вам возможность установить начальные значения с помощью setData () метод.Построитель форм передается методу createForm () вашего класса форм.

Также проверьте эту ссылку: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class

16 голосов
/ 03 апреля 2013

Если ваша форма связана с сущностью, просто установите значение по умолчанию для самой сущности, используя метод конструкции:

public function __construct()
{
    $this->field = 'default value';
}
12 голосов
/ 01 августа 2013

Подход 1 (из http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/)

Просто установите значение по умолчанию в вашей сущности, либо в объявлении переменной, либо в конструкторе:

class Entity {
    private $color = '#0000FF';
    ...
}

или

class Entity {
    private $color;

    public function __construct(){
         $this->color = '#0000FF';
         ...
    }
    ...
}

Подход 2 из комментария в приведенной выше ссылке, а также ответ Дмитрия (не принятый) из Как установить значение по умолчанию для поля формы в Symfony2?

Добавить значение по умолчанию для атрибута данных при добавлении поля с помощью FormBuilder, адаптированного из ответа Дмитрия.

Обратите внимание, что это предполагает, что свойство будет иметь и будет иметь значение null, когда это новая, а не существующая сущность.

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('color', 'text', array(
            'label' => 'Color:',
            'data' => (isset($options['data']) && $options['data']->getColor() !== null) ? $options['data']->getColor() : '#0000FF'
        )
    );
}
9 голосов
/ 16 октября 2016

Общее решение для любого случая / подхода, в основном с использованием формы без класса или когда нам нужен доступ к любым службам для установки значения по умолчанию:

// src/Form/Extension/DefaultFormTypeExtension.php

class DefaultFormTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if (null !== $options['default']) {
            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($options) {
                    if (null === $event->getData()) {
                        $event->setData($options['default']);
                    }
                }
            );
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('default', null);
    }

    public function getExtendedType()
    {
        return FormType::class;
    }
}

и зарегистрируйте расширение формы:

app.form_type_extension:
    class: App\Form\Extension\DefaultFormTypeExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

После этого мы можем использовать опцию default в любом поле формы:

$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
9 голосов
/ 06 сентября 2013

Вы можете установить значение по умолчанию, например, для формы message, например:

$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
    ->add('name', 'text')
    ->add('email', 'email')
    ->add('message', 'textarea')
    ->add('send', 'submit')
    ->getForm();

В случае, если ваша форма сопоставлена ​​с сущностью, вы можете пойти так (например, имя пользователя по умолчанию):

$user = new User();
$user->setUsername('John Doe');

$form = $this->createFormBuilder($user)
    ->add('username')
    ->getForm();
6 голосов
/ 18 апреля 2016
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if ($data == null) {
         $form->add('position', IntegerType::class, array('data' => 0));
     }

});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...