Как установить значение по умолчанию для поля формы в Symfony2?

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

21 ответов


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

->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => 'Default value'
))

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

$builder->add('myField', 'number', ['empty_data' => 'Default value'])

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

конструктор В сущности вы можете сделать $this - >setBar ('значение по умолчанию'); но это вызывается каждый раз, когда вы загружаете сущность (db или нет) и немного беспорядочно. Однако он работает для каждого типа поля, поскольку вы можете создавать даты или все, что вам нужно.

если заявления в получить Я бы не стал, но можно.

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

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

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

   return $obj;
}

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

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

установить данные перед формой сборки В конструкторах / службе вы знаете, есть ли у вас новый объект или он был заполнен из БД. Поэтому правдоподобно вызывать set data в разных полях при захвате нового объекта. Е. Г.

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

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

расширенной формы Похожие на Form events, но вы называете другой тип в зависимости от того, является ли это DB / new entity. Под этим я подразумеваю, что у вас есть FooType, который определяет вашу форму редактирования, BarType расширяет FooType this и устанавливает все данные в поля. В вашем контроллере вы просто выбираете, какой тип формы инициировать. Это отстой, если у вас есть пользовательская тема, хотя и как события, создает слишком много обслуживания по моему вкусу.

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

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

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

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

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

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

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

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

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


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

// 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 всегда будет установлено значение по умолчанию, Вместо получения значения от сущности.


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

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

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


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

public function __construct()
{
    $this->field = 'default value';
}

подход 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?

добавить значение по умолчанию значение атрибута data при добавлении поля с 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'
        )
    );
}

вы можете установить значение по умолчанию, например, в форме 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();

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

// 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'));

->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));
     }

});

просто, чтобы я понял проблему.

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

лично я думаю ,что решение @ MolecularMans-это путь. Я бы фактически установил значения по умолчанию в конструкторе или в инструкции property. Но тебе, кажется, не нравится такой подход.

вместо этого вы можете следуйте за этим:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

вы вешаете прослушиватель на свой тип формы, а затем можете проверить свою сущность и настроить builder->add операторы соответственно на основе havine новой или существующей сущности. Вам все равно нужно указать значения по умолчанию, хотя вы можете просто закодировать их в своем прослушивателе. Или передайте их в тип формы.

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


Если вы используете FormBuilder в symfony 2.7 для создания формы вы также можете передать исходные данные в createFormBuilder метод контролера

$values = array(
    'name' => "Bob"
);

$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');

не использовать:

'data' => 'Default value'

читайте здесь:https://symfony.com/doc/current/reference/forms/types/form.html#data

"параметр data всегда переопределяет значение, взятое из данных домена (объекта) при отрисовке. Это означает, что значение объекта также переопределяется, когда форма изменяет уже сохраненный объект, в результате чего он теряет свое сохраненное значение при отправке формы."


использовать следующий:

допустим, для этого примера у вас есть сущность Foo, и есть поле "active" (в этом примере это CheckBoxType, но процесс одинаков для каждого другого типа), которое вы хотите проверить по умолчанию

в вашем классе FooFormType добавьте:

...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
...
public function buildForm( FormBuilderInterface $builder, array $options )
{
    ...

    $builder->add('active', CheckboxType::class, array(
        'label' => 'Active',
    ));

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event){                 
            $foo = $event->getData();
            // Set Active to true (checked) if form is "create new" ($foo->active = null)
            if(is_null($foo->getActive())) $data->setActive(true);
        }
   );
}
public function configureOptions( OptionsResolver $resolver )
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle:Foo',
    ));
}

мое решение:

$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
            'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
        )) ;

часто, для значений init по умолчанию формы я использую светильники. Конечно, этот путь не самый легкий, но очень удобный.

пример:

class LoadSurgeonPlanData implements FixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $surgeonPlan = new SurgeonPlan();

        $surgeonPlan->setName('Free trial');
        $surgeonPlan->setPrice(0);
        $surgeonPlan->setDelayWorkHours(0);
        $surgeonPlan->setSlug('free');

        $manager->persist($surgeonPlan);
        $manager->flush();        
    }   
}

тем не менее, поле типа symfony имеет опцию сведения.

пример

$builder->add('token', 'hidden', array(
    'data' => 'abcdef',
));

есть очень простой способ, вы можете установить по умолчанию как здесь :

$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);

$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();

Если вы установите "данные" в форме создания, это значение не будет изменено при редактировании сущности.

мое решение :

public function buildForm(FormBuilderInterface $builder, array $options) {
    // In my example, data is an associated array
    $data = $builder->getData();

    $builder->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
    ));
}

тю.


значения по умолчанию устанавливаются путем настройки соответствующей сущности. Перед привязкой сущности к форме установите ее цветовое поле в "#0000FF":

// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);

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

пример:

public function getMyField() {
    if (is_null($this->MyField)) {
        $this->setMyField('my default value');
    }
    return $this->MyField;
}

обычно я просто устанавливаю значение по умолчанию для определенного поля в моей сущности:

/**
 * @var int
 * @ORM\Column(type="integer", nullable=true)
 */
protected $development_time = 0;

Это будет работать для новых записей или просто для обновления существующих.


как Брайан спросил:

empty_data появляется только на поле 1, если он представлен без стоимости. А когда вы хотите, чтобы форма по умолчанию отображаются 1 в ввод, когда нет значения?

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

$builder->add('myField', 'number', ['empty_value' => 'Default value'])