Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/04/2011, 19h03   #1
Membre actif
 
Avatar de FrankOVD
 
Inscription : juin 2005
Messages : 407
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 407
Points : 182
Points : 182
Envoyer un message via MSN à FrankOVD
Par défaut Recherche de type Autocomplete (JQuery ou YUI) combiné avec Select

Bonjour,

J'ai développé une application dans laquelle il est possible d'aller sélectionner un produit dans une liste d'au moins 5000 items. Bien entendu, j'ai affiché cette liste sous forme de liste de choix SELECT car cela permet de voir textuellement le nom du produit choisi alors que la valeur du champ se réfère à son ID.

Le problème, c'est que les utilisateurs ont parfois peine à trouver le produit qu'ils recherchent dans une aussi longue liste. J'avais alors implanté un champ INPUT auquel j'avais associé la fonctionnalité Autocomplete de JQueryUI, cela cependant enlève aux utilisateurs d'utiliser le mode liste quand ils recherchent un produit au nom semblable (ex : MODULE 1426 vs MODULE 1438).

Finalement, j'en suis venu à un espèce d'hybride. J'ai un objet SELECT qui, lorsqu'on y déclenche l'événement KEYDOWN, tranfère le focus sur un champ INPUT positionné juste aussi dessus et lance l'autocomplete. Je l'ai fait en JQuery ainsi qu'avec YUI, l'Autocomplete de YUI 3 étant beaucoup plus performant. ... Tout fonctionnait très bien jusqu'à dernièrement alors que plusieurs navigateurs ont subi d'importantes mises à jour et que depuis, mon code YUI génère une erreur "Caractère incorrect" que je n'arrive pas à régler.

Je suis donc à la recherche soit d'une astuce pour réparer mon code, soit d'une alternative à ma méthode.

Voici mon code avec YUI 3 (j'utilise YUI et JQuery à la fois) :

Code :
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
 
var sb = $("SELECT", piece); //Ma objet SELECT existe déjà
var i = $("<input>");
$(i).attr({"type":"text","id":"id_piece_override"+Math.random(),"name":"ac_piece"});
[...]
$(piece).append(i);
$(sb).bind("keydown", function(e) { 
  //Reçoit un tableau en JSon avec des objets {id:id_produit,text:nom}
  YUI().use('autocomplete', 'autocomplete-highlighters', function (Y) {
    var ac = new Y.AutoComplete({
      inputNode: "INPUT[name=ac_piece]",
      source : "jx.php?vmod=Pieces&vfunc=get_AC_pieces&query={query}",
      resultTextLocator:"text",
      render:false,
      alwaysShowList:false,
      tabSelect:true,
      maxResults:150,
      minQueryLength:2,
      resultHighlighter:'wordMatch'
    });
 
    ac.on("select", function(e, itemNode) {
      $("INPUT[name=ac_piece]").css({"background":"transparent"});
      var id = e.result.raw.id;
      if(!isNaN(id)) {
        $(sb).val(id);
        $(i).val("");
        setTimeout("$('INPUT[name=ac_piece]').val('')", 50); //Fix latence Internet Explorer
	$(sb).focus();
	$(sb).trigger("change");
      }		
 
      $(sb).bind("keydown", function(e) {
        $("INPUT[name=ac_piece]").css({"background-color":"#FFFFFF"});
        $("INPUT[name=ac_piece]").val(String.fromCharCode(e.which));
        $("INPUT[name=ac_piece]").focus();
        $(this).unbind("keydown");
	ac.render();
	return false;
      });
    });
 
    $(sb).bind("keydown", function(e) {
      $("INPUT[name=ac_piece]").css({"background-color":"#FFFFFF"});
      $("INPUT[name=ac_piece]").val(String.fromCharCode(e.which));
      $("INPUT[name=ac_piece]").focus();
      $(this).unbind("keydown");
      ac.render();
      return false;
    });
  });
});
Erreur générée dans IE9 (plus explicite que dans Firebug quoi que tout aussi imprécis)
Code :
1
2
3
4
5
6
 
Ligne: 15
Caractère: 982
Code: 0
Message d'erreur: Caractère incorrect
URL: http://yui.yahooapis.com/combo?3.3.0/build/io/io-base-min.js&3.3.0/build/json/json-parse-min.js
__________________
http://www.overdrunk.net

Pensez à la balise
FrankOVD est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/04/2011, 15h08   #2
Membre confirmé
 
Avatar de Pymento
 
Homme
Ingé. Info.
Inscription : janvier 2008
Messages : 338
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingé. Info.

Informations forums :
Inscription : janvier 2008
Messages : 338
Points : 273
Points : 273
Bonjour, je comprend pas pourquoi l'autocomplete de JQuery ne suffit pas ?

à moins que tu ne l'utilise pas correctement, le principe et de recup' l'ensemble des entrées qui commencent par xxx... de changer ton Select(en lui injectant l'ensemble de tes réponses) et d'afficher les 5premieres dans ton input text par exemple.
__________________
Memento Quia Pulvis Es, Et In Pulverem ReverteriS
Pymento est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/04/2011, 15h40   #3
Membre actif
 
Avatar de FrankOVD
 
Inscription : juin 2005
Messages : 407
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 407
Points : 182
Points : 182
Envoyer un message via MSN à FrankOVD
Citation:
Envoyé par Pymento Voir le message
Bonjour, je comprend pas pourquoi l'autocomplete de JQuery ne suffit pas ? .
Simplement pour des raisons de performances. Le délai entre la saisie et l'apparition de la liste de résultats est trop long. J'ai d'abord développé en JQuery car je le préfère aux autres mais ces articles ont guidé ma réflexion quand j'ai frappé le mur de la performance :

D'abord, une analyse intéressante du potentiel des librairies Javascript par une personne qui, comme moi, avait un penchant pour JQuery
THE BEST JAVASCRIPT LIBRARY

De l'information en extra que je n'ai pas beaucoup utilisé mais qui m'a beaucoup inspiré.
Building Fast Client-side Searches

J'ai finalement nettoyé un peu mon code et vidé le cache. Je ne sais si ça le fait dans les autres navigateurs, mais l'Autocomplete de YUI charge des résultats mis en cache même si la paramêtre cache est défini a false. Il faut donc nettoyer le cache en cours de développement.

Voici au final un code fonctionnel que j'ai pu placer dans mes librairies de fonctions. Ça fonctionne parfaitement.
Code :
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
 
/**
 * Gère un hybride permettant une recherche par saisie sur un objet SELECT
 * Paramètres : str sel_select : Sélecteur menant à l'objet SELECT
 *              str sel_input  : Sélecteur menant à l'objet INPUT (chaîne vide si aucun)
 *              str vmod       : Nom de la Classe PHP à interroger en Ajax
 *              str vfunc			 : Nom de la fonction de la Classe qui va générer les résultats
 *              str e					 : Événement
 **/
function YUI_autocomplete(sel_select, sel_input, vmod, vfunc, e) {
	if(($(sel_select).length == 1)&&($(sel_select).length == 1)) {
		if($(sel_input).length == 0) {
			var i = $("<input>");
			$(i).attr({"type":"text","id":"id"+random_range(1000,9999)});
			sel_input = "#"+$(i).attr("id");
			$(i).addClass("select_override");
			$(i).css({"width":$(sel_select).outerWidth() - 18,"margin-left":-1 * $(sel_select).outerWidth(),"margin-top":"0px","position":"absolute"});
			$(sel_select).after(i);
		}
 
		if(e.keyCode) var c = String.fromCharCode(e.keyCode); //Internet Explorer
		else var c = String.fromCharCode(e.which); //Firefox, Chrome
 
		YUI().use('autocomplete', 'autocomplete-highlighters', function (Y) {
			var ac = new Y.AutoComplete({ 
				inputNode: sel_input,
				source   : "jx.php?vmod="+vmod+"&vfunc="+vfunc+"&query={query}",
				resultTextLocator:"text",
				render:true,
				alwaysShowList:false,
				tabSelect:true,
				maxResults:150,
				minQueryLength:2,
				resultHighlighter:'wordMatch'
			});
			//Transfert de la valeur sélectionnée vers l'objet SELECT
			ac.on("select", function(e, itemNode) {
				$(sel_input).css({"background":"transparent"});
 
				var id = e.result.raw.id;
				if(!isNaN(id)) {
					$(sel_select).val(id);
					setTimeout("$('"+sel_input+"').val(''); $('"+sel_select+"').focus();", 50); //Si pas de délais, ne s'exécute pas...
					$(sel_select).trigger("change");
				}
			});
			$(sel_input).focus(); //Place le curseur dans le champ de saisie
			$(sel_input).val(c);  //Insère le premier caractère
			$(sel_input).css({"background-color":"#FFFFFF"});
		});
	}
	else {
		alert("L'option de recherche sur saisie ne peut pas s'exécuter car la référence à la liste de choix \""+sel_select+"\" n'est pas valide.");
		return false;
	}
}
__________________
http://www.overdrunk.net

Pensez à la balise
FrankOVD est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/04/2011, 15h51   #4
Membre confirmé
 
Avatar de Pymento
 
Homme
Ingé. Info.
Inscription : janvier 2008
Messages : 338
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 24
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingé. Info.

Informations forums :
Inscription : janvier 2008
Messages : 338
Points : 273
Points : 273
ha d'acc, dans ce cas je m'efface du débat, je suis pas encore à l'aise dans les problématiques de performance!
__________________
Memento Quia Pulvis Es, Et In Pulverem ReverteriS
Pymento est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h58.


 
 
 
 
Partenaires

Hébergement Web