mozilla

Revision 96099 of Utilisation de Data Islands XML dans Mozilla

  • Raccourci de la révision : Utilisation_de_Data_Islands_XML_dans_Mozilla
  • Titre de la révision : Utilisation de Data Islands XML dans Mozilla
  • ID de la révision : 96099
  • Créé :
  • Créateur : Hsivonen
  • Version actuelle ? Non
  • Commentaire 17 words added
Étiquettes : 

Contenu de la révision

 

Cet article est obsolète. S'il vous plaît voir le nouvel article en anglais.

Une fonctionnalité pratique d'Internet Explorer est la possibilité d'utiliser des îlots de données (Data islands, en anglais) pour lier des données aux contrôles HTML sur une page. Cette fonctionnalité n'est pas intégrée telle quelle dans Mozilla, mais on peut aisément imiter ce comportement pour créer des applications Web multi-navigateurs.

L'îlot de données basique que nous allons utiliser est un élément XML simple, soit lié à la page, soit codé explicitement dans celle-ci. Voici un exemple simple pour illustrer ceci :

<xml id="xmlDataIsland">
   <loaninfo>
       <borrower id="1">
           <firstname>Brian</firstname>
           <middlename>Ellis</middlename>
           <lastname>Johnson</lastname>
       </borrower>
   </loaninfo>
</xml>

Avec cet îlot de données, nous pouvons placer sur une page autant de contrôles que désirés en liant simplement l'îlot de données à ces contrôles à l'aide de JavaScript et du DOM.

Pour lier ceci, tout ce que nous avons besoin de faire est de confier le remplissage des contrôles à une fonction telle que :

function loadFields()
{
   var xmlNode = window.document.getElementsByTagName('xml');
   var borrowerNode = xmlNode[0].childNodes[1];
   if(borrowerNode.hasChildNodes())
   {
       var i = 0;
       var xmlChildNode, nodeVal=;
       while(borrowerNode.childNodes[i])
       {
           // Recherche un nœud
           xmlChildNode = borrowerNode.childNodes[i];
           // Vérifie le type de nœud
           if(xmlChildNode.nodeType != 3) // #text == 3
           {
               // Récupère la valeur du nœud (aka texte)
               nodeVal += xmlChildNode.firstChild.nodeValue + ' ';
           }
           i++;
       }
       // Applique la valeur du contrôle au nœud
       window.document.getElementById('txtBorrowerName').value = nodeVal;
   }
}

Exemple 1

Voici un autre exemple d'ilot de données XML utilisable dans Mozilla ou IE :

<xml id="mxxdataisland">
   <mxxdataisland>
       <rowset tagid="DATES"></rowset>
       <rowset tagid="SUBJPRP"></rowset>
       <rowset tagid="PRODUCT"></rowset>
   </mxxdataisland>
</xml>

Le role de cet îlot de données est d'apprendre au serveur d'applications à quels tableaux cette page va accéder.

Les contrôles de cette page sont alors liés au moyen des attributs personnalisés MXXOBJECT et MXXPROPERTY, très semblables aux attributs DATASRC et DATAFLD utilisés par IE. Ceci permet aux données XML retournées d'être analysées et liées ou « attachées » aux contrôles.

Remarque : Les noms MXXOBJECT et MXXPROPERTY ont été créés pour cet article, et peuvent être différents.

Lier les contrôles :

<input
    type="text"
    id="PropertyStAddr1"
    name="PropertyStAddr1"
    style="height:21px;width:302px;text-align:left;"
    maxlength="35"
    class="fldDefault"
    mxxobject="SUBJPRP" mxxproperty="PropertyStAddr1" <-- voici nos balises "d'attache"
>

<input
    type="text"
    class="fldZipCode"
    name="PropertyZip"
    id="PropertyZip"
    size="10"
    style="height:21px;width:69px;"
    mxxobject="SUBJPRP" mxxproperty="PropertyZip" <-- voici nos balises "d'attache"
    mxxxmlnode="xmldef_PropertyZip" <-- this links to a control-level data island
    mxxtype="MXXZipCodeAutoLoadEdit" <-- type personnalisé et optionnel pour manipuler les contrôles
>

Comme nous envoyons du XML au serveur, nous pouvons également lui envoyer certaines informations supplémentaires dont un contrôle particulier pourrait avoir besoin, ou lui signaler d'autres contrôles sur la page liés ou dirigés par un contrôle. Ci-dessous, voici un exemples de DataIsland personnalisé pour un type spécifique de contrôle :

<select
    id="PropertyState"
    name="PropertyState"
    style="height:20px;width:48px;"
    class="cmbDefault"
    mxxtype="GFXStateList"
    mxxxmlnode="xmldef_PropertyState"
    mxxobject="GOXSUBJPRP" mxxproperty="PropertyState"
>
</select>

<div style="width:0px; height:0px; visibility:hidden;z-index:1">
    <xml id="xmldef_PropertyState">
        <mxxstatelist>
            <status value="initialize"></status>
            <contenttype value="abbrev"></contenttype>
            <controls>
                <control type="countylist" tagid="PropertyCounty" contenttype="name"
                         valuetype ="name"></control>
            </controls>
        </mxxstatelist>
    </xml>
</div>

Telles quelles, ces XMLDataIslands ne nous sont d'aucune utilité. Il nous faut d'abord accomplir deux choses.

  1. Construire un gestionnaire de contrôle pour gérer les mises à jour et le rendu des différents types de contrôles.
    (Note : Les types de contrôles peuvent être n'importe quoi ; objet formulaire, tableau, spans, divs, iFrames, et tout ce à quoi vous avez accès via le DOM et un ID est valide)
  2. Construire un gestionnaire pour créer un DOM à envoyer au serveur, et transmettre la réponse une fois analysée aux contrôles.

Tout ce qu'un gestionnaire de contrôle doit être capable est de mettre à jour une valeur de contrôle. Cela signifie que tous les TextInputs peuvent partager un même gestionnaire, les selects un autre, etc. Une façon d'y parvenir est de regrouper les contrôles d'une page donnée dans un tableau associatif. Puis, lorsqu'une réponse est retournée, nous pouvons analyser le code XML à l'aide d'un attribut ID pour faire correspondre les données utiles XML avec un contrôle.

<input type="text" id="FirstName" ...>

Exemple de fonction de collection d'objets :

   // Extraction de tous les éléments pour les analyser 
   var tags = window.document.body.getElementsByTagName("*");
   var pPrevElem = null;
   var pNextElem = null;
   for (var i = 0; i < tags.length; i++)
   {
       pHTMLElement = tags[i];

       switch (pHTMLElement.tagName.toLowerCase())
       {
           case "span":
           case "table":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "input":
           case "select":
           case "textarea":
           case "button":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "div":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
       }
   }

La charge XML sortante pourrait être :

<page id="NewUser">
    <formcontrols>
        <control id="FirstName">
            <value />
        </control>
    </formcontrols>
</page>

Le retour sera alors :

<page id="NewUser">
    <formcontrols>
        <control id="FirstName">
            <value>Dennis</value>
        </control>
    </formcontrols>
</page>

L'analyseur prend alors la réponse retournée, la charge dans un DOM XML, et passe chaque nœud au gestionnaire de contrôle approprié.

   processTextControl(control, xmlNode);

Exemple d'analyse XML retournée :

   // parseout to controls
   var formControlNodes = xmlDoc.getElementsByTagName('formcontrols');
   for(i=0; i<formControlNodes.length;++i)
   {
       var pFormControlNode = formControlNodes[i];
       var pPageObject = m_MXXPageObjectsArray[pFormControlNode.getAttribute('id')];
       if(!pPageObject)
           continue;
       processTextControl(pPageObject, pBoundControlNode);
   }

Le gestionnaire de contrôles va alors extraire les données nécessaires pour remplir le contrôle. Dans ce cas, la valeur nodevalue sera utilisée pour l'attribut control.value. Un Select pourrait créer de nouvelles Options() avec ces données, ou même remplacer le noeud ou le HTML par les nouvelles données.

Voici une page exemple.

Finalement, voici un exemple simple de tableau utilisant les Data Islands XML qui fonctionne dans IE6 et dans Mozilla.

Pour que tout ce qui est décrit ci-dessus fonctionne, il nous faut envoyer cette information au serveur. Il y a plusieurs moyens, dont ASP, JSP et CGI. J'utilise XMLHTTP car il me permet de mettre à jour la page sans avoir à la recharger, qu'il permet aux contrôles de mettre à jour d'autres contrôles et qu'il agit comme une application 2-tiers classique en fournissant des mises à jour instantanées et la gestion des évènements.

 

Informations sur le document original

Liens Interwikis

{{ languages( { "en": "en/Using_XML_Data_Islands_in_Mozilla" } ) }}

Source de la révision

<p> </p>
<p><span id="result_box" lang="fr"><span class="hps" title="Click for alternate translations">Cet article</span> <span class="hps" title="Click for alternate translations">est</span> <span class="hps" title="Click for alternate translations">obsolète</span><span title="Click for alternate translations">.</span> <span class="hps" title="Click for alternate translations">S'il vous plaît</span> <span class="hps" title="Click for alternate translations">voir</span> <a href="/en/Using_XML_Data_Islands_in_Mozilla" title="en/Using XML Data Islands in Mozilla"><span class="hps" title="Click for alternate translations">le</span> <span class="hps" title="Click for alternate translations">nouvel article</span> <span class="hps" title="Click for alternate translations">en anglais</span></a><span title="Click for alternate translations">.</span></span></p>
<p>Une fonctionnalité pratique d'Internet Explorer est la possibilité d'utiliser des îlots de données (Data islands, en anglais) pour lier des données aux contrôles HTML sur une page. Cette fonctionnalité n'est pas intégrée telle quelle dans Mozilla, mais on peut aisément imiter ce comportement pour créer des applications Web multi-navigateurs.</p>
<p>L'îlot de données basique que nous allons utiliser est un élément XML simple, soit lié à la page, soit codé explicitement dans celle-ci. Voici un exemple simple pour illustrer ceci :</p>
<pre class="eval">&lt;xml id="xmlDataIsland"&gt;
   &lt;loaninfo&gt;
       &lt;borrower id="1"&gt;
           &lt;firstname&gt;Brian&lt;/firstname&gt;
           &lt;middlename&gt;Ellis&lt;/middlename&gt;
           &lt;lastname&gt;Johnson&lt;/lastname&gt;
       &lt;/borrower&gt;
   &lt;/loaninfo&gt;
&lt;/xml&gt;
</pre>
<p>Avec cet îlot de données, nous pouvons placer sur une page autant de contrôles que désirés en liant simplement l'îlot de données à ces contrôles à l'aide de JavaScript et du DOM.</p>
<p>Pour lier ceci, tout ce que nous avons besoin de faire est de confier le remplissage des contrôles à une fonction telle que :</p>
<pre class="eval">function loadFields()
{
   var xmlNode = window.document.getElementsByTagName('xml');
   var borrowerNode = xmlNode[0].childNodes[1];
   if(borrowerNode.hasChildNodes())
   {
       var i = 0;
       var xmlChildNode, nodeVal=<em>;</em>
       while(borrowerNode.childNodes[i])
       {
           // Recherche un nœud
           xmlChildNode = borrowerNode.childNodes[i];
           // Vérifie le type de nœud
           if(xmlChildNode.nodeType != 3) // #text == 3
           {
               // Récupère la valeur du nœud (aka texte)
               nodeVal += xmlChildNode.firstChild.nodeValue + ' ';
           }
           i++;
       }
       // Applique la valeur du contrôle au nœud
       window.document.getElementById('txtBorrowerName').value = nodeVal;
   }
}
</pre>
<p><a class="external" href="http://www.mozilla.org/xmlextras/xmldataislands/example1.html">Exemple 1</a></p>
<p>Voici un autre exemple d'ilot de données XML utilisable dans Mozilla ou IE :</p>
<pre class="eval">&lt;xml id="mxxdataisland"&gt;
   &lt;mxxdataisland&gt;
       &lt;rowset tagid="DATES"&gt;&lt;/rowset&gt;
       &lt;rowset tagid="SUBJPRP"&gt;&lt;/rowset&gt;
       &lt;rowset tagid="PRODUCT"&gt;&lt;/rowset&gt;
   &lt;/mxxdataisland&gt;
&lt;/xml&gt;
</pre>
<p>Le role de cet îlot de données est d'apprendre au serveur d'applications à quels tableaux cette page va accéder.</p>
<p>Les contrôles de cette page sont alors liés au moyen des attributs personnalisés MXXOBJECT et MXXPROPERTY, très semblables aux attributs DATASRC et DATAFLD utilisés par IE. Ceci permet aux données XML retournées d'être analysées et liées ou « attachées » aux contrôles.</p>
<p>Remarque : Les noms MXXOBJECT et MXXPROPERTY ont été créés pour cet article, et peuvent être différents.</p>
<p>Lier les contrôles :</p>
<pre class="eval">&lt;input
    type="text"
    id="PropertyStAddr1"
    name="PropertyStAddr1"
    style="height:21px;width:302px;text-align:left;"
    maxlength="35"
    class="fldDefault"
    <span style="color: #CC0000;">mxxobject="SUBJPRP" mxxproperty="PropertyStAddr1"</span> &lt;-- voici nos balises "d'attache"
&gt;

&lt;input
    type="text"
    class="fldZipCode"
    name="PropertyZip"
    id="PropertyZip"
    size="10"
    style="height:21px;width:69px;"
    <span style="color: #CC0000;">mxxobject="SUBJPRP" mxxproperty="PropertyZip"</span> &lt;-- voici nos balises "d'attache"
    <span style="color: #CC0000;">mxxxmlnode="xmldef_PropertyZip"</span> &lt;-- this links to a control-level data island
    <span style="color: #CC0000;">mxxtype="MXXZipCodeAutoLoadEdit"</span> &lt;-- type personnalisé et optionnel pour manipuler les contrôles
&gt;
</pre>
<p>Comme nous envoyons du XML au serveur, nous pouvons également lui envoyer certaines informations supplémentaires dont un contrôle particulier pourrait avoir besoin, ou lui signaler d'autres contrôles sur la page liés ou dirigés par un contrôle. Ci-dessous, voici un exemples de <em>DataIsland</em> personnalisé pour un type spécifique de contrôle :</p>
<pre class="eval">&lt;select
    id="PropertyState"
    name="PropertyState"
    style="height:20px;width:48px;"
    class="cmbDefault"
    mxxtype="GFXStateList"
    <span style="color: #CC0000;">mxxxmlnode="xmldef_PropertyState"</span>
    mxxobject="GOXSUBJPRP" mxxproperty="PropertyState"
&gt;
&lt;/select&gt;

&lt;div style="width:0px; height:0px; visibility:hidden;z-index:1"&gt;
    &lt;xml <span style="color: #CC0000;">id="xmldef_PropertyState"</span>&gt;
        &lt;mxxstatelist&gt;
            &lt;status value="initialize"&gt;&lt;/status&gt;
            &lt;contenttype value="abbrev"&gt;&lt;/contenttype&gt;
            &lt;controls&gt;
                &lt;control type="countylist" tagid="PropertyCounty" contenttype="name"
                         valuetype ="name"&gt;&lt;/control&gt;
            &lt;/controls&gt;
        &lt;/mxxstatelist&gt;
    &lt;/xml&gt;
&lt;/div&gt;
</pre>
<p>Telles quelles, ces <em>XMLDataIslands</em> ne nous sont d'aucune utilité. Il nous faut d'abord accomplir deux choses.</p>
<ol> <li>Construire un gestionnaire de contrôle pour gérer les mises à jour et le rendu des différents types de contrôles.<br> (Note : Les types de contrôles peuvent être n'importe quoi ; objet formulaire, tableau, spans, divs, iFrames, et tout ce à quoi vous avez accès via le DOM et un ID est valide)</li> <li>Construire un gestionnaire pour créer un DOM à envoyer au serveur, et transmettre la réponse une fois analysée aux contrôles.</li>
</ol>
<p>Tout ce qu'un gestionnaire de contrôle doit être capable est de mettre à jour une valeur de contrôle. Cela signifie que tous les TextInputs peuvent partager un même gestionnaire, les selects un autre, etc. Une façon d'y parvenir est de regrouper les contrôles d'une page donnée dans un tableau associatif. Puis, lorsqu'une réponse est retournée, nous pouvons analyser le code XML à l'aide d'un attribut ID pour faire correspondre les données utiles XML avec un contrôle.</p>
<pre class="eval">&lt;input type="text" id="FirstName" ...&gt;
</pre>
<p>Exemple de fonction de collection d'objets :</p>
<pre class="eval">   // Extraction de tous les éléments pour les analyser 
   var tags = window.document.body.getElementsByTagName("*");
   var pPrevElem = null;
   var pNextElem = null;
   for (var i = 0; i &lt; tags.length; i++)
   {
       pHTMLElement = tags[i];

       switch (pHTMLElement.tagName.toLowerCase())
       {
           case "span":
           case "table":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "input":
           case "select":
           case "textarea":
           case "button":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
           case "div":
               // this indexes by controlID and stores the elementObject
               m_MXXPageObjectsArray[pHTMLElement.id] = pHTMLElement;
               break;
       }
   }
</pre>
<p>La charge XML sortante pourrait être :</p>
<pre class="eval">&lt;page id="NewUser"&gt;
    &lt;formcontrols&gt;
        &lt;control id="FirstName"&gt;
            &lt;value /&gt;
        &lt;/control&gt;
    &lt;/formcontrols&gt;
&lt;/page&gt;
</pre>
<p>Le retour sera alors :</p>
<pre class="eval">&lt;page id="NewUser"&gt;
    &lt;formcontrols&gt;
        &lt;control id="FirstName"&gt;
            &lt;value&gt;Dennis&lt;/value&gt;
        &lt;/control&gt;
    &lt;/formcontrols&gt;
&lt;/page&gt;
</pre>
<p>L'analyseur prend alors la réponse retournée, la charge dans un DOM XML, et passe chaque nœud au gestionnaire de contrôle approprié.</p>
<pre class="eval">   processTextControl(control, xmlNode);
</pre>
<p>Exemple d'analyse XML retournée :</p>
<pre class="eval">   // parseout to controls
   var formControlNodes = xmlDoc.getElementsByTagName('formcontrols');
   for(i=0; i&lt;formControlNodes.length;++i)
   {
       var pFormControlNode = formControlNodes[i];
       var pPageObject = m_MXXPageObjectsArray[pFormControlNode.getAttribute('id')];
       if(!pPageObject)
           continue;
       processTextControl(pPageObject, pBoundControlNode);
   }
</pre>
<p>Le gestionnaire de contrôles va alors extraire les données nécessaires pour remplir le contrôle. Dans ce cas, la valeur <code>nodevalue</code> sera utilisée pour l'attribut <code>control.value</code>. Un Select pourrait créer de nouvelles Options() avec ces données, ou même remplacer le noeud ou le HTML par les nouvelles données.</p>
<p><a class="external" href="http://www.mozilla.org/xmlextras/xmldataislands/MXX_Info.html">Voici une page exemple.</a></p>
<p>Finalement, voici un <a class="external" href="http://www.mozilla.org/xmlextras/xmldataislands/table.html">exemple simple de tableau</a> utilisant les <em>Data Islands</em> XML qui fonctionne dans IE6 et dans Mozilla.</p>
<p>Pour que tout ce qui est décrit ci-dessus fonctionne, il nous faut envoyer cette information au serveur. Il y a plusieurs moyens, dont ASP, JSP et CGI. J'utilise XMLHTTP car il me permet de mettre à jour la page sans avoir à la recharger, qu'il permet aux contrôles de mettre à jour d'autres contrôles et qu'il agit comme une application 2-tiers classique en fournissant des mises à jour instantanées et la gestion des évènements.</p>
<p> </p>
<div class="originaldocinfo">
<h2 id="Informations_sur_le_document_original" name="Informations_sur_le_document_original">Informations sur le document original</h2>
<ul> <li>Auteur(s) : Thad Hoffman (<a class="link-mailto" href="mailto:phiori@mindspring.com">phiori@mindspring.com</a>, <a class="link-mailto" href="mailto:phiori@mac.com">phiori@mac.com</a>)</li> <li>Autres contributeurs : Heikki Toivonen (<a class="link-mailto" href="mailto:heikki@netscape.com">heikki@netscape.com</a>)</li> <li>Dernière mise à jour : 21 juin 2005</li> <li>Copyright : Copyright (C) <a class="link-mailto" href="mailto:phiori@mindspring.com">Thad Hoffman</a>, <a class="link-mailto" href="mailto:heikki@netscape.com">Heikki Toivonen</a></li>
</ul>
</div>
<p><span class="comment">Liens Interwikis</span></p>
<p>{{ languages( { "en": "en/Using_XML_Data_Islands_in_Mozilla" } ) }}</p>
Revenir à cette révision