Autocompletion dans un input avec JqueryUI

J’ai déjà regardé l’autocompletion sous Laravel, avec Bootstrap et les macro du helper Form sur un champ simple.

Cette fois ci, je vais utiliser JqueryUI et 2 champs dans mon formulaire, un champ caché : id et un champ de recherche texte ; ici c’est donc la même utilisation qu’un select. On utilise ce type de recherche lorsque que l’on désire retrouver un enregistrement particulier par une clé unique : un numéro de facture, un client …

Comme d’habitude, je débute par une route de test :

Route::controller('route','RouteController');

Il faut bien sûr intégrer la bibliothèque javascript dans le Layout principal.

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/black-tie/jquery-ui.min.css" rel="stylesheet">
...
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>

<script>
	@section('scripts')
		// script particulier a une page
	@show
</script>

Et oui, il faut aussi obligatoirement une section « scripts » pour lancer notre autocompletion js.

Dans le contrôleur, on a une méthode getIndex() qui affichera simplement le formulaire et une méthode getPays qui retourne elle, un tableau json.

<?php

class RouteController extends BaseController
{   
    /**
     *  affichage du formulaire de test
     *
     */
    public function getIndex(){
        return View::make('test');
    }

    /**
     *  recherche de résultats par ajax
     *
     */
    public function getPays($maxRows)
    {
      $max= Input::get('maxRows');
      $find= trim(Input::get('txt'));
      $array=array();

      /*$array[]=array('id'=>1,'value'=>'Automne');
      $array[]=array('id'=>2,'value'=>'Autoroute');
      $array[]=array('id'=>3,'value'=>'Autoroutier');
      $array[]=array('id'=>5,'value'=>'Amérique');
      $array[]=array('id'=>6,'value'=>'Américain');
      $array[]=array('id'=>7,'value'=>'Amélie'); */

      $results = DB::table('pays')->where('pays','LIKE', '%'.$find.'%')->take($maxRows)->get();

      foreach($results as $result){
         $array[]= array( 'id'=>$result->id, 'value'=>$result->pays );
      }
      return Response::json($array);
    }
}

Le méthode getPays(), notre service ajax, prend en parametres $maxRows : le nombre maximum de résultats à retourner et surtout Input::get(‘txt’) qui est le fragment de chaine pour faire une recherche pour l’autocompletion. Ce fragment de chaine est envoyé « en temps réel » par le formulaire par le biais d’ajax.

Il ne reste plus que la vue test.blade.php a écrire, le gros morceau :

@section('content')
<div class="page-header">
	<h3>test</h3>
</div>
	{{ Form::open() }}

	<fieldset>
		<label from="recherche">Pays de visite :</label>
		<input type="text" id="recherche" name="recherche" autocomplete="off">
		<input type="hidden" id="recherche_id" name="recherche_id" size="3" readonly>
	</fieldset>

	{{ Form::close() }}
@stop

La section Principale est très simple, nous créons juste un champ caché (ou type= »text » pour voir ce qui ce passe). C’est ce champ caché qui sera envoyé, utilisé par le contrôleur à la réception du formulaire; le champ texte de recherche de ce formulaire lui n’a aucune utilité puisqu’il correspond à la clé du champ caché.

@section('styles')
.invalide { }
.valide {  border-color:#0a0 !important; }
@stop

On peut créer une section style pour différencier les input valides , des invalides.

Il ne reste plus que la section scripts.
Pour mon formulaire, je vais utiliser 3 actions  du plugin jquery :
« source » : action ajax de demander une liste de réponses au serveur, action déclenchée a partir de la variable minLength (3=a partir de 3 caractères saisis)
« select » : action déclenchée par l’utilisateur lorsqu’il sélectionne une entrée de la « liste ajax »;
« change » : lorsque l’utilisateur quitte la zone de saisie

@section('scripts')
	@parent

$('#recherche').autocomplete({
    minLength: 3,
    source : function(requete, reponse){ 
        $.ajax({
	    url : '{{URL::action( 'RouteController@getPays', array( 12 ) )}}',
            dataType : 'json', 
            data : {
                txt : requete.term // on donne la chaîne de caractère tapée dans le champ de recherche
            },
            success : function(data){
			      var suggestions = [];  
                        $.each(data, function(i, val){  
                 	    suggestions.push({"id": val.id, "value": val.value});
             	        });  
             	        reponse(suggestions); 
            }
        });
    },

    select : function(event, ui) {
		$( '#'+this.id+'_id').val(ui.item.id);
		$( this ).removeClass( "invalide" ).addClass( "valide" );
    },

    change: function( event, ui ) {
	      var id = $( '#'+this.id+'_id').val();
	      if (id<1) {
		   //alert('valeur incorrecte');
		   $( this ).removeClass( "valide" ).addClass( "invalide" );
		   //this.focus();
	      }
    }
});

@stop

Source :
dans « url » nous avons l’url pour accéder a notre service ajax, notre tableau json.
« data » représente la chaine de caractères de recherche.
« success » est la méthode appelée à la bonne réception du service ajax, ici nous parcourons notre tableau json pour retourner les bonnes valeurs a la liste javascript.

Select :
Notre but premier est de remplir notre champ caché ! donc  à la sélection d’un item dans la liste par l’utilisateur, nous copions la valeur « id » dans l’attribut valeur de l’input caché.

Change :
vérifie si le champ caché a bien été saisi. Eventuellement, on peut afficher un message d’erreur, bloquant ou pas.

Share Button

Vous devriez aimer...