Voir le flux RSS

phpiste

dataTable avec symfony3 [partie 2]

Noter ce billet
par , 23/09/2016 à 13h44 (3416 Affichages)
Bonjour,

Ce billet et une continuation de l’ancien billet manipuler une dataTable js
http://www.developpez.net/forums/blo...table-symfony2
A travers ce billet vous allez pouvoir améliorer l'exemple précédent en ajoutant un utilisateur via une popup.

Intro
J’ai pensé au début à créé un nouveau template pour l’ajout, mais ceci va nous obliger de quitter la page et perdre les fonctionnalités de refresh de dataTable, pour cela on va proposer à l’utilisateur un formulaire dans une popup qui lui permettra d’ajouter une entrée dans la base sans qu’il quitte la page des listes d’utilisateurs et pouvoir la rafraichir pour voir la nouvelle entrée, pour l’exemple je vais utiliser la popup de bootstrap.

Donc pour mettre le tout en place, j’ai effectué quelques modifications

Nom : Screen Shot 2016-09-23 at 11.19.09 AM.png
Affichages : 2148
Taille : 26,0 Ko
Importent: j'ai mis a jour la version du framework vers v3.
la création d’un nouveau bundle nommé AppBundle et déplacement des vues dedans (à partir du dossier Resources sous /app)
L’ajout plusieurs lib javascript:
Bootstrap: servira à améliorer l’ergonomie et la mise en page du site, et pour la popup javascript
jquery.form.js: pour simplifier l’envoi des formulaires en ajax

J’ai aussi utiliser le layout bootstrap suivant pour améliorer l’affichage
http://getbootstrap.com/examples/dashboard/

1/ Ajouter le formType

Pour ajouter une classe de formulaire, lancer tout simplement la commande

Code : Sélectionner tout - Visualiser dans une fenêtre à part
php bin/console generate:doctrine:form AppBundle:User
Un fichier sera créé sous AppBundle/Form, modifier le pour avoir le contenu suivant

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
 
<?php
 
namespace AppBundle\Form;
 
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
 
class UserType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
        ;
    }
 
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\User'
        ));
    }
}

2/ Ajouter l’action associé qui à travers, on pourra instancier le FormType et et le passer au rendu:


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
 
use Symfony\Component\Form\Extension\Core\Type\TextType;
use AppBundle\Entity\User;
use AppBundle\Form\UserType;
   …….
   …….
    /**
     * @Route("/user/new", name="user_new")
     */
    public function newAction(Request $request)
    {
        $user = new User();
 
        $form = $this->createForm(UserType::class, $user);
 
        return $this->render('AppBundle:user:new.html.twig', array(
            'form' => $form->createView(),
        ));
    }

Créer la vue pour afficher le formulaire


La vue contiendra des éléments html relatifs à la modal bootstrap ainsi que la fonction javascript pour envoyer le formulaire en ajax
Code html : 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
 
<div class="modal-header">
	<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
	<h4 class="modal-title">Ajouter un utilisateur</h4>
</div>
 
<form method="post" action="{{path('user_create')}}" class="user-create-form">
	<div class="modal-body">
		{{form_widget(form)}}
	</div>
	<div class="modal-footer">
	    <button type="button" class="btn btn-default" data-dismiss="modal">fermer</button>
	    <button type="submit" class="btn btn-primary">Enregistrer</button>
	</div>
</form>
 
<script>
        $('.user-create-form').submit(function(e) {
                e.preventDefault();
            $(this).ajaxSubmit({
                dataType: 'json',
                success: function(result){
                        if (result.status == 'ok'){
                                userTable.ajax.reload();
                                $('#myModal').modal('hide');
                        }
                }
            });
            return false;
        }); 
</script>

La mise en forme avec le layout

Aussi le layout principale est à changer pour inclure le html de base de la popup, le nouveau design et les différents scripts et styles de librairies tiers
Code html : 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
 
<html>
	<head>
		{%block css%}
		    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
 
		    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
 
		    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.6/css/jquery.dataTables.min.css" />
		    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.12/css/dataTables.bootstrap.min.css" />
		    <style type="text/css">
 
                    </style>
		{% endblock %}
	</head>
</html>
 
<body cz-shortcut-listen="true">
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">dataTable exemple</a>
        </div>
        {% block actions %}
        {% endblock %}
      </div>
    </nav>
 
    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-12 main">
        	<br />
    			{% block body %}
    			{% endblock %}
          </div>
        </div>
      </div>
    </div>
 
    <!-- /.modal source code -->
    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content"></div>
        </div>
    </div>
</body>
 
{% block javascript %}
    <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script src="https://cdn.datatables.net/1.10.6/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.12/js/dataTables.bootstrap.min.js"></script>
    <script type="text/javascript" src="http://malsup.github.io/min/jquery.form.min.js"></script>
{% endblock %}

la page liste des utilisateurs

Reste aussi le code de la page liste des utilisateurs, j’ai un peut changer son code js pour pouvoir l’adapter à la nouvelle fonctionnalité d’ajout.

Code html : 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
 
{% extends "AppBundle::base.html.twig" %}
 
{% block actions %}
    <ul class="nav navbar-nav navbar-right">
      <li><a class="btn btn-link user-add-btn" href="{{ path('user_new') }}"><i class="glyphicon glyphicon-plus"></i> Ajouter</a></li>
    </ul>
{% endblock %}
 
{% block body %}
    <h1 class="page-header">Liste des utilisateurs</h1>
    <table id="user-list" class="table table-striped"></table>
{% endblock %}
 
{% block javascript %}
    {{ parent() }}
 
    <script>
        var userTable;
        $(function() {
           //C'est le bouton qui affiche la popup, et charge aussi le formulaire dans cette dernière.
            $('.user-add-btn').click(function(e) {
                $.get(e.currentTarget.href, function(html){
                    $('#myModal .modal-content').html(html);
                    $('#myModal').modal('show');
                });
                e.preventDefault();
            });
 
              userTable = $('#user-list').DataTable({
                "processing": true,
                "serverSide": true,
                "ajax": "{{ path('user_paginate') }}",
                "sAjaxDataProp": "data",
                "pageLength": 10,
                "columns":[
                    {"data": "id"},
                    {"data": "name"},
                    {"data": "created_at"}
                ]
            });
        });
    </script>
{% endblock %}

Vous pourriez actuellement afficher le contenu du formulaire dane la popup en cliquant sur Ajouter

Nom : Screen Shot 2016-09-23 at 11.15.53 AM.png
Affichages : 2128
Taille : 25,1 Ko

Pour pouvoir insérer le nouvelle entrée dans la base il nous fera une nouvelle action createAction

Le rôle de cette action est de prendre les données envoye en POST.

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
 
    /**
     * @Route("/user/create", name="user_create")
     */
    public function createAction(Request $request)
    {
        $user = new User();
 
        $form = $this->createForm(UserType::class, $user);
 
        $form->handleRequest($request);
 
        if ($form->isSubmitted() && $form->isValid()) {
            dump($form->getData());
            die;
        }
    }

Si à ce stade là vous rencontrez l’erreur suivante
Nom : Screen Shot 2016-09-23 at 11.36.20 AM.png
Affichages : 2120
Taille : 50,7 Ko


C’est parce qu'il ne trouve pas une méthode capable de binder la valeur du champs name du formulaire avec l’attribut name de la classe.
Il suffit donc d’ajouter les setters des attributs, du coup voici le code de la class User
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
 
<?php
 
namespace AppBundle\Entity;
 
use Doctrine\ORM\Mapping as ORM;
 
/**
 * User
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;
 
    /**
     * @var string
     *
     * @ORM\Column(type="string")
     */
    private $name;
 
    /**
     * @var string
     *
     * @ORM\Column(type="datetime")
     */
    private $createdAt;
 
    public function __construct()
    {   
        $this->createdAt = new \dateTime('now');
    }
 
    public function getId() 
    {
        return $this->id;
    }
 
    public function getName() 
    {
        return $this->name;
    }
 
    public function getCreatedAt() 
    {
        return $this->createdAt;
    }
 
    public function setName($name) 
    {
        $this->name = $name;
 
        return $this;
    }
 
    public function setCreatedAt($createdAt) 
    {
        $this->createdAt = $createdAt;
 
        return $this;
    }
}

Reste maintenant l’insertion dans la base de données, pour cela ajoutant deux lignes, qui a la suite font appel au service doctrine.manager et permettent de persister l’objet et l'insérer dans la base.


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
 
    /**
     * @Route("/user/create", name="user_create")
     */
    public function createAction(Request $request)
    {
        $user = new User();
 
        $form = $this->createForm(UserType::class, $user);
 
        $form->handleRequest($request);
 
        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();
 
            return new JsonResponse(['status' => 'ok']);
        } else {
            return new JsonResponse(['status' => 'ko']);
        }
    }

@todo

Dans le prochain tuto
  • Supprimer un utilisateur
  • Modifier un utilisateur
  • Afficher les détails
  • Améliorer le filtre avec un critère supplémentaire: la date de création

Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Viadeo Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Twitter Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Google Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Facebook Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Digg Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Delicious Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog MySpace Envoyer le billet « dataTable avec symfony3 [partie 2] » dans le blog Yahoo

Mis à jour 17/08/2017 à 18h16 par Malick (Ajout balises code)

Catégories
Javascript , Développement Web , symfony2

Commentaires