Nous allons voir ici comment utiliser le bundle pugx/autocompleter-bundle permettant d'avoir une autocompletion simple sur un champs de recherche.
1 ) Installation du bundle avec composer
composer require pugx/autocompleter-bundle
2 ) Dans appeKernel.php ajoutez
new PUGX\AutocompleterBundle\PUGXAutocompleterBundle()
3 ) Sur votre twig base.html.twig ajoutez ce dont le bundle a besoin, ici il faut rajouter jquery-ui et le script adapté pour l'autocomplétion
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="{{ asset('bundles/pugxautocompleter/js/autocompleter-jqueryui.js') }}"></script>
4 ) Rajouter ces éléments pour loader l'autocompleter sur le formulaire adéquat au niveau de votre fichier javascript, app.js par exemple à la racine web de votre projet.
$(document).ready(function () {
'use strict';
$('#form_titre').autocompleter({
url_list: '/search-article',
url_get: '/?term='
});
$("#ui-id-1").click(function(){
var id = $("#form_titre").val();
if(id.toString().length > 0){
$(location).attr('href', '/article/'+id.toString());
}
})
});
5) Créer le formulaire que vous avez besoin, Form.html.twig Nous allons utiliser l'entité "Article" et son FormType pour l'exemple
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use PUGX\AutocompleterBundle\Form\Type\AutocompleteType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ArticleType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('titre', AutocompleteType::class, ['class' => 'AppBundle:Article']);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Article',
]);
}
}
Nous créons ensuite le twig adapté
{% include "base.html.twig" %}
{% block search %}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
{% endblock %}
6) rajouter ce json qui sera loader par le script autocomplete search.json.twig
[{% for article in articles -%}
{{ {value: article.id, label: article.titre}|json_encode|raw }}
{%- if not loop.last %},{% endif -%}
{%- endfor %}]
7 ) Dans votre controller rajouter le modèle sur lequel vous souhaitez lancer la recherche et rajoutez le champs nécessaire, dans cet exemple "Article".
public function searchAction()
{
$article = new Article();
$form = $this->createFormBuilder( $article, array(
'action' => $this->generateUrl('homepage').'?term=',
'method' => 'GET',
) )
->add('titre', null, ['label' => ' Barre de recherche'] )
->getForm();
return $this->render(':default/Form.html.twig', ['form' => $form->createView() ]);
}
Nous Rajouter dans l'entité la requête adapté à la recherche, ici un exemple simple qui peut être totalement revu :)
namespace AppBundle\Repository;
/**
* articleRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ArticleRepository extends \Doctrine\ORM\EntityRepository
{
/**
* @param string $titre
*
* @return array
*/
public function findLike($titre)
{
return $this
->createQueryBuilder('a')
->where('a.titre LIKE :titre')
->setParameter( 'titre', "%$titre%")
->orderBy('a.titre')
->setMaxResults(5)
->getQuery()
->execute()
;
}
}
8 ) Nous créons l'action dans le Controller de votre choix qui permettra de lancer la recherche et de l'afficher dans le json créé plus en amont.
/**
* @Route("/search-article", name="search_article", defaults={"_format"="json"})
* @Method("GET")
*/
public function searchArticleAction(Request $request)
{
$q = $request->query->get('term'); // use "term" instead of "q" for jquery-ui
$results = $this->getDoctrine()->getRepository('AppBundle:Article')->findLike($q);
return $this->render(":default/search.json.twig", ['articles' => $results]);
}