Bonjour les devs,
J'essaye de rendre un form dynamique en suivant cette doc: http://symfony.com/doc/2.2/cookbook/...ification.html
Les champs dynamiques sont une liste d'IPs et une checkbox qui apparait ou nom, selon la config du server choisi.
Pour faire simple (et propre ?), je decide de submit mon form en ajax a chaque fois que le server choisi change, et je remplace mon formulaire par la nouvelle vue.
Ca marche, mais le soucis c'est que les erreurs des champs non remplis apparaissent lors de l'update ajax de mon form. Logique, me direz-vous, mais moi je n'en veux pas de ces erreurs, je veux juste mon form updaté...
Voici mon FormType:
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 class DomainCreateType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $factory = $builder->getFormFactory(); $serverRepository = $options['server_repository']; $builder->add('names', 'textarea', array( 'constraints' => array( new Assert\Regex(array('pattern' => "/^[^\.]+\.[[:alpha:]\.]{2,6}$/m")), new Assert\NotBlank(), ), )); // Limit to user servers $builder->add('server', 'entity', array( 'class' => 'Nexy\MainBundle\Entity\Server', 'property' => 'name', 'empty_value' => 'Choisissez un serveur', 'required' => true, 'constraints' => array( new Assert\NotNull(), ), 'query_builder' => function (ServerRepository $er) use ($options) { return $er->getByOwnerQB($options['user']); }, )); // Ask if user want a database // $builder->add('database', 'checkbox', array( // 'required' => false, // 'label' => 'Base de donnée associée', // )); // Ips selection by server selected $refreshIps = function(FormInterface $form, $server = null) use ($factory) { $form->add($factory->createNamed('ip', 'entity', null, array( 'class' => 'Nexy\MainBundle\Entity\Ip', 'property' => 'ip', 'label' => 'Ip', 'required' => true, 'constraints' => array( new Assert\NotNull(), ), 'query_builder' => function (IpRepository $er) use ($server) { $qb = $er->getByServerQB($server); $qb->andWhere($qb->getRootAlias().'.status = :status')->setParameter('status', Status::GOOD); return $qb; }, ))); }; // Database option if server mysql compliant $refreshDatabase = function(FormInterface $form, $server = null) use ($factory, $serverRepository) { if (is_int($server) || is_string($server)) { $server = $serverRepository->find($server); } if (null != $server && true === $server->getMysqlServer()) { $form->add($factory->createNamed('database', 'checkbox', null, array( 'required' => false, 'label' => 'Base de données associée', ))); } }; // Form creation event $builder->addEventListener(FormEvents::PRE_SET_DATA, function (DataEvent $event) use ($refreshIps, $refreshDatabase) { $form = $event->getForm(); $data = $event->getData(); if (array_key_exists('server', $data)) { $refreshIps($form, $data['server']); $refreshDatabase($form, $data['server']); } if ($data === null) { $refreshIps($form); $refreshDatabase($form); } }); // Form submit, before validation $builder->addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($refreshIps, $refreshDatabase) { $form = $event->getForm(); $data = $event->getData(); if (array_key_exists('server', $data)) { $refreshIps($form, $data['server']); $refreshDatabase($form, $data['server']); } }); } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setRequired(array( 'user', 'server_repository' )); } public function getName() { return 'domain_create'; }
Mon action du controlleur:
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public function newAction() { // TODO: Remove new from domains name /* @var $domainManager DomainManager */ $domainManager = $this->get('nexy.domain_manager'); $preSelectedServer = $this->getDoctrine()->getRepository('NexyMainBundle:Server')->find($this->getRequest()->get('server_id', 0)); // Check if user has view rights if (!$this->get('security.context')->isGranted('EDIT', $preSelectedServer)) { return $this->redirect($this->generateUrl('nexy_front_domain_new')); } $sr = $this->getDoctrine()->getManager()->getRepository('NexyMainBundle:Server'); $form = $this->createForm(new DomainCreateType(), array('server' => $preSelectedServer), array('user' => $this->getUser(), 'server_repository' => $sr)); // Ajax update form if ($this->getRequest()->isXmlHttpRequest()) { $form->bind($this->getRequest()); return new Response($this->renderView('NexyFrontBundle:Domain:_new_form.html.twig', array('form' => $form->createView()))); } // Form submit if ($this->getRequest()->isMethod('POST')) { $form->bind($this->getRequest()); if ($form->isValid()) { $withDatabase = $form->get('database')->getData(); $names = explode("\r\n", $form->get('names')->getData()); $server = $form->get('server')->getData(); $ip = $form->get('ip')->getData(); // Check unused domains $unused = true; foreach ($server->getDomains() as $domain) { if (in_array(strtolower($domain->getName()), array_map('strtolower', ($names)))) { $unused = false; $this->get('session')->getFlashBag()->add('error', "Le domaine {$domain->getName()} existe déjà sur le serveur {$server->getName()}."); break; } } if ($unused === true) { // Register domains foreach ($names as $name) { $name = trim($name); if ($name === '') { continue; } $domain = new Domain(); $domain->setName($name); $domain->setServer($server); $domain->setIp($ip); $domainManager->registerDomain($domain, $withDatabase); // Add a create operation for the domain $this->get('nexy.operation_manager')->opCreate($this->getUser(), $domain); if ($withDatabase === true) { $this->get('nexy.operation_manager')->opCreate($this->getUser(), $domain->getSqlDatabases()->get(0)); } } $this->get('session')->getFlashBag()->add('success', "Les domaines sont ajoutés !"); return $this->redirect($this->generateUrl('nexy_front_server_show_domains', array('slug' => $server->getSlug()))); } } } return array( 'form' => $form->createView(), ); }
Et le code twig du formulaire:
Code twig : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 <form id="domain_create" class="form-horizontal" action="{{ path('nexy_front_domain_new') }}" method="post" {{ form_enctype(form) }}> {{ form_row(form.names) }} {{ form_row(form.server) }} {{ form_row(form.ip) }} {{ form_rest(form) }} <div class="form-actions"> <input type="submit" class="btn btn-primary" value="Ajouter"/> <a class="btn" href="{{ path("nexy_front_domain_index") }}">Annuler</a> </div> </form>
En gros, est-il possible de binder le formulaire sans checker les erreurs ? Ou dois-je faire completement autrement ?
Merci d'avance de votre aide !
Partager