Existe uma maneira fácil de definir um valor padrão para o campo de formulário de texto?
Existe uma maneira fácil de definir um valor padrão para o campo de formulário de texto?
Respostas:
Pode ser usado durante a criação facilmente com:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
chave para'value'
empty_data
data
é inútil - substitui o valor salvo. empty_data
não mostra o valor, ele é usado no envio de valor vazio e torna impossível salvar opções desmarcadas.
você pode definir o valor padrão com empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
Eu já contemplei isso algumas vezes no passado, então pensei em anotar as diferentes idéias que tive / usei. Algo pode ser útil, mas nenhuma é a solução "perfeita" do Symfony2.
Construtor Na Entidade, você pode fazer $ this-> setBar ('valor padrão'); mas isso é chamado toda vez que você carrega a entidade (db ou não) e fica um pouco confuso. No entanto, funciona para todos os tipos de campos, pois você pode criar datas ou qualquer outra coisa que precisar.
Se declarações dentro de get's eu não, mas você poderia.
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Fábrica / instância . Chame uma função estática / classe secundária que fornece uma entidade padrão previamente preenchida com dados. Por exemplo
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
Não é realmente ideal, pois você terá que manter essa função se adicionar campos extras, mas isso significa que você está separando os configuradores de dados / padrão e o que é gerado a partir do banco de dados. Da mesma forma, você pode ter vários getFactories caso deseje diferentes dados padrão.
Entidades estendidas / de reflexão Crie uma Entidade estendida (por exemplo, FooCreate estende Foo) que fornece os dados padrão no momento da criação (por meio do construtor). Semelhante à idéia de fábrica / instância, apenas uma abordagem diferente - prefiro métodos estáticos pessoalmente.
Definir dados antes do formulário de compilação Nos construtores / serviço, você sabe se possui uma nova entidade ou se foi preenchida a partir do banco de dados. Portanto, é plausível chamar dados do conjunto nos diferentes campos quando você pega uma nova entidade. Por exemplo
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
Eventos do formulário Ao criar o formulário, você define os dados padrão ao criar os campos. Você substitui esse ouvinte de evento PreSetData de uso. O problema é que você está duplicando a carga de trabalho do formulário / duplicando o código e dificultando a manutenção / compreensão.
Formulários estendidos Semelhante aos eventos de Formulário, mas você chama o tipo diferente, dependendo se é uma entidade db / new. Com isso, quero dizer que você tem o FooType, que define seu formulário de edição, o BarType estende o FooType e define todos os dados para os campos. No seu controlador, basta escolher o tipo de formulário a ser instalado. Isso é péssimo se você tiver um tema personalizado e, como eventos, criar muita manutenção para o meu gosto.
Twig Você pode criar seu próprio tema e usar como padrão os dados usando a opção de valor também ao fazê-lo por campo. Não há nada que impeça que você envolva isso em um tema de formulário, caso deseje manter seus modelos limpos e o formulário reutilizável. por exemplo
form_widget(form.foo, {attr: { value : default } });
JS Seria trivial preencher o formulário com uma função JS se os campos estiverem vazios. Você poderia fazer algo com espaços reservados, por exemplo. Essa é uma péssima idéia, no entanto.
Formulários como um serviço Para um dos grandes projetos baseados em formulários que criei, criei um serviço que gerava todos os formulários, fazia todo o processamento etc. Isso acontecia porque os formulários eram para serem usados em vários controladores em vários ambientes e enquanto os formulários foram gerados / manipulados da mesma maneira, foram exibidos / interagiram de maneira diferente (por exemplo, tratamento de erros, redirecionamentos etc.). A vantagem dessa abordagem foi que você pode usar como padrão os dados, fazer tudo o que precisa, lidar com os erros genericamente, etc, e tudo está encapsulado em um só lugar.
Conclusão A meu ver, você encontrará o mesmo problema várias vezes - onde estão os dados padrão?
Para esse fim, abordei o problema de forma diferente a cada vez. Por exemplo, uma opção "boletim informativo" do formulário de inscrição é configurada facilmente (e logicamente) no construtor antes de criar o formulário. Quando eu estava criando coleções de formulários vinculadas (por exemplo, quais botões de opção em diferentes tipos de formulários vinculados), usei Ouvintes de Eventos. Quando criei uma entidade mais complicada (por exemplo, uma que exigisse filhos ou muitos dados padrão), usei uma função (por exemplo, 'getFactory') para criar o elemento conforme necessário.
Não acho que exista uma abordagem "correta", pois toda vez que tenho esse requisito, ele é um pouco diferente.
Boa sorte! Espero ter dado a você alguma opinião sobre o assunto e não divagado demais;)
Se você precisar definir o valor padrão e seu formulário estiver relacionado à entidade, use a seguinte abordagem:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
'myField',
'text',
array(
'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
)
);
}
Caso contrário, myField
sempre será definido como valor padrão, em vez de obter valor da entidade.
$options['data']->getMyField()
por$option['data']['myField']
empty_data
: Esta opção determina qual valor o campo retornará quando o valor enviado estiver vazio. Ele não define um valor inicial
Você pode definir o padrão para o campo relacionado em sua classe de modelo (na definição de mapeamento ou definir o valor você mesmo).
Além disso, o FormBuilder permite definir valores iniciais com o método setData () . O construtor de formulários é passado para o método createForm () da sua classe de formulário.
Além disso, verifique este link: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
Se seu formulário estiver vinculado a uma entidade, basta definir o valor padrão na própria entidade usando o método de construção:
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
). Use setData(...)
para estes.
Abordagem 1 (em http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/ )
Basta definir o valor padrão em sua entidade, na declaração da variável ou no construtor:
class Entity {
private $color = '#0000FF';
...
}
ou
class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
Abordagem 2 de um comentário no link acima, e também a resposta de Dmitriy (não a aceita) em Como definir o valor padrão para o campo de formulário no Symfony2?
Adicione o valor padrão ao atributo de dados ao adicionar o campo com o FormBuilder, adaptado da resposta de Dmitriy.
Observe que isso pressupõe que a propriedade terá e terá apenas o valor nulo quando for uma entidade nova e não existente.
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'
)
);
}
Você pode definir um valor padrão, por exemplo, para o formulário message
, assim:
$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->add('send', 'submit')
->getForm();
Caso seu formulário seja mapeado para uma Entidade, você pode seguir este exemplo (por exemplo, nome de usuário padrão):
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();
Uma solução geral para qualquer caso / abordagem, principalmente usando um formulário sem classe ou quando precisamos acessar qualquer serviço para definir o valor padrão:
// 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;
}
}
e registre a extensão do formulário:
app.form_type_extension:
class: App\Form\Extension\DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
Depois disso, podemos usar a default
opção em qualquer campo de formulário:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
Não use:
'data' => 'Default value'
Leia aqui: https://symfony.com/doc/current/reference/forms/types/form.html#data
"A opção de dados sempre substitui o valor obtido dos dados do domínio (objeto) durante a renderização. Isso significa que o valor do objeto também é substituído quando o formulário edita um objeto já persistente, fazendo com que perca seu valor persistente quando o formulário é enviado."
Use o seguinte:
Digamos que, neste exemplo, você tenha um Entity Foo e haja um campo "ativo" (neste exemplo é CheckBoxType, mas o processo é o mesmo para todos os outros tipos), que você deseja que seja verificado por padrão
Na sua classe FooFormType, adicione:
...
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()
vez de ler o campo pode torná-lo ainda melhor.
Só assim eu entendo o problema.
Você deseja ajustar a maneira como o formulário é criado com base nos dados da sua entidade. Se a entidade estiver sendo criada, use algum valor padrão. Se a entidade existir, use o valor do banco de dados.
Pessoalmente, acho que a solução da @ MolecularMans é o caminho a percorrer. Na verdade, eu definiria os valores padrão no construtor ou na declaração de propriedade. Mas você não parece gostar dessa abordagem.
Em vez disso, você pode seguir isto: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
Você pendura um ouvinte no seu tipo de formulário e, em seguida, pode examinar sua entidade e ajustar as instruções construtor-> add de acordo com a inclusão de uma entidade nova ou existente. Você ainda precisa especificar seus valores padrão em algum lugar, embora possa codificá-los no seu ouvinte. Ou passe-os para o tipo de formulário.
Parece muito trabalho embora. Melhor apenas passar a entidade para o formulário com os valores padrão já definidos.
Freqüentemente, para valores padrão init do formulário, eu uso equipamentos. De causa desta maneira não é mais fácil, mas muito confortável.
Exemplo:
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();
}
}
No entanto, o campo do tipo symfony tem os dados da opção .
Exemplo
$builder->add('token', 'hidden', array(
'data' => 'abcdef',
));
Existe uma maneira muito simples, você pode definir padrões como aqui:
$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);
$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
Se você definir 'dados' em seu formulário de criação, esse valor não será modificado ao editar sua entidade.
Minha solução é:
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',
));
}
Tchau.
'data' => $data['myfield'] ?? 'Default value',
Os valores padrão são definidos configurando a entidade correspondente. Antes de vincular a entidade ao formulário, defina seu campo de cores como "# 0000FF":
// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
Se esse campo estiver vinculado a uma entidade (é uma propriedade dessa entidade), você pode apenas definir um valor padrão para ela.
Um exemplo:
public function getMyField() {
if (is_null($this->MyField)) {
$this->setMyField('my default value');
}
return $this->MyField;
}
Normalmente, apenas defino o valor padrão para um campo específico na minha entidade:
/**
* @var int
* @ORM\Column(type="integer", nullable=true)
*/
protected $development_time = 0;
Isso funcionará para novos registros ou apenas para atualizar os existentes.
'empty_data'
um retorno de chamada é usado para permitir parâmetros de construtor na entidade.
Como Brian perguntou:
empty_data parece definir apenas o campo para 1 quando é enviado sem valor. E quando você deseja que o formulário seja padrão para exibir 1 na entrada quando nenhum valor estiver presente?
você pode definir o valor padrão com empty_value
$builder->add('myField', 'number', ['empty_value' => 'Default value'])