I. Présentation▲
I-A. Un composant autocomplete ?▲
Intégrer un composant XSL d'autocomplétion dans vos applications XMLRAD, tel est l'objectif de ce tutoriel.
Si vous voulez rapidement vous faire une idée concrète du résultat, visitez les démos suivantes : Démos Yahoo Library, ou les exemples ici dans la section IV (-C, -D et -E).
Mais si vous vous attardez sur le code source JavaScript que vous devez manipuler, vous risquez d'être effrayé… Non pas que les killers de Yahoo aient mal codé, mais justement, le niveau en JavaScript est tel qu'un débutant aura du mal à être à l'aise.
J'ai encapsulé cette complexité dans un composant XSL que je vous propose de découvrir. Il n'implémente pas encore la totalité des propriétés et méthodes du composant original, mais évolue régulièrement. À l'inverse certaines fonctionnalités jugées utiles ont été ajoutées. Si vous êtes pressés, allez directement à la section III qui explique pas à pas l'insertion du composant autocomplete.
Nous mettrons en œuvre le composant à travers trois exemples sympathiques :
- le plus simple qui interroge une liste de pays avec la base Training ;
- un peu plus compliqué, on renseigne un champ mail de destinataires ;
- enfin très sympa, une boîte de vérification d'adresse s'appuyant sur les services google maps.
I-B. La Yahoo Lib▲
Le framework JavaScript de Yahoo (http://developer.yahoo.com/yui/) a mes faveurs depuis un bout de temps déjà, pour les raisons suivantes :
- c'est un des seuls à être bien documenté et fourni avec des exemples (même si on aimerait toujours plus d'exemples !) ;
- il est relativement facile à intégrer dans une application ;
- il est open source ;
- Yahoo étant utilisateur de son propre framework, c'est plutôt rassurant pour les corrections et évolutions à venir. ;
- la YUILib a donné lieu à une déclinaison sous la forme d'un autre projet particulièrement bluffant : Ext.js anciennement nommé la YUI-Ext.
I-C. Prérequis▲
Si vous suivez pas à pas ce tutoriel, il n'y a aucune raison pour que vous ne puissiez obtenir les mêmes résultats !
Maintenant si vous souhaitez comprendre les fondations, vous devrez avoir un minimum de connaissances en XSL et une pratique assez régulière de l'environnement XMLRAD.
Pour ce qui concerne JavaScript, aucune inquiétude sauf si vous êtes un technicien curieux qui cherche à comprendre les sources de la Yahoo Lib… Là vous aurez besoin d'un level JEDI :-)
II. Architecture▲
La lecture de cette section n'est pas obligatoire pour la mise en œuvre du composant, mais il est intéressant de comprendre comment le composant Autocomplete de Yahoo fonctionne.
On peut découper le processus en six étapes :
- La zone d'édition intégrant une détection à la saisie ;
- Une fois un délai imparti après le dernier caractère saisi, déclenchement de la recherche ;
- L'invocation d'une action http afin de récupérer un résultat ;
- La production d'un résultat (XML) par un processus externe ;
- La mise en forme de ce résultat sous forme de liste ;
- L'action à entreprendre lorsqu'un des résultats est sélectionné.
II-A. Diagramme de séquence▲
La mise en œuvre de ces étapes implique une connaissance avancée du JavaScript, heureusement implémentée par la librairie YUI.
Le diagramme de séquence qui suit expose le fonctionnement du composant :
III. Mise en œuvre du composant XSL Autocomplete▲
Le composant XSL est écrit dans un fichier nommé yui.xsl (qui a vocation à intégrer d'autres composants de la YUI Lib).
L'utilisation du composant XSL Autocomplete dans un XMLService requiert quatre étapes :
- La déclaration du namespace yui dans le XSL et l'inclusion de la feuille de style du composant : yui.xsl ;
- L'ajout des headers JavaScript ;
- L'insertion à l'endroit désiré du composant XSL (<xsl:call-template name=« yui:Autocomplete »>) ;
- L'écriture du XMLService qui va produire les données de réponse à la saisie.
III-A. Déclaration du namespace yui▲
Nous déclarons le namespace yui en tête de fichier xsl : xmlns:yui=« http://developer.yahoo.com/yui/ »
Puis nous importons la librairie yui.xsl dans une WebForm :
<
xsl
:
stylesheet
version
=
"1.0"
xmlns
:
xsl
=
"http://www.w3.org/1999/XSL/Transform"
xmlns
:
msxsl
=
"urn:schemas-microsoft-com:xslt"
xmlns
:
xslc
=
"http://xslcomponents.org/TR/WD-xslc"
xmlns
:
yui
=
"http://developer.yahoo.com/yui/"
>
<
xsl
:
import
href
=
"../../xslc.xsl"
/>
<
xsl
:
import
href
=
"../../Common.xsl"
/>
<
xsl
:
import
href
=
"../../yui.xsl"
/>
yui.xsl hors cadre XMLRAD ?
Ceux qui souhaiteraient utiliser yui.xsl hors cadre XMLRAD, ne sont pas obligés d'importer xslc.xsl et Common.xsl qui sont des librairies XMLRAD.
De la même manière, la déclaration des namespaces en tête de feuille de style n'impose strictement que xmlns:yui. Le reste est intrinsèquement lié à votre application.
Aussi, un seul répertoire virtuel est utilisé pour les fichiers JavaScript nécessaires : /SharedPortal/js.
Enfin si vous n'utilisez pas un XMLService pour les données de réponse à l'autocomplétion, alors la contrainte de votre service personnalisé reste de fournir une réponse au format XML.
III-B. Ajout des headers JavaScript▲
Les fichiers JavaScript utilisés par le composant proviennent de la lib Yahoo :
- yahoo.js
- dom.js
- event.js
- connection
- animation.js
- autocomplete.js
La librairie yui.xsl offre un template qui permet d'inclure les fichiers JavaScript nécessaires à l'exécution du composant Autocomplete.
Il suffit d'invoquer le template de cette façon :
<
xsl
:
template
match
=
"document"
>
<
xsl
:
call-template
name
=
"xslc:Page"
>
<
xsl
:
with-param
name
=
"Head"
>
<
xsl
:
call-template
name
=
"yui:AutoComplete.Head"
/>
</
xsl
:
with-param>
Le template yui:AutoComplete.Head va générer les liens de type :
<
script language=
"JavaScript"
src=
"/SharedPortal/yui_2.2.0/yahoo/yahoo-min.js"
xmlns
:
yui=
"http://developer.yahoo.com/yui/"
></
script>
III-C. Insertion du composant XSL▲
Nous allons maintenant insérer le composant XSL à l'endroit désiré de la feuille de style. Nous choisirons de le placer en tête du paramètre Body xsl:with-param name=« Body » (Template xsl:Page).
Portez votre attention sur l'invocation du template nommé : <xsl:call-template name=« yui:AutoComplete »>
<
xsl
:
template
match
=
"document"
>
<
xsl
:
call-template
name
=
"xslc:Page"
>
<
xsl
:
with-param
name
=
"Body"
>
<
xsl
:
call-template
name
=
"yui:AutoComplete"
>
<
xsl
:
with-param
name
=
"Name"
>
InputSearchCountry</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"InputAttributes"
><Attributes
size
=
"20"
/></
xsl
:
with-param>
<
xsl
:
with-param
name
=
"UseShadow"
>
true</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"DatasXMLServiceName"
>
DataSearchCOUNTRY</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultRecordName"
>
COUNTRY</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultFields"
>
<Field>
<Name>
COUNTRY_NAME</Name>
</Field>
<Field>
<Name>
COUNTRY_ID</Name>
</Field>
<Field>
<Name>
COUNTRY_POPULATION</Name>
</Field>
</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"TemplateResult"
>
<span
style
=
"color:blue"
><FieldName>
COUNTRY_NAME</FieldName></span>
<span
style
=
"color:purple"
>
(<FieldName>
COUNTRY_POPULATION</FieldName>
)</span>
</
xsl
:
with-param>
<!-- param name="TemplateResult" -->
...
</
xsl
:
call-template>
...
...
</
xsl
:
with-param>
<!-- Body -->
...
...
</
xsl
:
call-template>
<!-- xslc:Page -->
...
...
</
xsl
:
template>
Le template est appelé ici avec quelques paramètres :
Nom du paramètre |
Description |
---|---|
Name |
Nom qui sera donné au champ de saisie de l'autocomplete |
InputAttributes |
Attributs supplémentaires du champ de saisie comme la taille, etc. |
DatasXMLServiceName |
Nom du XMLService qui va renvoyer les résultats de la recherche |
ResultRecordName |
Nom de chaque élément XML résultat |
ResultFields |
Nom des champs enfants de ResultRecordName qu'on utilisera à l'affichage |
TemplateResult |
Patron visuel html de présentation de chaque ligne résultat. Les champs dynamiques issus de la requête sont insérés à l'aide de la balise <FieldName>. |
Ce template va insérer une zone de saisie (input type="text) dans le flux HTML.
Dès que l'utilisateur va saisir quelques caractères, le navigateur va émettre une requête HTTP joignant notre XMLService, DataSearchCOUNTRY :
Pour rappel, XHR veut dire XMLHttpRequest. Description Wikipedia
Si on regarde le résultat retourné par la requête XHR :
Pour que le composant puisse afficher une liste de résultat, il faut que le XMLService responsable de la production des données existe et… fonctionne :-)
Nous allons donc créer ce service, qui va exécuter une requête SQL recherchant les états comportant le mot clé passé en paramètre. Rappelons que le paramètre s'appelle search.
III-D. Ajout du XMLService fournisseur de données▲
Le composant autocomplete va invoquer un service local évitant ainsi une requête XMLHttp « cross-domain ». Ce service local pourra invoquer des services distants sur Internet (WebServices, RSS, RDF…), récupérer des données dans une base de données voire dans un fichier XML, etc.
Nous implémentons ce service sous la forme d'un XMLService.
Dans la section précédente III-C, nous avons appelé un template nommé avec un paramètre qui nous intéresse particulièrement :
<
xsl
:
with-param
name
=
"DatasXMLServiceName"
>
DataSearchCOUNTRY</
xsl
:
with-param>
C'est le XMLService DataSearchCOUNTRY qui est responsable de la recherche / production des données qui seront affichées dans la liste déroulante de l'autocomplétion.
Parmi les paramètres HTTP que recevra DataSearchCOUNTRY, il y a la valeur qui a été saisie dans le champ input du formulaire : q = « searched value ».
Le XMLGram se contente d'intégrer une XMLInstruction DBExtract : Les résultats seront retournés au format XML par le framework : Ce sont ces résultats que le composant Autocomplete va parser et présenter à l'utilisateur dans une liste déroulante.
Création du XMLService
Nous créons un XMLService de type « XMLGram Only » nommé « DataSearchCOUNTRY ».
Dans le XMLGram, nous débutons par une XMLInstruction Assign qui va récupérer la valeur du paramètre search en l'entourant du caractère %. La donnée SEARCHED_VALUE représentera la valeur à rechercher. Cela nous servira avec la condition SQL LIKE :
Puis nous ajoutons une XMLInstruction DBExtract qui va rechercher les pays dont le nom comporte le mot clé recherché :
Nous essayons à nouveau notre composant, en saisissant « af » dans la zone de saisie.
Firebug nous indique qu'une nouvelle requête XHR a été exécutée. Notre XMLService DataSearchCOUNTRY a été invoqué. Allons voir la réponse retournée par l'application XMLRAD :
Nous constatons que le flux XML retourné a été généré automatiquement par le framework XMLCLX.
Nous avons trois résultats, chacun présenté dans une balise <COUNTRY>.
C'est à ce moment que le composant Autocomplete va parser les réponses et présenter les résultats en suivant le template visuel que nous avons indiqué dans le paramètre TemplateResult :
<
xsl
:
with-param
name
=
"TemplateResult"
>
<span
style
=
"color:blue"
><FieldName>
COUNTRY_NAME</FieldName></span>
<span
style
=
"color:purple"
>
(<FieldName>
COUNTRY_POPULATION</FieldName>
)</span>
</
xsl
:
with-param>
Ca donne le résultat suivant :
Si on clique sur un des résultats, par exemple « Albania (3100000) », seul le mot « Albania » s'affichera dans la zone de saisie.
Pourquoi ?
Parce que dans le paramètre <ResultFields> du composant XSL, le premier élément <Field> était COUNTRY_NAME. Si vous aviez voulu afficher la population, alors il aurait fallu placer en premier le champ Field dont l'élément NAME est COUNTRY_POPULATION.
Nous verrons cependant plus loin qu'il est possible d'afficher la valeur d'un ou plusieurs champs aux endroits souhaités.
IV. Paramètres du composant▲
IV-A. Présentation▲
Nous allons aller un peu plus loin, car notre composant recèle encore quelques surprises… Et puis surtout, c'est bien drôle d'afficher du texte dans un champ de saisie suite à une sélection combien même bien présentée, mais dans la vraie vie on a souvent des besoins plus sournois !
Par exemple, comment faire pour remplir un ID caché dans un champ hidden lors de la sélection ? Aussi, comment faire pour rechercher des données sur un site externe (RDF, XML, RSS, etc.) ? Ou alors, comment permettre une saisie dans un champ de type area et non plus un input text, de façon à rechercher successivement des adresses email ?
Des exemples, des exemples, etc.
IV-B. Référence paramètres▲
Dans le tableau suivant, est listée la liste des paramètres de la version courante de XSL:Autocomplete :
Nom du paramètre |
Description |
---|---|
Name |
Nom qui sera donné au champ de saisie de l'autocomplete |
InputAttributes |
Attributs supplémentaires du champ de saisie comme la taille, etc. |
InputType |
2 valeurs possibles : input (par défault) ou area. La saisie s'effectuera respectivement dans une zone input type=« text » ou type=« area » |
UseShadow |
Affiche ou non une ombre autour des résultats proposés |
DelimChar |
Caractère séparant le texte affiché et le dernier texte à rechercher, si plusieurs textes se succèdent dans la zone de saisie |
DatasXMLServiceName |
Nom du XMLService qui va renvoyer les résultats de la recherche |
QueryParamName |
Nom du paramètre http qui contiendra la valeur à rechercher, « search » par défaut. |
QueryDelay |
Délai après la dernière saisie de caractères avant exécution de la requête fournisseur de données. (0.5 sec par défaut). |
CustomParam |
Si la requête XHR doit être accompagnée de paramètres constants |
ResultRecordName |
Nom de chaque élément XML résultat |
ResultFields |
Nom des champs enfants de ResultRecordName qu'on utilisera à l'affichage |
TemplateResult |
Patron visuel html de présentation de chaque ligne résultat. Les champs dynamiques issus de la requête sont insérés à l'aide de la balise <FieldName>. |
MaxResultsDisplayed |
Nombre maximal de résultats proposés. 100 par défault. |
ActionOnKeyDown |
Javascript à exécuter lors d'un keydown dans la zone de saisie |
ActionOnSelect |
Javascript à exécuter lorsqu'un résultat est sélectionné |
ActionOnDataReturn |
Javascript à exécuter lorsque les données de recherche sont renvoyées par le proxy fournisseur de données |
ActionOnSelect |
Javascript à exécuter lorsqu'un résultat est sélectionné |
IV-C. Exemple : Mise à jour de champs lors de la sélection▲
Imaginez que vous êtes en train de remplir un formulaire concernant une personne. Vous devez indiquer son pays d'appartenance et pour ce faire, vous décidez de mettre en place un autocomplete.
Lorsque l'utilisateur sélectionnera un pays proposé, le composant devra mettre à jour l'identifiant (Pays_ID) dans un champ caché du formulaire qui provoquera l'insertion ou la mise à jour de la personne.
Il faut déjà prévoir le formulaire :
<form
name
=
"MainForm"
method
=
"POST"
action
=
"{/document/Aliases/YUI_AutocompleteDLL}InsertPERSON"
>
<input
type
=
"hidden"
name
=
"Pays_ID"
id
=
"Pays_ID"
/>
... <!-- autres champs du formulaire -->
Maintenant, nous allons indiquer dans les paramètres du template que le champ Pays_ID doit être mis à jour lors de la sélection (avec la valeur COUNTRY_ID de l'enregistrement respectif).
Vous vous rappelez quand on a énuméré les champs utiles pour le composant Autocomplete, dans le paramètre <ResultFields><Fields>…</Fields></ResultFields> ?
Nous allons faire la même chose avec une légère addition : l'élément SetDomID :
<
xsl
:
with-param
name
=
"ResultFields"
>
<Field>
<Name>
COUNTRY_NAME</Name>
</Field>
<Field>
<Name>
COUNTRY_ID</Name>
<SetDomID>
Pays_ID</SetDomID>
</Field>
<Field>
<Name>
COUNTRY_POPULATION</Name>
<SetDomID>
Pays_Population</SetDomID>
</Field>
</
xsl
:
with-param>
Maintenant, assurons-nous du bon fonctionnement en surveillant la valeur du champ de formulaire Pays_ID quand on sélectionnera un pays.
Pendant qu'on y est, nous afficherons au passage la population du pays sélectionné, dans une balise <span> identifiée par : id = « Pays_Population ».
Juste avant la sélection :
Juste après la sélection :
Très pratique. Malgré tout, une des limites actuelles du composant est qu'il ne sait mettre à jour que des attributs « value » sur un élément identifiable du DOM.
Par exemple, il n'est actuellement pas possible de remplir le contenu d'une balise <span>, car il faudrait dans ce cas modifier la valeur de l'élément enfant innerHTML (ou technique équivalente). C'est à l'étude pour la prochaine version du composant.
<
xsl
:
with-param
name
=
"InputType"
>
textarea</with-param><
xsl
:
with-param
name
=
"InputAttributes"
>
<Attributes
size
=
"20"
style
=
"display:none"
/>
</
xsl
:
with-param>
On peut faire en sorte que la zone d'input soit une text area (pour une liste d'emails par exemple).
On peut également agir sur les attributs de cette zone d'input pour modifier sa taille, couleur, visibilité, etc.
IV-D. Exemple : Saisie multiple, choix de destinataires email▲
Passons à un autre exemple : Façon GMail, nous allons rechercher et sélectionner successivement plusieurs destinataires email.
Nous allons avoir besoin d'une surface de saisie plus grande (un textarea…), et que la recherche s'effectue sur une partie du contenu, en l'occurrence le dernier morceau saisi.
Allons-y ! Insérons le code suivant dans un nouveau XMLService, que nous nommerons FormSearchEMAIL :
<
xsl
:
call-template
name
=
"yui:AutoComplete"
>
<
xsl
:
with-param
name
=
"Name"
>
search</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"InputType"
>
textarea</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"InputAttributes"
>
<Attributes
cols
=
"100"
rows
=
"3"
/>
</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"UseShadow"
>
true</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"DelimChar"
>
\n</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"DatasXMLServiceName"
>
DataSearchEMAIL</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultRecordName"
>
EMAIL</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultFields"
>
<Field>
<Name>
PSN_EMAIL</Name>
</Field>
<Field>
<Name>
PSN_FIRST_NAME</Name>
</Field>
<Field>
<Name>
PSN_LAST_NAME</Name>
</Field>
</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"TemplateResult"
>
<div>
<img
src
=
"{$XMLC_PictosPath}button_UnreadEvents.gif"
style
=
"float:left;"
/>
<span
style
=
"color:#376A94;"
><FieldName>
PSN_EMAIL</FieldName></span>
<br/>
<FieldName>
PSN_FIRST_NAME</FieldName>
<FieldName>
PSN_LAST_NAME</FieldName>
</div>
<div
style
=
"height:4px;"
>
</div>
</
xsl
:
with-param>
</
xsl
:
call-template>
De « nouveaux » paramètres font leur apparition :
Paramètre InputType :
<
xsl
:
with-param
name
=
"InputType"
>
textarea</
xsl
:
with-param>
La saisie s'effectuera dans un champ de type textarea !
Paramètre InputAttributes :
<
xsl
:
with-param
name
=
"InputAttributes"
>
<Attributes
cols
=
"100"
rows
=
"3"
/>
</
xsl
:
with-param>
Les attributs de ce champ textarea : 100 colonnes et 3 lignes.
Paramètre DelimChar :
<
xsl
:
with-param
name
=
"DelimChar"
>
\n</
xsl
:
with-param>
Le paramètre DelimChar permet d'indiquer que la recherche des emails s'effectuera sur le texte qui suit le dernier saut de ligne (\n)
Nous créons le XMLService DataSearchEMAIL qui fournira les réponses pour les emails trouvés dans la table PERSON :
Le résultat en image montre combien il a été aisé d'implémenter un bloc de sélection de destinataires.
Dans un de mes projets, au lieu de rechercher les emails dans une base de données, notre proxy recherchait dans un annuaire LDAP… La mécanique côté client est exactement la même. Le proxy qui recherchait dans l'annuaire LDAP se chargeait seulement de formater les résultats au format XML, chaque résultat étant présenté dans une balise <EMAIL>.
IV-E. Exemple : Recherche et vérification d'adresse via la géolocalisation de GoogleMaps▲
Un dernier petit exemple pour la route : Cette fois, la recherche s'effectuera sur un domaine extérieur à l'application.
Comme nous ne pouvons pas accéder directement à un domaine externe avec une requête XHR, nous allons écrire un proxy applicatif local. Ce dernier invoquera lui-même l'API GoogleMaps.
Décrivons succinctement les étapes :
- L'utilisateur saisit un morceau d'adresse dans un champ de saisie ;
- Le composant Autocomplete envoie une requête vers un XMLService local à l'application (XHR locale !) ;
- Ce dernier XMLService invoque en HTTP l'API Google Maps et produit un résultat XML ;
- Le composant Autocomplete présente les résultats ;
- L'utilisateur sélectionne les résultats, et les champs correspondant à l'adresse s'autoalimentent.
Pour rappel, il est obligatoire que la requête XHR s'effectue sur le domaine local de l'application.
C'est pour cela que la plupart des sites mettent en œuvre cette technique de proxy local.
Il semblerait que les choses changent à l'avenir : La fin de l'interdiction d'invocation XMLHttpRequest cross-sites ?
Nous commencerons par écrire le proxy local sous la forme d'un XMLService de type « XMLGram Only ». Puis nous intégrerons et paramétrerons le composant Autocomplete dans la form de recherche.
Écriture du proxy local DataSearchADRESSE :
Ce service doit interroger l'API Google Maps de géolocalisation. Pour ce faire, il faut invoquer l'url http://maps.google.com/maps/geo en passant en paramètre l'adresse recherchée, le paramètre output = xml et la clé GoogleMaps :
Nous créons le XMLGram avec une XMLInstruction HttpInvoke qui se charge d'interroger Google Maps :
Cette instruction HttpInvoke va parser le flux XML retourné par Google Maps, et sélectionner les éléments <Placemark>. Pour chaque élément <Placemark> sera générée une « ligne » de réponse dans le container visuel de l'autocomplete.
Il nous reste à intégrer le composant Autocomplete dans une form, en lui indiquant de rechercher une adresse via le XMLService DataSearchLOCATIONS.
Création du XMLService
À cet effet, nous créons un nouveau XMLService, que nous nommons FormGEOLOC.
Nous insérons notre composant XSL, paramétré pour l'occasion.
Voici l'extrait de code XSL :
<
xsl
:
call-template
name
=
"yui:AutoComplete"
>
<
xsl
:
with-param
name
=
"Name"
>
InputSearchLOCATIONS</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"InputAttributes"
>
<Attributes
size
=
"70"
/>
</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"UseShadow"
>
true</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"DatasXMLServiceName"
>
DataSearchLOCATIONS</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"QueryParamName"
>
q</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"QueryDelay"
>
4</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultRecordName"
>
Placemark</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"ResultFields"
>
<Field>
<Name>
address</Name>
</Field>
<Field>
<Name>
coordinates</Name>
</Field>
<Field>
<Name>
ThoroughfareName</Name>
<SetDomID>
ADRESSE_AFF</SetDomID>
</Field>
<Field>
<Name>
LocalityName</Name>
<SetDomID>
VILLE_AFF</SetDomID>
</Field>
<Field>
<Name>
PostalCodeNumber</Name>
<SetDomID>
CP_AFF</SetDomID>
</Field>
</
xsl
:
with-param>
<
xsl
:
with-param
name
=
"TemplateResult"
>
<table
border
=
"0"
cellpadding
=
"1"
cellspacing
=
"0"
width
=
"100%"
style
=
"margin-bottom:2px;"
>
<tr>
<td><img
src
=
"{$XMLC_PictosPath}OrganizationSmall.gif"
/></td>
<td>
<span
style
=
"color:#376A94;"
>
<FieldName>
address</FieldName>
</span>
</td>
<td>
<span
style
=
"color:#FF567A;"
>
<FieldName>
coordinates</FieldName>
</span>
</td>
</tr>
</table>
</
xsl
:
with-param>
</
xsl
:
call-template>
Des « nouveaux » paramètres font leur apparition :
Paramètre QueryDelay :
<
xsl
:
with-param
name
=
"QueryDelay"
>
4</
xsl
:
with-param>
Il s'agit d'augmenter le délai d'attente avant de lancer une recherche, car la saisie d'une adresse prend un peu de temps :-)
Nous portons cette valeur à quatre secondes.
Paramètre QueryParamName :
<
xsl
:
with-param
name
=
"QueryParamName"
>
q</
xsl
:
with-param>
Par défaut, c'est le paramètre search qui contient la valeur recherchée et transmis avec la requête HTTP.
Nous pouvons changer le nom de ce paramètre, comme ici, où nous l'avons renommé « q ».
Notez que nous retrouvons nos paramètres <SetDomID>.
Dès que nous aurons sélectionné un résultat, les champs de saisie détaillant l'adresse (Adresse, CP, Ville) seront remplis automatiquement.
Nous pouvons découvrir le résultat :
Et quand on sélectionne une adresse, nos champs de saisie sont bien remplis dans la foulée.
Merci Google. Et… merci Yahoo ! (D'ailleurs ils auraient sans doute préféré que je passe par leur API à eux ! C'est hors sujet, mais il faut reconnaître que l'API Google Map présente à mon sens les qualités d'une meilleure intégration dans nos applications web au regard de ses concurrentes (Yahoo, ViaMichelin, etc.). Mais c'est un autre débat…
V. Conclusion▲
V-A. Générales▲
Vous avez pu constater que la mise en œuvre de l'autocomplete en partant de ZÉRO pouvait rebuter plus d'un développeur, même bien documenté sur le site de Yahoo.
Alors, une encapsulation telle que notre composant XSL Autocomplete nous facilite grandement la tâche. Il est vrai que du coup, on ne maîtrise plus trop le fond JavaScript qui est généré. Mais il est très simple d'aller vérifier dans le code source de la page HTML générée. Le code JavaScript relatif à l'autocomplete n'est pas obfusqué et vous comprendrez très vite le travail effectué par le composant, rien de bien obscur.
Il est temps de s'arrêter sur notre dernier exemple de Géolocalisation pour ce tutoriel, j'en ai d'autres sur le bout de la langue, mais autant en garder un peu en exclu pour mes stagiaires (vous aussi vous pouvez le faire ! je veux dire… : Faire partie de mes stagiaires :-)), voire dans quelque temps une partie 2 de ce tuto ?
En effet on pourrait aborder des questions, comme : Comment prendre la main en JavaScript lorsqu'on sélectionne une réponse ? Comment afficher un indicateur visuel d'attente lorsqu'une recherche est en cours ? Comment afficher une belle icône dès que les résultats sont extraits ? etc. J'espère que cela vous aura donné des idées, pour apporter votre contribution voire créer d'autres composants XSL, et surtout apporter vos critiques et questions. Pensez aux forums XMLRAD ou XSL.
V-B. Améliorations▲
Bien que je fournisse les sources avec ce tutoriel, le composant n'est pas encore releasé publiquement. Les raisons sont que j'attends encore des remarques de nouveaux utilisateurs, afin de fixer définivement la grammaire XML, et plus généralement « la philosophie » de la version 1.
Une autre raison est que pendant l'écriture de ce document, YAHOO a publié une nouvelle version de son composant Autocomplete avec des changements qui impactent le composant XSL. Il faut donc que je le modifie en conséquence.
Pas de panique, les sources livrées ici sont accompagnées de la version Yahoo qui lui permet de fonctionner.
Hors l'adaptation à la nouvelle version, les améliorations apportées le seront en fonction de vos remarques et contributions, ainsi des todos en attente.
Par exemple, j'en parlais plus haut, il serait bien que <SetDomID> permettre d'affecter sur sélection, une valeur à tout type de balise, et pas seulement aux balises qui comportent un attribut « value ».
Enfin, il reste à externaliser les css pour permettre un skinnage personnalisé.
V-C. Et les sources… ?▲
Sur un plateau :
Description |
|
---|---|
La librairie Yahoo à décompresser dans \SharedPortal\js |
|
Les sources du projet XMLRAD 2006R1 (IIS / JScript) |