Une des particularités des textbox est de gérer l'autocomplétion. On remarquera deux types de complétions: une sur l'historique de votre navigation dans la barre d'url, et une autre dans les formulaires.
Pour qu'une textbox gère l'autocomplétion, il faut préciser l'attribut type et autocompletesearch:
<textbox type="autocomplete" autocompletesearch="history"/>
Ici, la textbox complétera le contenu de votre textbox en fonction de l'historique. Vous pouvez aussi préciser dans autocompletesearch form-history pour une autocomplétion sur les formulaires.
Pour pouvoir utiliser la fonctionnalité form-history, il faut au préalable activer la péférence "browser.formfill.enable" à 'true' et utiliser l'interface 'nsIFormHistory2' si vous voulez enregistrer des résultats dans l'historique des formulaires. Pour une application xulrunner, il faut ajouter une ligne dans le fichier votreapplication/defaults/preferences/prefs.js :
pref("browser.formfill.enable", true);
exemple :
<?xml version="1.0"?>
<?xml-stylesheet href="[[chrome://global/skin/]]" type="text/css"?>
<window xmlns="[[http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"]]>
<script type="text/javascript">
<![CDATA[
function addEntry()
{
var fhService = Components.classes["@mozilla.org/satchel/form-history;1"].
getService(Components.interfaces.nsIFormHistory2);
fhService.addEntry("myAutocomplete", document.getElementById("myAutocomplete").value);
}
]]>
</script>
<textbox id="myAutocomplete"
type="autocomplete"
autocompletesearch="form-history"
autocompletesearchparam="myAutocomplete" />
<button label="Add Entry" oncommand="addEntry()" />
</window>
Si vous voulez avoir votre propre type d'autocomplétion, il faut implémenter un composant implémentant nsIAutoCompleteSearch dont le contractID est du type: @mozilla.org/autocomplete/search;1?name=Foobar où Foobar est la valeur de l'attribut autocompletesearch.
Nous allons coder un composant XPCom qui permet d'autocompléter sur les jours de la semaine. Si dans la textbox l'utilisateur rentre la chaîne "lu" la textbox devra compléter par "lundi", si la chaîne rentrée par l'utilisateur est "m", alors la textbox proposera "mardi" et "mercredi".
Jetons un coup d'oeil à l'interface qu'il faut implémenter: nsIAutoCompleteSearch.idl
Avant tout, on remarque que nsIAutoCompleteSearch.idl se trouve dans le Toolkit et pas dans XPFE. Donc si vous voulez implémenter ce genre de comportement dans seaMonkey, il faut regarder nsIAutoCompleteSession.
On voit qu'il faut implémenter deux méthodes:
void startSearch(in AString searchString,
in AString searchParam,
in nsIAutoCompleteResult previousResult,
in nsIAutoCompleteObserver listener);
et
void stopSearch();
Le code ressemblera à ça:
//Le constructeur. Première fonction appelée.
function itemAutoCompleteSearch() {
};
itemAutoCompleteSearch.prototype = {
//Méthode appelée quand l'utilisateur rentre une nouvelle lettre dans le textbox.
startSearch: function(searchString, searchParam, previousResult, listener) {
},
//Fonction appelée si l'utilisateur tappe rapidement son texte et ne laisse pas le temps au
//composant de retourner les résultats de l'autocomplétion.
stopSearch: function() {
},
QueryInterface: function(aIID) {
if (!aIID.equals(nsIAutoCompleteSearch) &&
!aIID.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
Donc le coeur du composant se trouvera dans la fonction startSearch. À chaque fois que l'utilisateur rentre une nouvelle lettre, cette fonction est appelée, elle enverra (d'une manière particulière que l'on va voir bientôt) les candidats pour l'autocomplétion.
On remarque le premier argument qui est la chaîne de caratère rentrée par l'utilisateur.
Implémentons donc cette fonction startSearch:
startSearch: function(searchString, searchParam, previousResult, listener) {
var semaine = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"];
var candidats = new Array();
var i;
for each(i in semaine) {
if (i.indexOf(searchString) == 0) {
candidats.push(i);
}
}
},
Donc le tableau candidats contient les jours de la semaine commençant par ce qu'a entré l'utilisateur. Maintenant, il faut renvoyer le résultat à la textbox. Il faut pour cela utiliser le listener passé en argument pour renvoyé le résultat. Son fonctionnement est aussi décrit dans le fichier nsIAutoCompleteSearch.idl.
Il faut donc appeler la méthode:
listener.onSearchResult(search, result);
On doit mettre les candidats pour la complétion en paramètre à cette fonction précédé de l'objet autoSearch. Mais ce résultat n'est pas sous la forme d'un simple tableau, il doit être de la forme: nsIAutoCompleteResult.
C'est à nous d'implémenter cet objet:
readonly attribute AString searchString;
La chaîne de caractère recherchée.
readonly attribute unsigned short searchResult;
L'état de la recherche:
readonly attribute AString errorDescription;
Si il y a une erreur, une string résumant l'erreur.
readonly attribute unsigned long matchCount;
Nombre de résultats.
AString getValueAt(in long index);
Une fonction renvoyant le résultat à un certain index.
AString getCommentAt(in long index);
Si showcommentcolumn (attribut de la textbox) est à true, un commentaire est ajouté à droite du résultat. Pour connaître ce commentaire, cette fonction est appelée.
AString getStyleAt(in long index);
Cette fonction est sensée être utilisée pour connaîte le style (CSS) du résultat, mais elle ne parait pas être exploitée (bien que appelée). Dans l'history et le form-history, ce n'est pas implémenté.
void removeValueAt(in long rowIndex, in boolean removeFromDb);
Est utlisé pour supprimer le résultat de la base de la base d'autocomplétion.
Mettons à jour le code de starSearch:
startSearch: function(searchString, searchParam, previousResult, listener) {
var semaine = ["lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"];
var candidats = new Array();
var i;
for each(i in semaine) {
if (i.indexOf(searchString) == 0) {
candidats.push(i);
}
}
var result = {
QueryInterface: function(aIID) {
if (aIID.equals(nsIAutoCompleteResult) || aIID.equals(nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
results: null,
defaultIndex: 0,
errorDescription: null,
matchCount: 0,
searchResult: Components.interfaces.nsIAutoCompleteResult.RESULT_SUCCESS,
searchString: searchString,
getCommentAt: function(index) {},
getStyleAt: function(index) {},
getValueAt: function(index) {return this.results[index]},
removeValueAt: function(rowIndex, removeFromDb) {}
}
result.results = candidats;
result.matchCount = candidats.length;
listener.onSearchResult(this, result);
}
Code complet du composant: http://xulfr.org/sources/Weeksdays.js
Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.