Hello web developers .
Je suis sur un projet web et je cherche la manière la plus propre pour mettre en place un moteur de recherche avec pagination des résultats.
Ce projet consiste à rechercher des données dont l'adresse complète est enregistré.
Concernant la gestion des adresses, j'ai décidé de modéliser une table pour l'adresse, une pour la ville, une pour le département et la région puis une autre pour le pays.
Je dispose donc d'un mld de ce genre :
- adresse(id, ..., adresse, #ville_id) // 92-98 Boulevard Victor Hugo
- ville(id, nom, cp, adresse_id) // 92110 Clichy
- departement(id, nom, region_id) // Hauts-de-Seine
- region(id, nom, pays_id) // Île-de-France
- pays(id, nom) // France
D'entrée de jeu je me pose la question :Quelque recherche mon permis de découvrir que la plupart des cas utilisés la méthode GET.Quelle méthode utiliser pour ce formulaire, POST ou GET ?
Cependant j'ai utilisé la méthode POST, car je me sers de l'hydratation de formulaire avec l'api google maps.
En effet celle-ci me permet d'hydrater les champs de mon formulaire à l'aide du composant componentForm.
Api : https://developers.google.com/maps/d...ressform?hl=fr
Sur moteur de recherche j'inclue donc l'api google maps (Place Autocomplete Address Form) afin de bénéficier de l'auto complétion des adresses maps.
Côté client j'utilise l'architecture informatique Ajax à l'aide de la bibliothèque jQuery et plus particulièrement la méthode jQuery.ajax() pour la pagination.
Et la méthode $.post pour le formulaire de recherche.
Côté serveur j'utilise le bundle KnpPaginatorBundle (https://github.com/KnpLabs/KnpPaginatorBundle) pour générer mes résultats paginés.
Et le composant FormBuilder de symfony pour la génération du formulaire.
Je souhaite donc ici afficher mes résultats lors de la soumission du formulaire.
Puis afficher les résultats suivants sans avoir à recharger la page lors du clic d'un nouveau numéro de page.
Cependant, je n'arrive pas à conserver mes résultats lors du passage à la seconde page.
Ici j'avais comme idée d'utiliser les sessions pour enregistrer les données de mon formulaire mais j'ai décidé d'abandonner cette méthode, car pour moi je ne pense pas que ce soit la bonne méthode.
En ce qui concerne la pagination elle fonctionne correctement en ajax, j'ai pu la tester avec des résultats pré-chargés dans la méthode du contrôleur.
Voici des extraits de code :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // index.html.twig <div id="displayResults"> // Et les templates incluent qui vont suivre :
Code : 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 // Template twig utilisé pour la pagination par le bundle knpPaginatorBundle (custom_pagination.html.twig) {% if pageCount > 1 %} <nav> <ul class="pagination"> {% if previous is defined %} <li class="page-item"> <a class="page-link" data-page="{{ previous }}" href="#" aria-label="Previous"> <span aria-hidden="true">«</span> <span class="sr-only">Previous</span> </a> </li> {% endif %} {% for page in pagesInRange %} {% if page != current %} <li class="page-item"><a class="page-link" data-page="{{ page }}" href="#">{{ page }}</a></li> {% else %} <li class="page-item active"><a class="page-link">{{ page }}</a></li> {% endif %} {% endfor %} {% if next is defined %} <li class="page-item"> <a class="page-link" data-page="{{ next }}" href="#" aria-label="Next"> <span aria-hidden="true">»</span> <span class="sr-only">Next</span> </a> </li> {% endif %} </ul> </nav> {% endif %}
Code : 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 // Template du formulaire {{ form_start(form, {'attr': {'id':'address_search', 'class': 'form-inline', 'role' : 'search' }}) }} {{ form_errors(form) }} {{ form_row(form.address, {'id':'autocomplete', 'attr': {'placeholder':'Enter an address, a city, postal code'}}) }} {# Hidden fields #} {{ form_row(form.streetNumber, {'id':'street_number'}) }} {{ form_row(form.route, { 'id': 'route'}) }} {{ form_row(form.latitude, { 'id': 'lat'}) }} {{ form_row(form.longitude, { 'id': 'lng'}) }} {{ form_row(form.city, { 'id': 'locality'}) }} {{ form_row(form.postalCode, { 'id': 'postal_code'}) }} {{ form_row(form.department, { 'id': 'administrative_area_level_2'}) }} {{ form_row(form.region, { 'id': 'administrative_area_level_1'}) }} {{ form_row(form.country, { 'id': 'country'}) }} {{ form_row(form.search, {'attr': {'class':'btn btn-primary'}}) }} {{ form_end(form) }}
Code : 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 // Méthode ajax du formulaire $('#search').on('submit', function(e) { e.preventDefault(); var $this = $(this); // The jQuery object of the form $.ajax({ url: Routing.generate('search'), // méthode du bundle FOSJsRoutingBundle type: 'POST', data: $this.serialize(), // Serializing form data success: function( result ) { var elem = document.getElementById('displayResults'); elem.innerHTML = ""; elem.innerHTML = result; } }); }); // Méthode ajax pour la pagination $('body').on('click', 'a.page-link', function(e) { e.preventDefault(); var page = $(this).attr('data-page'); $.ajax({ type: "POST", url: Routing.generate('index'), data: { "page" : page }, cache: false, success: function(result){ var elem = document.getElementById('displayResults'); elem.innerHTML = ""; elem.innerHTML = result; } }); });
Code : 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 // Méthodes du controlleur public function indexAction(Request $request) { $form = $this->createForm(AddressSearchType::class); $em = $this->getDoctrine()->getManager(); $res = $em->getRepository('CoreBundle:MyEntity')->findByLocation(); // Récupère les résultats en fonction de la location de l'utilisateur $pagination = $this->pagination( $res, $request->get('page', 1) ); if ($request->isXmlHttpRequest()) { return new Response($this->renderView('CoreBundle:MyEntity:list.html.twig', array('pagination' => $pagination))); // parameters to template } return $this->render('CoreBundle:MyEntity:index.html.twig', [ 'form' => $form->createView(), 'pagination' => $pagination ]); } public function searchAction(Request $request) { if($request->isXmlHttpRequest()) { $data = $request->get('address_search'); // Requête pour récupérer les données du formulaire sérialisé $em = $this->getDoctrine()->getManager(); // $data['query_request'] // User input, verify validation rules $res = $em->getRepository('CoreBundle:MyEntity')->findByAddress($data); $pagination = $this->pagination( $res, $request->get('page', 1) ); return new Response($this->renderView('CoreBundle:MyEntity:list.html.twig', array('pagination' => $pagination))); } } private function pagination($data, $page, $limit = 2) { $paginator = $this->get('knp_paginator'); $pagination = $paginator->paginate($data, $page, $limit); $pagination->setTemplate('CoreBundle:Template:custom_pagination.html.twig'); return $pagination; }Merci d'avance pour vos soutiens.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 // Routes index: path: /my_uri/ defaults: _controller: CoreBundle:MyEntity:index options: expose: true #test# search: path: /my_uri/search defaults: _controller: CoreBundle:MyEntity:search options: expose: true
Partager