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

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

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

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

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

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

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

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

Если бы заявления внутри get's я бы не сделал, но вы могли бы.

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

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

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

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

Объекты Extended / Reflection Создают расширяющийся Entity (например, FooCreate extends Foo), который дает данные по умолчанию во время создания (через конструктор). Подобно идее Factory / instance просто другой подход – я предпочитаю статические методы лично.

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

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

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

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

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

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

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

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

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

  • Если вы храните его на уровне db / doctrine, что произойдет, если вы не хотите сохранять значение по умолчанию каждый раз?
  • Если вы сохраните его на уровне Entity, что произойдет, если вы хотите повторно использовать этот объект в другом месте без каких-либо данных?
  • Если вы храните его на уровне Entity Level и добавляете новое поле, хотите ли вы, чтобы предыдущие версии имели это значение по умолчанию при редактировании? То же самое касается значения по умолчанию в БД …
  • Если вы храните его на уровне формы, это очевидно, когда вы приходите для поддержки кода позже?
  • Если в конструкторе это происходит, если вы используете форму в нескольких местах?
  • Если вы нажмете его на уровень 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

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

 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?

Добавьте значение по умолчанию в атрибут данных при добавлении поля с помощью 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(); 

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

 $user = new User(); $user->setUsername('John Doe'); $form = $this->createFormBuilder($user) ->add('username') ->getForm(); 

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

 class FormTypeExtension 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; } } по class FormTypeExtension 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: AdminBundle\Form\Extension\BootstrapAdminFormTypeExtension 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 – это путь. Я бы фактически установил значения по умолчанию в конструкторе или в заявлении свойства. Но вам, похоже, не нравится этот подход.

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

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

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

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

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

Мое решение:

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

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

Пример:

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

Значения по умолчанию устанавливаются путем настройки соответствующего объекта. Прежде чем привязать объект к форме, установите его цветовое поле в «# 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; 

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

Если вы установите «данные» в своей форме создания, это значение не будет изменено при редактировании вашего объекта.

Мое решение:

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

До свидания.

Когда Брайан спросил:

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

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

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