sim, mas as respostas dadas nesta questão não está satisfazendo / não funcionam ... I irá adicionar um "Edit" para explicar porque :-)
herrjeh42
Parece que a solução 'perfeita' que você procura é que um campo tenha a opção 'default_value'. A coisa é que, atualmente, não existe , então não acho que exista a solução perfeita que você está procurando. A única coisa que o symfony fornece (veja o link) é a opção de dados. Portanto, o if-then é a única abordagem que eu posso ver no caixa eletrônico. Mesmo se houvesse uma opção 'default_value' no próprio campo, imagino que essencialmente faria a mesma coisa internamente de qualquer maneira.
Crysallus
Além disso, corrigi minha resposta na abordagem 2, conforme meus comentários abaixo. Se isso resolver o problema de sintaxe mencionado no ponto 2, convém editar esse comentário. Ou deixe-me saber qual é o problema e corrigirei minha resposta.
Para o Symfony 2.1, eu precisei mudar a 'data'chave para'value'
Edd
175
Isso não apenas define um valor padrão, mas também sempre força o valor em qualquer contexto. Não o que eu chamaria de um "valor padrão" ...
Hubert Perron
4
Eu diminuí a votação desta solução, pois ela não é uma solução para o problema (como Hubert Perron mencionado acima). Eu estou tentando obter uma melhor solução neste post stackoverflow.com/questions/17986481/...
herrjeh42
13
Este é o valor inicial, o valor padrão éempty_data
Pierre de LESPINAY
3
dataé inútil - substitui o valor salvo. empty_datanão mostra o valor, ele é usado no envio de valor vazio e torna impossível salvar opções desmarcadas.
Definir dados não está definindo o padrão. Esta resposta é a correta.
Alexei Tenitski
9
Isso 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?
27714 Brian
Nos meus testes, empty_data não me permite substituir o valor padrão de um campo enviado vazio, por exemplo, se você deseja salvar no banco de dados como 0 em vez de NULL. Este bug está ainda em aberto, tanto quanto eu posso dizer: github.com/symfony/symfony/issues/5906
Chadwick Meyer
63
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 =newstatic();
$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
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?
Se você armazená-lo no nível db / doutrina, o que acontece se você não quiser armazenar o padrão todas as vezes?
Se você armazená-lo no nível da entidade, o que acontece se você quiser reutilizar essa entidade em outro lugar sem nenhum dado nela?
Se você armazená-lo no nível de entidade e adicionar um novo campo, deseja que as versões anteriores tenham esse valor padrão na edição? O mesmo vale para o padrão no banco de dados ...
Se você o armazena no nível do formulário, é óbvio quando você mantém o código posteriormente?
Se estiver no construtor, o que acontece se você usar o formulário em vários locais?
Se você empurrá-lo para o nível JS, você foi longe demais - os dados não devem estar na visão, não importa o JS (e estamos ignorando a compatibilidade, erros de renderização etc.)
O serviço é ótimo se, como eu, você o está usando em vários lugares, mas é um exagero para um simples formulário de adição / edição em um site ...
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;)
você poderia dar um pouco mais de detalhes sobre o que você quis dizer sobre 'um serviço que gerou todos os formulários'? Também estou trabalhando em um projeto realmente centrado em formulários agora e seria ótimo ter perspectivas diferentes sobre ele.
user2268997
2
ao usar a doutrina, os construtores não são chamados quando uma entidade é carregada do banco de dados.
NDM
43
Se você precisar definir o valor padrão e seu formulário estiver relacionado à entidade, use a seguinte abordagem:
No caso de matrizes em vez de entidades, substitua-as $options['data']->getMyField()por$option['data']['myField']
ggg 29/11
3
Esse é o caminho certo para adicionar / atualizar, eu acho. Mas eu odeio Symfony torná-lo muito complexo.
Yarco
Esta é a única boa resposta. Não entendo outras respostas quando olho para o documento. empty_data: Esta opção determina qual valor o campo retornará quando o valor enviado estiver vazio. Ele não define um valor inicial
Vincent Decaux 19/06
19
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.
O primeiro funciona (obrigado!), O segundo não funciona (para mim): $ options ["data] é sempre definido, portanto o valor padrão nunca será usado. Ainda estou me perguntando se a solução número 1 é a maneira pretendida Para fazer isso ...
herrjeh42
Você está certo sobre $ options ['data'] sempre sendo definido. Se você não inicializar o campo da entidade, poderá testar nulo no campo, por exemplo. 'data' => $ options ['data'] -> getColor ()! == null? etc ... Isso pressupõe que nulo não é um valor válido para o campo de cores; portanto, as entidades existentes nunca teriam um valor nulo para esse campo.
Crysallus
ah, estúpido: tentei com 'isset ($ $ options [' data '] -> getColor ())', recebi uma mensagem de erro sobre "não é permitido usá-lo em contextos de escrita" e esqueci que tenho que verificá-lo de forma diferente :-)
herrjeh42
1
Na verdade, parece haver ocasiões em que a entrada de dados não está definida. Mais seguro para testar, por exemplo, isset ($ options ['data']) && $ options ['data'] -> getColor ()! == null? ...
crysallus
9
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):
Eu prefiro esse método, especialmente porque na maioria dos aplicativos você está criando um formulário e passando em uma entidade com a qual o formulário lida.
skrilled
9
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:
"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:
...useSymfony\Component\Form\FormEvent;useSymfony\Component\Form\FormEvents;...publicfunction 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);});}publicfunction configureOptions(OptionsResolver $resolver ){
$resolver->setDefaults(array('data_class'=>'AppBundle:Foo',));}
Isso aqui é dinheiro !! Use o ouvinte de eventos do formulário para verificar seus valores antes de padronizá-los. Essa deve ser a resposta aceita para os valores padrão nos seus formulários, pois funciona para as ações Novas e Editar.
Tlens
Esta é a maneira correta de lidar com isso e essa deve ser a resposta aceita.
Bettinz
O que você mencionou no início não é verdade se você usar um condicional / ternário. Assim:'data' => $data['myfield'] ?? 'Default value'
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.
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.
Se você estiver usando um FormBuilderno symfony 2.7 para gerar o formulário, também poderá passar os dados iniciais para o createFormBuildermétodo do Controler
Se você definir 'dados' em seu formulário de criação, esse valor não será modificado ao editar sua entidade.
Minha solução é:
publicfunction 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',));}
Muito mais útil do que uma resposta aceita! Se você usa o PHP7 +, você pode torná-lo ainda mais 'data' => $data['myfield'] ?? 'Default value',
limpo
Você tem um erro de digitação na função array_key_exists () #
Deadpool
1
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":
Essa abordagem funciona, mas tem a desvantagem de que você precisa fazer isso toda vez que usa a classe de formulário e é muito detalhada (muitas instruções definidas). Como o componente do formulário é muito elegante, deve haver algo mais. Mas obrigado de qualquer maneira :-)
herrjeh42
@ jamie0726 Na minha opinião, é responsabilidade do controlador definir os valores do objeto sempre que novo ou buscado. Dessa forma, é possível usar o formulário em diferentes situações com comportamentos diferentes, por exemplo, a nova cor pode mudar devido ao usuário ter uma função de gerente ou super-gerente e, como essa é uma lógica de negócios, deve ser controlada pelo controlador ou um serviço, não o formulário. Então, como Cerad afirmou, eu também prefiro esta solução. Você sempre pode criar um serviço para definir esses valores padrão e, no controlador, usar esse serviço, mantendo-o SECO.
saamorim
Essa é a solução que eu escolhi, porque se encaixa na lógica que penso. Os controladores gerados têm métodos diferentes para criar formulários EDIT e CREATE, e é aí que eu defino os dados padrão / iniciais para a nova entidade.
Alumi
1
Se esse campo estiver vinculado a uma entidade (é uma propriedade dessa entidade), você pode apenas definir um valor padrão para ela.
Isso não parece funcionar quando 'empty_data'um retorno de chamada é usado para permitir parâmetros de construtor na entidade.
NDM
1
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?
Respostas:
Pode ser usado durante a criação facilmente com:
fonte
'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
fonte
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.
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
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
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
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;)
fonte
Se você precisar definir o valor padrão e seu formulário estiver relacionado à entidade, use a seguinte abordagem:
Caso contrário,
myField
sempre será definido como valor padrão, em vez de obter valor da entidade.fonte
$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 inicialVocê 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
fonte
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:
fonte
'mapped' => false
). UsesetData(...)
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:
ou
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.
fonte
Você pode definir um valor padrão, por exemplo, para o formulário
message
, assim:Caso seu formulário seja mapeado para uma Entidade, você pode seguir este exemplo (por exemplo, nome de usuário padrão):
fonte
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:
e registre a extensão do formulário:
Depois disso, podemos usar a
default
opção em qualquer campo de formulário:fonte
Não use:
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:
fonte
'data' => $data['myfield'] ?? 'Default value'
fonte
$event->setData()
vez de ler o campo pode torná-lo ainda melhor.Minha solução:
fonte
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.
fonte
Se você estiver usando um
FormBuilder
no symfony 2.7 para gerar o formulário, também poderá passar os dados iniciais para ocreateFormBuilder
método do Controlerfonte
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:
No entanto, o campo do tipo symfony tem os dados da opção .
Exemplo
fonte
Existe uma maneira muito simples, você pode definir padrões como aqui:
fonte
Se você definir 'dados' em seu formulário de criação, esse valor não será modificado ao editar sua entidade.
Minha solução é:
Tchau.
fonte
'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":
fonte
Se esse campo estiver vinculado a uma entidade (é uma propriedade dessa entidade), você pode apenas definir um valor padrão para ela.
Um exemplo:
fonte
Normalmente, apenas defino o valor padrão para um campo específico na minha entidade:
Isso funcionará para novos registros ou apenas para atualizar os existentes.
fonte
'empty_data'
um retorno de chamada é usado para permitir parâmetros de construtor na entidade.Como Brian perguntou:
você pode definir o valor padrão com
empty_value
fonte
Resolvi esse problema, adicionando valor no attr :
fonte