Есть ли простой способ установить значение по умолчанию для поля текстовой формы?
Есть ли простой способ установить значение по умолчанию для поля текстовой формы?
Ответы:
Можно легко использовать при создании:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
ключ на'value'
empty_data
data
бесполезно - затирает сохраненное значение. empty_data
не показывает значение, он использует его при отправке пустого значения и делает невозможным сохранение непроверенных вариантов.
вы можете установить значение по умолчанию с помощью empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
Я размышлял об этом несколько раз в прошлом, поэтому решил записать разные идеи, которые у меня были / использовались. Что-то может быть полезно, но ни одно из решений для Symfony2 не является "идеальным".
Конструктор В Entity вы можете сделать $ this-> setBar ('значение по умолчанию'); но это вызывается каждый раз, когда вы загружаете объект (db или нет), и это немного беспорядочно. Однако он работает для каждого типа поля, поскольку вы можете создавать даты или что-то еще, что вам нужно.
Если бы заявления внутри были, я бы не стал, но вы могли бы.
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Завод / экземпляр . Вызов статической функции / вторичного класса, который предоставляет вам объект по умолчанию, предварительно заполненный данными. Например
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
Не совсем идеально, учитывая, что вам придется поддерживать эту функцию, если вы добавляете дополнительные поля, но это означает, что вы разделяете установщики данных / default и те, которые генерируются из db. Точно так же у вас может быть несколько getFactories, если вам нужны разные данные по умолчанию.
Сущности Extended / Reflection Создайте расширяющуюся сущность (например, FooCreate extends Foo), которая дает вам данные по умолчанию во время создания (через конструктор). Подобно идее Factory / instance, только другой подход - лично я предпочитаю статические методы.
Установить данные перед формой сборки В конструкторах / сервисах вы знаете, есть ли у вас новый объект или он был заполнен из базы данных. Поэтому правдоподобно вызывать набор данных в разных полях, когда вы захватываете новую сущность. Например
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
События формы При создании формы вы устанавливаете данные по умолчанию при создании полей. Вы переопределяете это использование прослушивателя событий PreSetData. Проблема в том, что вы дублируете рабочую нагрузку формы / дублируете код и затрудняете поддержку / понимание.
Расширенные формы Подобно событиям формы, но вы вызываете другой тип в зависимости от того, является ли это сущностью db / new. Под этим я подразумеваю, что у вас есть FooType, который определяет вашу форму редактирования, BarType расширяет FooType this и устанавливает все данные в поля. Затем в вашем контроллере вы просто выбираете, какой тип формы инициировать. Это отстой, если у вас есть настраиваемая тема и, как и события, требуется слишком много обслуживания, на мой вкус.
Twig Вы можете создать свою собственную тему и использовать данные по умолчанию, используя параметр значения, если вы делаете это для отдельных полей. Ничто не мешает вам обернуть это в тему формы, если вы хотите, чтобы ваши шаблоны были чистыми, а форму можно было использовать повторно. например
form_widget(form.foo, {attr: { value : default } });
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
всегда будет установлено значение по умолчанию вместо получения значения от объекта.
$options['data']->getMyField()
на$option['data']['myField']
empty_data
: Этот параметр определяет, какое значение будет возвращать поле, если отправленное значение пусто. Не устанавливает начальное значение
Вы можете установить значение по умолчанию для связанного поля в вашем классе модели (в определении сопоставления или установить значение самостоятельно).
Кроме того, FormBuilder дает вам возможность установить начальные значения с помощью метода setData () . Конструктор форм передается методу createForm () вашего класса формы.
Также проверьте эту ссылку: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
Если ваша форма привязана к сущности, просто установите значение по умолчанию для самой сущности, используя метод построения:
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
). Используйте setData(...)
для этого.
Подход 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();
В случае, если ваша форма сопоставлена с сущностью, вы можете сделать это (например, имя пользователя по умолчанию):
$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'));
Не используйте:
'data' => 'Default value'
Читайте здесь: https://symfony.com/doc/current/reference/forms/types/form.html#data
«Параметр данных всегда переопределяет значение, полученное из данных домена (объекта) при визуализации. Это означает, что значение объекта также переопределяется, когда форма редактирует уже сохраненный объект, в результате чего он теряет свое постоянное значение при отправке формы».
Используйте следующее:
Допустим, в этом примере у вас есть Entity 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())) $foo->setActive(true);
}
);
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle:Foo',
));
}
'data' => $data['myfield'] ?? 'Default value'
->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));
}
});
$event->setData()
вместо чтения поля может сделать его еще лучше.
Просто так я понимаю проблему.
Вы хотите настроить способ построения формы на основе данных в вашей сущности. Если объект создается, используйте какое-то значение по умолчанию. Если объект существует, используйте значение базы данных.
Лично я думаю, что решение @MolecularMans - это правильный путь. Я бы фактически установил значения по умолчанию в конструкторе или в заявлении свойства. Но, похоже, вам не нравится такой подход.
Вместо этого вы можете следовать этому: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
Вы вешаете прослушиватель на свой тип формы, а затем можете проверить свою сущность и соответствующим образом настроить операторы builder-> add на основе создания новой или существующей сущности. Вам все равно нужно где-то указать значения по умолчанию, хотя вы можете просто закодировать их в своем слушателе. Или передайте их в тип формы.
Хотя, похоже, много работы. Лучше просто передать сущность в форму с уже установленными значениями по умолчанию.
Часто для значений формы по умолчанию я использую фикстуры. Конечно, это не самый простой способ, но очень удобный.
Пример:
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',
));
}
До свидания.
'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'
используется обратный вызов, чтобы разрешить параметры конструктора для объекта.
Как спросил Брайан:
empty_data, похоже, устанавливает для поля значение 1 только тогда, когда оно отправляется без значения. А как насчет того, чтобы форма по умолчанию отображала 1 во входных данных, когда значение отсутствует?
вы можете установить значение по умолчанию с помощью empty_value
$builder->add('myField', 'number', ['empty_value' => 'Default value'])