Comment définir la valeur par défaut pour le champ de formulaire dans Symfony2?

y a-t-il un moyen facile de définir une valeur par défaut pour le champ de forme de texte?

124
demandé sur Ondrej Slinták 2011-10-27 11:56:54

21 réponses

peut être utilisé facilement lors de la création avec:

->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => 'Default value'
))
105
répondu webda2l 2011-10-27 10:07:24

, vous pouvez définir la valeur par défaut avec empty_data

$builder->add('myField', 'number', ['empty_data' => 'Default value'])
107
répondu rkmax 2014-11-04 12:42:36

Je l'ai contemplé plusieurs fois dans le passé, alors j'ai pensé noter les différentes idées que j'ai eu / utilisé. Quelque chose pourrait être utile, mais aucun n'est "parfait" Symfony2 solutions.

constructeur Dans L'Entity vous pouvez faire $this - > setBar ('default value'); mais cela s'appelle à chaque fois que vous chargez l'entity (db ou pas) et est un peu désordonné. Cela fonctionne cependant pour chaque type de champ car vous pouvez créer des dates ou tout autre chose dont vous avez besoin.

Si les instructions à l'intérieur de d'obtenir Je ne le ferais pas, mais vous pourriez.

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

Usine / de l'instance . Appelez une fonction statique / classe secondaire qui vous fournit une entité par défaut pré-remplie avec des données. Par exemple:

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

   return $obj;
}

pas vraiment idéal étant donné que vous aurez à maintenir cette fonction si vous ajoutez des champs supplémentaires, mais il ne signifie que vous séparez les données setters / default et ce qui est généré à partir du db. De la même façon, vous pouvez avoir plusieurs getFactories si vous voulez différentes données par défaut.

entités élargies / de réflexion Créer une extension D'entité (par exemple FooCreate extends Foo) qui vous donne les données par défaut à create time (via le constructeur). Similaire à L'idée de L'usine / instance juste une approche différente - je préfère personnellement les méthodes statiques.

Ensemble de Données avant formulaire de construction Dans le constructeur / service, vous savez si vous avez une nouvelle entité ou si elle a été générée à partir de la base de données. Il est donc plausible d'appeler des données de jeu sur les différents champs lorsque vous attrapez une nouvelle entité. Par exemple:

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

Des Événements De Formulaire Lorsque vous créez le formulaire, vous définissez les données par défaut lors de la création des champs. Vous outrepassez ce PreSetData event listener. Le problème avec cela est que vous dupliquez la charge de travail du formulaire / dupliquer le code et le rendre plus difficile à maintenir / comprendre.

formes Étendues Semblable à des événements de forme, mais vous appelez le type différent selon si c'est un db / nouvelle entité. Par ceci je veux dire que vous avez FooType qui définit votre forme d'édition, BarType étend FooType ceci et définit toutes les données aux champs. Dans votre controller, vous choisissez simplement le type de formulaire à lancer. Cela craint si vous avez un thème personnalisé et comme des événements, crée trop d'entretien pour mon goût.

Brindille Vous pouvez créer votre propre thème et les données par défaut en utilisant l'option value aussi lorsque vous le faites sur une base par champ. Il n'y a rien qui vous empêche d'emballer ceci dans un thème de forme non plus si vous souhaitez garder vos gabarits propres et le formulaire réutilisable. par exemple

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

JS Il serait trivial de peupler la forme avec une fonction JS si les champs sont vide. Vous pouvez faire quelque chose avec des espaces réservés par exemple. C'est une mauvaise idée.

Formulaires en tant que service Pour l'un des grands projets basés sur les formulaires que j'ai fait, j'ai créé un service qui a généré tous les formulaires, fait tout le traitement, etc. Cela s'explique par le fait que les formulaires devaient être utilisés par plusieurs contrôleurs dans plusieurs environnements et que, bien que les formulaires aient été générés / manipulés de la même manière, ils étaient affichés / interagis avec différents (par exemple, gestion des erreurs, redirections, etc.). La beauté de cette approche était que vous pouvez les données par défaut, faire tout ce dont vous avez besoin, Gérer les erreurs de manière générique etc et il est tout encapsulé dans un endroit.

Conclusion Comme je le vois, vous rencontrerez le même problème encore et encore - où est les données par défaut de vivre?

  • si vous le stockez au niveau db / doctrine ce qui se passe si vous ne voulez pas stocker le défaut chaque de temps?
  • Si vous les conservez au niveau de l'Entité qu'advient-il si vous voulez ré-utiliser cette entité ailleurs sans données?
  • si vous le stockez au niveau de L'entité et ajoutez un nouveau champ, voulez-vous que les versions précédentes aient cette valeur par défaut lors de l'édition? Il en va de même pour la valeur par défaut dans la base de données...
  • si vous le stockez au niveau de la forme, est-ce évident quand vous venez de maintenir le code plus tard?
  • si c'est dans le constructeur de ce qui se passe si vous utilisez le formulaire à plusieurs endroits?
  • si vous le poussez au niveau JS alors vous êtes allé trop loin - les données ne devraient pas être dans la vue peu importe JS (et nous ignorons la compatibilité, les erreurs de rendu etc)
  • le service est grand si comme moi vous l'utilisez dans plusieurs endroits, mais c'est exagéré pour un simple add / edit form sur un site...

à cette fin, j'ai approché le problème différent à chaque fois. Par exemple, une option "newsletter" de formulaire d'inscription est facilement (et logiquement) définie dans le constructeur juste avant de créer le formulaire. Lorsque je construisais des collections de formulaires qui étaient liées entre elles (par exemple, quels boutons radio de différents types de formulaires étaient liés entre eux), alors j'ai utilisé des écouteurs D'événements. Quand j'ai construit une entité plus compliquée (par exemple, une qui nécessite des enfants ou beaucoup de données en défaut) j'ai utilisé une fonction (par exemple 'getFactory') pour créer l'élément it comme j'ai besoin il.

Je ne pense pas qu'il y ait une" bonne " approche car chaque fois que j'ai eu cette exigence, elle était légèrement différente.

bonne chance! J'espère que je vous ai donné un peu de nourriture pour la pensée à toute vitesse et n'a pas radoter trop ;)

57
répondu stefancarlton 2013-08-07 12:53:02

si vous devez définir la valeur par défaut et que votre formulaire se rapporte à l'entité, alors vous devez utiliser l'approche suivante:

// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
    ...
    ->add(
        'myField',
        'text',
        array(
            'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
        )
    );
}

Sinon, myField sera toujours définir la valeur par défaut, au lieu d'obtenir la valeur de l'entité.

40
répondu Dmitriy 2013-03-20 16:19:19

vous pouvez définir la valeur par défaut pour le champ correspondant dans votre classe de modèle (dans la définition de mappage ou définissez la valeur vous-même).

de plus, FormBuilder vous donne une chance de définir les valeurs initiales avec la méthode setData () . Form builder est passé à la méthode createForm () de votre classe de formulaire.

aussi, vérifier ce lien: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class

19
répondu Jakub Zalas 2011-10-27 08:11:41

si votre formulaire est lié à une entité, il suffit de définir la valeur par défaut sur l'entité elle-même en utilisant la méthode de construction:

public function __construct()
{
    $this->field = 'default value';
}
16
répondu Hubert Perron 2013-11-29 14:03:35

approche 1 (de http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms / )

définissez simplement la valeur par défaut dans votre entité, soit dans la déclaration variable, soit dans le constructeur:

class Entity {
    private $color = '#0000FF';
    ...
}

ou

class Entity {
    private $color;

    public function __construct(){
         $this->color = '#0000FF';
         ...
    }
    ...
}

approche 2 d'un commentaire dans le lien ci-dessus, et aussi la réponse de Dmitriy( pas accepté) de comment définir la valeur par défaut pour la forme champ en Symfony2?

ajoute la valeur par défaut à l'attribut data en ajoutant le champ avec le FormBuilder, adapté de la réponse de Dmitriy.

notez que cela suppose que le bien aura et aura seulement la valeur nulle quand il s'agit d'une nouvelle entité, et non d'une entité existante.

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'
        )
    );
}
11
répondu crysallus 2017-05-23 11:55:02

vous pouvez définir une valeur par défaut, par exemple pour le formulaire message , comme ceci:

$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
    ->add('name', 'text')
    ->add('email', 'email')
    ->add('message', 'textarea')
    ->add('send', 'submit')
    ->getForm();

dans le cas où votre forme est mappée à une entité, vous pouvez aller comme ceci (par exemple Nom d'utilisateur par défaut):

$user = new User();
$user->setUsername('John Doe');

$form = $this->createFormBuilder($user)
    ->add('username')
    ->getForm();
9
répondu Gottlieb Notschnabel 2013-09-06 14:51:10

une solution générale pour tout cas / approche, principalement en utilisant un formulaire sans classe ou lorsque nous avons besoin d'accéder à n'importe quel service pour définir la valeur par défaut:

// 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;
    }
}

et enregistrer l'extension du formulaire:

app.form_type_extension:
    class: App\Form\Extension\DefaultFormTypeExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

après cela, nous pouvons utiliser default option dans n'importe quel champ de forme:

$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
9
répondu yceruto 2018-03-28 11:03:08
->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));
     }

});
6
répondu ziiweb 2016-04-18 16:05:36

juste pour que je comprenne le problème.

Vous voulez ajuster la façon dont le formulaire est construit sur la base de données dans votre entité. Si l'entité est créée, utilisez une valeur par défaut. Si l'entité existe, utilisez la valeur de la base de données.

personnellement, je pense que la solution de @MolecularMans est la voie à suivre. Je définirais en fait les valeurs par défaut dans le constructeur ou dans la déclaration de propriété. Mais vous ne semblez pas aimer cette approche.

à la place vous pouvez suivre ceci: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

vous accrochez un auditeur sur votre type de formulaire et vous pouvez ensuite examiner votre entité et ajuster le constructeur->ajouter des déclarations en conséquence en fonction de havine une entité nouvelle ou existante. Vous avez toujours besoin de spécifier vos valeurs par défaut quelque part, mais vous pouvez simplement les coder dans votre écouteur. Ou les passer dans le type de forme.

semble être beaucoup de travail cependant. Mieux de passer à l'entité de la forme avec ses valeurs par défaut déjà.

4
répondu Cerad 2013-08-01 15:27:47

si vous utilisez un FormBuilder dans symfony 2.7 pour générer le formulaire, vous pouvez également passer les données initiales à la méthode createFormBuilder du contrôleur

$values = array(
    'name' => "Bob"
);

$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
4
répondu Bob 2015-07-01 07:42:00

N'utilisez pas:

'data' => 'Default value'

lire ici: https://symfony.com/doc/current/reference/forms/types/form.html#data

" l'option data l'emporte toujours sur la valeur prise à partir des données du domaine (objet) lors du rendu. Cela signifie que la valeur de l'objet est également supérieure lorsque la forme modifie un objet déjà persisté, ce qui lui fait perdre sa valeur persist lorsque la forme est soumise."


utilisez la formule suivante:

permet de dire, pour cet exemple, que vous avez une entité Foo, et il y a un champ "active" (dans cet exemple est CheckBoxType, mais le processus est le même pour tous les autres types), que vous voulez vérifier par défaut

dans votre classe de FooFormType ajouter:

...
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',
    ));
}
4
répondu cure85 2018-03-27 13:51:16

ma solution:

$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
            'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
        )) ;
3
répondu trocolo 2013-12-14 20:10:02

souvent, pour les valeurs init par défaut de la forme j'utilise des fixtures. Ce n'est pas facile, mais c'est très confortable.

exemple:

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

pourtant, champ Type symfony ont l'option données .

exemple

$builder->add('token', 'hidden', array(
    'data' => 'abcdef',
));
3
répondu Mikhail Schedrakov 2014-03-14 10:53:21

il y a une façon très simple, vous pouvez définir par défaut comme ici:

$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);

$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
3
répondu Alsatian 2014-07-07 15:46:39

si vous définissez "données" dans votre formulaire de création, cette valeur ne sera pas modifiée lors de l'édition de votre entité.

ma solution est:

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

Bye.

2
répondu Quentin Machard 2017-07-07 08:17:07

les valeurs par défaut sont définies en configurant l'entité correspondante. Avant de lier l'entité à former, définissez son champ de couleur à "#0000FF":

// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
1
répondu Molecular Man 2013-08-01 06:37:45

Si ce champ est lié à une entité (c'est une propriété de l'entité), vous pouvez simplement définir une valeur par défaut.

un exemple:

public function getMyField() {
    if (is_null($this->MyField)) {
        $this->setMyField('my default value');
    }
    return $this->MyField;
}
1
répondu Andrei Sandulescu 2014-03-11 10:19:41

habituellement, je viens de définir la valeur par défaut pour un champ spécifique dans mon entité:

/**
 * @var int
 * @ORM\Column(type="integer", nullable=true)
 */
protected $development_time = 0;

cela fonctionnera pour les nouveaux enregistrements ou si seulement la mise à jour des enregistrements existants.

1
répondu matotej 2014-10-08 13:07:46

comme Brian a demandé:

empty_data semble que définir le champ à 1 lorsqu'il est soumis à aucune valeur. Qu'en est-il lorsque vous voulez que la forme par défaut à l'affichage 1 dans le d'entrée si aucune valeur n'est présente?

, vous pouvez définir la valeur par défaut avec empty_value

$builder->add('myField', 'number', ['empty_value' => 'Default value'])
1
répondu Snowirbis 2017-05-11 15:18:30