Existe-t-il un moyen simple de définir une valeur par défaut pour le champ de formulaire de texte?
Existe-t-il un moyen simple de définir une valeur par défaut pour le champ de formulaire de texte?
Réponses:
Peut être utilisé lors de la création facilement avec:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
clé en'value'
empty_data
data
est inutile - il écrase la valeur enregistrée. empty_data
n'affiche pas la valeur, il l'utilise lors de la soumission d'une valeur vide et rend impossible l'enregistrement des choix non cochés.
vous pouvez définir la valeur par défaut avec empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
J'ai envisagé cela à quelques reprises dans le passé, alors j'ai pensé noter les différentes idées que j'avais / utilisées. Quelque chose pourrait être utile, mais aucune n'est une solution Symfony2 "parfaite".
Constructeur Dans l'entité, vous pouvez faire $ this-> setBar ('valeur par défaut'); mais cela est appelé chaque fois que vous chargez l'entité (db ou non) et est un peu compliqué. Cela fonctionne cependant pour chaque type de champ car vous pouvez créer des dates ou tout ce dont vous avez besoin.
Si les déclarations dans get, je ne le ferais pas, mais vous pourriez.
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Usine / instance . Appelez une fonction statique / une 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 devrez maintenir cette fonction si vous ajoutez des champs supplémentaires, mais cela signifie que vous séparez les paramètres de données / par défaut et ce qui est généré à partir de la base de données. De même, vous pouvez avoir plusieurs getFactories si vous souhaitez des données par défaut différentes.
Entités étendues / de réflexion Créez une entité étendue (par exemple, FooCreate étend Foo) qui vous donne les données par défaut au moment de la création (via le constructeur). Similaire à l'idée Factory / instance, une approche différente - je préfère personnellement les méthodes statiques.
Définir les données avant le formulaire de génération Dans les constructeurs / service, vous savez si vous avez une nouvelle entité ou si elle a été remplie à partir de la base de données. Il est donc plausible d'appeler des données d'ensemble sur les différents champs lorsque vous saisissez une nouvelle entité. Par exemple
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
É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 remplacez cet écouteur d'événement Use PreSetData. Le problème avec cela est que vous dupliquez la charge de travail du formulaire / dupliquez le code et que vous le rendez plus difficile à maintenir / comprendre.
Formulaires étendus Semblable aux événements Form, mais vous appelez le type différent selon qu'il s'agit d'une entité db / new. Je veux dire par là que vous avez FooType qui définit votre formulaire d'édition, BarType étend FooType et définit toutes les données dans les champs. Dans votre contrôleur, vous choisissez alors simplement le type de formulaire à lancer. Cela craint si vous avez un thème personnalisé et que vous aimez les événements, cela crée trop de maintenance à mon goût.
Twig Vous pouvez créer votre propre thème et les données par défaut en utilisant également l'option de valeur lorsque vous le faites sur une base par champ. Rien ne vous empêche de l'envelopper dans un thème de formulaire si vous souhaitez garder vos modèles propres et le formulaire réutilisable. par exemple
form_widget(form.foo, {attr: { value : default } });
JS Ce serait trivial de remplir le formulaire avec une fonction JS si les champs sont vides. Vous pouvez faire quelque chose avec des espaces réservés par exemple. C'est une mauvaise, une mauvaise idée cependant.
Formulaires en tant que service Pour l'un des grands projets basés sur les formulaires que j'ai réalisés, j'ai créé un service qui générait tous les formulaires, effectuait tout le traitement, etc. C'était parce que les formulaires devaient être utilisés sur plusieurs contrôleurs dans plusieurs environnements et pendant que les formulaires ont été générés / traités de la même manière, ils ont été affichés / interagis différemment (par exemple, gestion des erreurs, redirections, etc.). La beauté de cette approche était que vous pouvez par défaut les données, faire tout ce dont vous avez besoin, gérer les erreurs de manière générique, etc. et tout est encapsulé au même endroit.
Conclusion Comme je le vois, vous rencontrerez le même problème à maintes reprises - où sont les données par défaut à vivre?
À cette fin, j'ai abordé le problème différemment à chaque fois. Par exemple, une option de formulaire d'inscription "newsletter" 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 dans différents types de formulaires étaient liés ensemble), j'ai utilisé des écouteurs d'événements. Lorsque j'ai construit une entité plus compliquée (par exemple, une entité qui nécessitait des enfants ou beaucoup de données par défaut), j'ai utilisé une fonction (par exemple, «getFactory») pour créer l'élément selon mes besoins.
Je ne pense pas qu'il y ait une «bonne» approche, car chaque fois que j'ai eu cette exigence, elle a été légèrement différente.
Bonne chance! J'espère que je vous ai donné matière à réflexion en tout cas et que je n'ai pas trop bavardé;)
Si vous devez définir la valeur par défaut et que votre formulaire se rapporte à l'entité, 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
always sera défini sur la valeur par défaut, au lieu d'obtenir la valeur de l'entité.
$options['data']->getMyField()
par$option['data']['myField']
empty_data
: Cette option détermine la valeur renvoyée par le champ lorsque la valeur soumise est vide. Il ne fixe pas de valeur initiale
Vous pouvez définir la valeur par défaut du champ associé dans votre classe de modèle (dans la définition de mappage ou définir la valeur vous-même).
De plus, FormBuilder vous donne la possibilité de définir des valeurs initiales avec la méthode setData () . Le générateur de formulaire est passé à la méthode createForm () de votre classe de formulaire.
Consultez également ce lien: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
Si votre formulaire est lié à une entité, définissez simplement la valeur par défaut sur l'entité elle-même à l'aide de la méthode construct:
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
). Utilisez setData(...)
pour cela.
Approche 1 (à partir 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 de variable, soit dans le constructeur:
class Entity {
private $color = '#0000FF';
...
}
ou
class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
Approche 2 à partir d'un commentaire dans le lien ci-dessus, ainsi que la réponse de Dmitriy (pas celle acceptée) de Comment définir la valeur par défaut du champ de formulaire dans Symfony2?
Ajoutez la valeur par défaut à l'attribut data lors de l'ajout du champ avec FormBuilder, adapté de la réponse de Dmitriy.
Notez que cela suppose que la propriété aura et n'aura la valeur null que s'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'
)
);
}
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 formulaire est mappé à une entité, vous pouvez procéder comme suit (par exemple, nom d'utilisateur par défaut):
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();
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 enregistrez l'extension de 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 l' default
option dans n'importe quel champ de formulaire:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
N'utilisez pas:
'data' => 'Default value'
Lisez ici: https://symfony.com/doc/current/reference/forms/types/form.html#data
"L'option data remplace toujours la valeur extraite des données de domaine (objet) lors du rendu. Cela signifie que la valeur de l'objet est également remplacée lorsque le formulaire modifie un objet déjà persistant, ce qui lui fait perdre sa valeur persistante lorsque le formulaire est soumis."
Utilisez le suivant:
Disons que, pour cet exemple, vous avez une entité Foo, et il y a un champ "actif" (dans cet exemple, CheckBoxType, mais le processus est le même pour tous les autres types), que vous voulez vérifier par défaut
Dans votre classe FooFormType, ajoutez:
...
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()
au lieu de lire le champ pourrait le rendre encore meilleur.
Juste pour que je comprenne le problème.
Vous souhaitez ajuster la façon dont le formulaire est construit en fonction des données de votre entité. Si l'entité est en cours de création, 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.
Au lieu de cela, vous pouvez suivre ceci: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
Vous accrochez un écouteur sur votre type de formulaire et vous pouvez ensuite examiner votre entité et ajuster le générateur-> ajouter des instructions en conséquence en fonction de la présence d'une entité nouvelle ou existante. Vous devez toujours spécifier vos valeurs par défaut quelque part bien que vous puissiez simplement les coder dans votre écouteur. Ou passez-les dans le type de formulaire.
Cela semble cependant beaucoup de travail. Mieux vaut simplement passer l'entité au formulaire avec ses valeurs par défaut déjà définies.
Si vous utilisez un FormBuilder
dans symfony 2.7 pour générer le formulaire, vous pouvez également passer les données initiales à la createFormBuilder
méthode du contrôleur
$values = array(
'name' => "Bob"
);
$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
Souvent, pour les valeurs par défaut de la forme, j'utilise des appareils. Bien sûr, cette manière n'est pas la plus simple, mais 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, le champ de type symfony a les données d' option .
Exemple
$builder->add('token', 'hidden', array(
'data' => 'abcdef',
));
Il existe un moyen très simple, vous pouvez définir les valeurs 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();
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',
));
}
Au revoir.
'data' => $data['myfield'] ?? 'Default value',
Les valeurs par défaut sont définies en configurant l'entité correspondante. Avant de lier l'entité au formulaire, définissez son champ de couleur sur "# 0000FF":
// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
Si ce champ est lié à une entité (est une propriété de cette entité), vous pouvez simplement lui 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;
}
Je ne fais généralement que définir la valeur par défaut pour un champ spécifique de mon entité:
/**
* @var int
* @ORM\Column(type="integer", nullable=true)
*/
protected $development_time = 0;
Cela fonctionnera pour les nouveaux enregistrements ou si vous mettez simplement à jour ceux existants.
'empty_data'
rappel est utilisé pour autoriser les paramètres du constructeur sur l'entité.
Comme Brian l'a demandé:
empty_data semble définir le champ sur 1 uniquement lorsqu'il est soumis sans valeur. Qu'en est-il lorsque vous souhaitez que le formulaire affiche par défaut 1 dans l'entrée lorsqu'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'])