php - symfony2 - symfony choice type
¿Cómo establecer el valor predeterminado para el campo de formulario en Symfony2? (21)
A menudo, para los valores predeterminados de inicio de la forma yo uso aparatos. Por esta razón no es la más fácil, pero sí muy cómoda.
Ejemplo:
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();
}
}
Sin embargo, el campo de tipo Symfony tiene los data opción.
Ejemplo
$builder->add(''token'', ''hidden'', array(
''data'' => ''abcdef'',
));
¿Hay una manera fácil de establecer un valor predeterminado para el campo de formulario de texto?
Como Brian preguntó:
empty_data parece que solo establece el campo en 1 cuando se envía sin valor. ¿Qué sucede cuando desea que el formulario muestre 1 en la entrada cuando no hay ningún valor presente?
puede establecer el valor predeterminado con el valor de empty_value
$builder->add(''myField'', ''number'', [''empty_value'' => ''Default value''])
Enfoque 1 (de http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/ )
Simplemente establezca el valor predeterminado en su entidad, ya sea en la declaración de variables o en el constructor:
class Entity {
private $color = ''#0000FF'';
...
}
o
class Entity {
private $color;
public function __construct(){
$this->color = ''#0000FF'';
...
}
...
}
Enfoque 2 de un comentario en el enlace anterior, y también la respuesta de Dmitriy (no la aceptada) de ¿Cómo establecer el valor predeterminado para el campo de formulario en Symfony2?
Agregue el valor predeterminado al atributo de datos cuando agregue el campo con FormBuilder, adaptado de la respuesta de Dmitriy.
Tenga en cuenta que esto supone que la propiedad tendrá y solo tendrá el valor nulo cuando sea una entidad nueva, y no una 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''
)
);
}
Hay una forma muy simple, puede establecer los valores predeterminados como aquí:
$defaults = array(''sortby'' => $sortby,''category'' => $category,''page'' => 1);
$form = $this->formfactory->createBuilder(''form'', $defaults)
->add(''sortby'',''choice'')
->add(''category'',''choice'')
->add(''page'',''hidden'')
->getForm();
He contemplado esto varias veces en el pasado, así que pensé en anotar las diferentes ideas que he tenido / usado. Algo podría ser útil, pero ninguno son soluciones "perfectas" de Symfony2.
Constructor En la Entidad puede hacer $ this-> setBar (''valor predeterminado''); pero esto se llama cada vez que carga la entidad (db o no) y es un poco desordenado. Sin embargo, funciona para cada tipo de campo, ya que puede crear fechas o cualquier otra cosa que necesite.
Si las declaraciones dentro de get no lo harían, pero podrías.
return ( ! $this->hasFoo() ) ? ''default'' : $this->foo;
Fábrica / instancia . Llame a una función / clase secundaria estática que le proporciona una entidad predeterminada rellenada previamente con datos. P.ej
function getFactory() {
$obj = new static();
$obj->setBar(''foo'');
$obj->setFoo(''bar'');
return $obj;
}
No es realmente ideal dado que tendrá que mantener esta función si agrega campos adicionales, pero significa que está separando los definidores de datos / predeterminados y lo que se genera a partir de la db. Del mismo modo, puede tener múltiples getFactories si desea diferentes datos predeterminados.
Entidades extendidas / Reflexión Cree una Entidad extendida (por ejemplo, FooCreate extiende Foo) que le brinda los datos predeterminados en el momento de la creación (a través del constructor). Similar a la idea Fábrica / instancia, solo un enfoque diferente: prefiero los métodos estáticos personalmente.
Establecer datos antes del formulario de compilación En los constructores / servicio, usted sabe si tiene una nueva entidad o si se completó desde la base de datos. Es plausible, por lo tanto, llamar a los datos establecidos en los diferentes campos cuando toma una nueva entidad. P.ej
if( ! $entity->isFromDB() ) {
$entity->setBar(''default'');
$entity->setDate( date(''Y-m-d'');
...
}
$form = $this->createForm(...)
Eventos de formulario Al crear el formulario, se configuran los datos predeterminados al crear los campos. Usted anula este uso del detector de eventos PreSetData. El problema con esto es que está duplicando la carga de trabajo del formulario / duplicando el código y haciendo que sea más difícil de mantener / entender.
Formas extendidas similares a los eventos de formulario, pero usted llama al tipo diferente dependiendo de si es una entidad nueva / db. Con esto quiero decir que tiene FooType que define su forma de edición, BarType extiende FooType esto y establece todos los datos en los campos. En su controlador, usted simplemente elige qué tipo de formulario instigar. Esto apesta si tienes un tema personalizado y, aunque te gustan los eventos, crea demasiado mantenimiento para mi gusto.
Twig Puede crear su propio tema y predeterminar los datos usando la opción de valor también cuando lo hace por campo. No hay nada que le impida incluir esto en un tema de formulario si desea mantener sus plantillas limpias y el formulario reutilizable. p.ej
form_widget(form.foo, {attr: { value : default } });
JS Sería trivial rellenar el formulario con una función JS si los campos están vacíos. Podrías hacer algo con los marcadores de posición, por ejemplo. Esta es una mala idea, sin embargo.
Formularios como servicio Para uno de los grandes proyectos basados en formularios que realicé, creé un servicio que generaba todos los formularios, realizaba todo el procesamiento, etc. Esto se debía a que los formularios se iban a usar en múltiples controladores en múltiples entornos y mientras que los formularios se generaron / manejaron de la misma manera, se mostraron / interactuaron de manera diferente (por ejemplo, manejo de errores, redirecciones, etc.). La belleza de este enfoque es que puede predeterminar los datos, hacer todo lo que necesita, manejar los errores de forma genérica, etc. y todo está encapsulado en un solo lugar.
Conclusión Como lo veo, se encontrará con el mismo problema una y otra vez: ¿dónde están los datos predeterminados para vivir?
- Si lo almacena a nivel de db / doctrina, ¿qué sucede si no desea almacenar el valor predeterminado cada vez?
- Si lo almacena a nivel de Entidad, ¿qué sucede si desea reutilizar esa entidad en otro lugar sin ningún tipo de información?
- Si lo almacena a nivel de entidad y agrega un nuevo campo, ¿desea que las versiones anteriores tengan ese valor predeterminado al editar? Lo mismo ocurre con el valor predeterminado en la base de datos ...
- Si lo almacena en el nivel de formulario, ¿es obvio que cuando vuelva a actualizar el código?
- Si está en el constructor, ¿qué sucede si usa el formulario en varios lugares?
- Si lo empuja al nivel JS, entonces ha ido demasiado lejos: los datos no deberían estar a la vista. No importa, JS (y estamos ignorando la compatibilidad, los errores de representación, etc.)
- El servicio es excelente si, como yo, lo está utilizando en varios lugares, pero es excesivo para un simple formulario de agregar / editar en un sitio ...
Con ese fin, he abordado el problema de manera diferente cada vez. Por ejemplo, una opción de "boletín" del formulario de registro se configura fácilmente (y lógicamente) en el constructor justo antes de crear el formulario. Cuando estaba creando colecciones de formularios que estaban vinculados entre sí (por ejemplo, qué botones de opción en diferentes tipos de formularios vinculados entre sí), he utilizado Event Listeners. Cuando he creado una entidad más complicada (por ejemplo, una que requería hijos o muchos datos predeterminados), he usado una función (por ejemplo, ''getFactory'') para crear el elemento que necesito.
No creo que haya un enfoque "correcto" ya que cada vez que he tenido este requisito ha sido ligeramente diferente.
¡Buena suerte! Espero que, de todos modos, te haya dado algo de qué pensar y no haya divagado demasiado;)
Los valores predeterminados se establecen mediante la configuración de la entidad correspondiente. Antes de vincular la entidad para formar, establezca su campo de color en "# 0000FF":
// controller action
$project = new Project();
$project->setColor(''#0000FF'');
$form = $this->createForm(new ProjectType(), $project);
Mi solución:
$defaultvalue = $options[''data'']->getMyField();
$builder->add(''myField'', ''number'', array(
''data'' => !empty($defaultvalue) ? $options[''data'']->getMyField() : 0
)) ;
Por lo general, solo establezco el valor predeterminado para un campo específico en mi entidad:
/**
* @var int
* @ORM/Column(type="integer", nullable=true)
*/
protected $development_time = 0;
Esto funcionará para nuevos registros o solo para actualizar los existentes.
Puede establecer el valor predeterminado para el campo relacionado en su clase de modelo (en la definición de asignación o establecer el valor usted mismo).
Además, FormBuilder le da la oportunidad de establecer valores iniciales con el método setData() . El generador de formularios se pasa al método createForm() de su clase de formulario.
Además, consulte este enlace: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
Puede establecer un valor predeterminado, por ejemplo, para el message
formulario, como este:
$defaultData = array(''message'' => ''Type your message here'');
$form = $this->createFormBuilder($defaultData)
->add(''name'', ''text'')
->add(''email'', ''email'')
->add(''message'', ''textarea'')
->add(''send'', ''submit'')
->getForm();
En caso de que su formulario esté asignado a una Entidad, puede hacerlo de esta manera (por ejemplo, nombre de usuario predeterminado):
$user = new User();
$user->setUsername(''John Doe'');
$form = $this->createFormBuilder($user)
->add(''username'')
->getForm();
Se puede usar fácilmente durante la creación con:
->add(''myfield'', ''text'', array(
''label'' => ''Field'',
''data'' => ''Default value''
))
Si ese campo está vinculado a una entidad (es una propiedad de esa entidad), simplemente puede establecer un valor predeterminado para ella.
Un ejemplo:
public function getMyField() {
if (is_null($this->MyField)) {
$this->setMyField(''my default value'');
}
return $this->MyField;
}
Si estás usando un FormBuilder
en Symfony 2.7 para generar el formulario, también puedes pasar los datos iniciales al método createFormBuilder
del Controler.
$values = array(
''name'' => "Bob"
);
$formBuilder = $this->createFormBuilder($values);
$formBuilder->add(''name'', ''text'');
Si establece ''datos'' en su formulario de creación, este valor no se modificará cuando edite su entidad.
Mi solución es:
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'',
));
}
Adiós.
Si necesita establecer un valor predeterminado y su formulario se relaciona con la entidad, entonces debe usar el siguiente enfoque:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
''myField'',
''text'',
array(
''data'' => isset($options[''data'']) ? $options[''data'']->getMyField() : ''my default value''
)
);
}
De lo contrario, myField
siempre se establecerá en el valor predeterminado, en lugar de obtener el valor de la entidad.
Si su formulario está vinculado a una entidad, simplemente establezca el valor predeterminado en la propia entidad utilizando el método de construcción:
public function __construct()
{
$this->field = ''default value'';
}
Solo así entiendo el problema.
Desea ajustar la forma en que se construye el formulario en función de los datos de su entidad. Si la entidad se está creando, use un valor predeterminado. Si la entidad existe, use el valor de la base de datos.
Personalmente, creo que la solución de @MolecularMans es el camino a seguir. Realmente establecería los valores predeterminados en el constructor o en la declaración de propiedad. Pero parece que no te gusta ese enfoque.
En su lugar, puede seguir esto: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
Cuelga un oyente en su tipo de formulario y luego puede examinar su entidad y ajustar el constructor -> agregar declaraciones en función de haber creado una entidad nueva o existente. Aún debe especificar sus valores predeterminados en algún lugar, aunque podría codificarlos en su escucha. O pasarlos en el tipo de formulario.
Aunque parece mucho trabajo. Es mejor pasar la entidad al formulario con sus valores predeterminados ya establecidos.
Una solución general para cualquier caso / enfoque, principalmente mediante el uso de un formulario sin clase o cuando necesitamos acceso a cualquier servicio para establecer el valor predeterminado:
// 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;
}
}
y registra la extensión del formulario:
app.form_type_extension:
class: App/Form/Extension/DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony/Component/Form/Extension/Core/Type/FormType }
Después de eso, podemos usar la opción default
en cualquier campo de formulario:
$formBuilder->add(''user'', null, array(''default'' => $this->getUser()));
$formBuilder->add(''foo'', null, array(''default'' => ''bar''));
puede establecer el valor predeterminado con empty_data
$builder->add(''myField'', ''number'', [''empty_data'' => ''Default value''])
No use
''data'' => ''Default value''
Lea aquí: https://symfony.com/doc/current/reference/forms/types/form.html#data
"La opción de datos siempre anula el valor tomado de los datos del dominio (objeto) cuando se procesa. Esto significa que el valor del objeto también se anula cuando el formulario edita un objeto ya persistido, lo que hace que pierda su valor persistente cuando se envía el formulario".
Usa lo siguiente:
Digamos que, para este ejemplo, usted tiene una Entidad Foo, y hay un campo "activo" (en este ejemplo es CheckBoxType, pero el proceso es el mismo que para cualquier otro tipo), que desea que se verifique por defecto
En su clase FooFormType agregue:
...
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'',
));
}
->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));
}
});