Moteur de recherche autocomplétion avec un select et un input
Bonjour à tous et à toutes.
J'ai un petit moteur de recherche autocompletion qui fonctionne très bien mais je voudrai le modifier.
Pour le moment ce moteur de recherche fonctionne avec un input qui affiche les références présentes en bdd au fur et à mesure que l'on renseigne le champ.
Mon souci c'est que parfois il y a beaucoup de références qui s'affiche en dessous.
J'aimerai pour limiter l'affichage de trop de référence ajouter un champ select pour choisir une marque puis que l'input affiche les références comme actuellement mais en tenant conte de la valeur du select.
Voici mon script actuel.
Le formulaire
Code:
1 2 3 4 5 6
| <form style=" width:250px; display:inline;" method="post" action="<?php echo''.ROOTPATH.'';?>/index.php?page=cartouche">
<input type="hidden" name="choix" value="POUR_IMPRIMANTE" />
<input name="name" type="text" autocomplete="off" onKeyUp="suggest(this, 'cartouche_generique', 'POUR_IMPRIMANTE');" placeholder="Par Imprimante"/>
<img src="<?php echo''.ROOTPATH.'';?>/images/go.png" alt="fleche"/>
<input type="submit" class="Cder" value="ok"/>
</form> |
La page autocomplete.js
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| var value_suggested = ''; //On stock la value du champ de texte pour éviter de refaire le processus si la valeur n'a pas changé (appuyé sur une touche autre que caractère)
function suggest(element, table, field){
//Détection du navigateur
var is_ie = ((navigator.userAgent.toLowerCase().indexOf("msie") != -1) && (navigator.userAgent.toLowerCase().indexOf("opera") == -1));
/*Fonction utile : détermine la position absolue exacte d'un objet sur la page*/
findPos = function(obj){
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft
curtop += obj.offsetTop
}
}
return [curleft,curtop];
}
//Création de la liste des propositions si elle n'existe pas encore
if(!document.getElementById('suggestsList')){
var suggestsList = document.createElement('ul');
suggestsList.id = 'suggestsList';
/*On donne à la liste la même largeur que le champ de texte => on doit récupérer sa largeur et son padding*/
var style = (!is_ie ? window.getComputedStyle(element, null) : element.currentStyle); //Récupération du style
if(style.width){
var width = parseInt(style.width.replace(/px/, '')); //On transforme la largeur dans le style en int
//On récupère le padding éventuel du champ pour le rajouter à la largeur à attribuer à la liste
var paddingRight = (style.paddingRight ? style.paddingRight : false);
if(paddingRight){
paddingRight = parseInt(paddingRight.replace(/px/, ''));
width += paddingRight;
}
var paddingLeft = (style.paddingLeft ? style.paddingLeft : false);
if(paddingLeft){
paddingLeft = parseInt(paddingLeft.replace(/px/, ''));
width += paddingLeft;
}
width = (isNaN(width) ? 150 : width);
suggestsList.style.width = 500+'px'; //On donne à la liste la même largeur que celle du champ de texte
}
//On positionne la liste sous le champ
suggestsList.style.position = 'absolute';
var coord = findPos(element); //Récupération des coordonnées du champ
suggestsList.style.left = coord[0]+'px';
suggestsList.style.top = coord[1]+(19)+'px'; //On ajoute 19px de haut pour que la liste soit sur le champ et non par-dessus
document.body.appendChild(suggestsList); //On insère la liste dans le document
}
else{
//Si la liste existe déjà, on se contente de la repérer par rapport à son id
suggestsList = document.getElementById('suggestsList');
}
//Si la valeur a changée, on masque la liste, le temps d'actualiser son contenu
if(element.value != value_suggested){
suggestsList.style.display = 'none';
}
//Fonction servant à cacher les suggestions
closeSuggest = function(nofocus){
var todelete = document.createElement('div');
todelete.appendChild(suggestsList);
if(!nofocus){ element.focus(); }
};
//Fonction gérant le parcour des éléments à l'aide des touches directionnelles
selectSuggest = function(direction){
//On regarde si un élément est selectionné
var selected = -1;
var lis = suggestsList.getElementsByTagName('li');
for(i=0; i<lis.length; i++){
if(lis[i].id == 'selectedSuggest'){
selected = i;
}
lis[i].id = '';
}
selected += direction;
selected = (selected < -1 ? (lis.length-1) : selected);
if(selected >= 0 && selected < lis.length){
lis[selected].id = 'selectedSuggest';
}
};
//Remplit le champ avec la suggestion sélectionnée
useSelected = function(){
//On regarde si un élément est selectionné
var lis = suggestsList.getElementsByTagName('li');
for(i=0; i<lis.length; i++){
if(lis[i].id == 'selectedSuggest'){
element.value = lis[i].firstChild.innerHTML;
}
}
closeSuggest();
};
document.body.onkeyup = function(e){
var key = (!is_ie ? e.keyCode : window.event.keyCode);
switch(key){
case 27: //Esc
closeSuggest();
break;
case 9: //Tab
closeSuggest(true); //On referme la liste sans redonner le focus au champ
break;
case 38: //Up
selectSuggest(-1);
break
case 40: //Down
selectSuggest(1);
break;
case 13: //Enter
useSelected();
break;
}
};
document.body.onclick = function(){ closeSuggest(true); };
if(element.value != '' && element.value != value_suggested){
/*Récupération de la liste des suggestions*/
var suggests = new Array();
var xhr_generique = false;
try { xhr_generique = new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e){ xhr_generique = new XMLHttpRequest(); }
//Requête AJAX : attention à bien donner le chemin du fichier autocomplete_ajax.php
//timestamp en parametre pour empecher la mise en cache
xhr_generique.open("GET", '../includes/autocomplete_ajax.php?table='+table+'&field='+field+'&search='+element.value+'&nocache='+Math.floor((new Date()).getTime()), true);
// Attente de l'état 4 (-> OK)
xhr_generique.onreadystatechange = function () {
// l'état est à 4, requête reçue
if(xhr_generique.readyState == 4){
var xml = xhr_generique.responseXML; //Récupération du xml contenant les suggestions
var suggests_xml = xml.getElementsByTagName('suggest');
for(i=0; i<suggests_xml.length; i++){
//On remplit l'array des suggestions
suggests[suggests.length] = suggests_xml[i].firstChild.data;
}
//On supprime l'ancien contenu de la liste des suggestions, puis on la remplit
suggestsList.innerHTML = '';
if(suggests.length){
for(i=0; i<suggests.length; i++){
var li = document.createElement('li');
var a = document.createElement('a');
a.innerHTML = suggests[i];
//On ajoute un évènement sur le lien pour que son contenu soit mis dans le champ lorsque l'on clique dessus
a.onclick = function(){
element.value = this.innerHTML;
closeSuggest();
};
li.appendChild(a);
suggestsList.appendChild(li);
}
//Maintenant que la liste est remplie, on l'affiche
suggestsList.style.display = '';
}
else{
//S'il n'y a aucune suggestion correspondante, on cache la liste
closeSuggest();
}
}
}
xhr_generique.send(null);
}
else if(element.value == ''){
//Si le champ est vide, on cache la liste
closeSuggest();
}
//On enregistre la value pour laquelle le traitement a été effectuer pour ne pas le refaire s'il n'y a pas de changement
value_suggested = element.value;
} |
La page autocomplete_ajax.php
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
| <?php
$check = array('cartouche_generique' => array('POUR_IMPRIMANTE'));
//Connexion à la base de données
include('identifiants.php');
connexionbdd();
$table = (isset($_GET['table']) ? $_GET['table'] : '');
$field = (isset($_GET['field']) ? $_GET['field'] : '');
$search = (isset($_GET['search']) ? $_GET['search'] : '');
if(isset($check[$table]) && in_array($field, $check[$table])){ //Vérification
if($table && $field && $search){
$search = strtolower(mysql_escape_string($search));
header("content-type: application/xml");
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
echo '<suggests>';
$and_ou_or = 'AND'; //on utilisera AND dans la boucle
$mots = explode(" ", $search); //séparation des mots
$nombre_mots = count ($mots); //comptage du nombre de mots
$valeur_requete = '';
for($nombre_mots_boucle = 0; $nombre_mots_boucle < $nombre_mots; $nombre_mots_boucle++)
//tant que le nombre de mots de la recherche est supérieur à celui de la boucle, on continue en incrémentant à chaque fois le nombre de mots
{
$valeur_requete .= '' . $and_ou_or .' lower(`'.$field.'`) LIKE \'%' . $mots[$nombre_mots_boucle] . '%\''; //modification de la variable $valeur_requete
}
$valeur_requete = ltrim($valeur_requete,$and_ou_or); //suppression de AND ou de OR au début de la boucle
$query = 'SELECT `'.$field.'` FROM `'.$table.'` WHERE '.$valeur_requete.' GROUP BY `'.$field.'`ORDER BY `'.$field.'`';
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
echo ' <suggest>'.$row[$field].'</suggest>';
}
echo '</suggests>';
}
}
else{
die('Requête interdite');
}
?> |
Mon souci se situ essentiellement au niveau du js, je ne sais pas comment récupérer la valeur du select.
Merci d'avance à tous ceux et celles qui pourrons m'aider.