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 : 96096
  • Créé :
  • Créateur : Fredchat
  • Version actuelle ? Non
  • Commentaire /* Suite de la traduction - à reprendre */

Contenu de la révision

{{template.Traduction_en_cours("Using XML Data Islands in Mozilla")}}

Un des dispositif pratique d'Internet Explorer est la capacité à utiliser des îlots de données (ou Data Islands en anglais) pour lier des données aux contrôles HTML d'une page. Cette fonctionnalité n'est pas encore pleinement utilisable dans Mozilla, mais on peut facilement imiter ce comportement pour construire des applications Web multi-navigateur.

L'îlot de données de base que nous allons utiliser est un simple élément XML qui est lié à la page, ou bien codé explicitement dans celle-ci. Dans l'immédiat, illustrons par un exemple simple :

<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 équiper n'importe quel contrôle d'une page en liant simplement l'îlot de données aux contrôles à l'aide de JavaScript et du DOM.

Pour lier ceci, tout ce dont nous avons besoin est une fonction pour manipuler le chargement des contrôles, 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 de l'utilisation des DataIsland XML dans Mozilla ou IE :

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

Le but de cet îlot de données est d'informer le serveur d'applications sur les tableaux auxquelles cette page peut accéder ou demander des informations.

Les contrôles de cette page sont alors liés par l'intermédiaire des attributs personnalisés MXXOBJECT et MXXPROPERTY, plutôt que par les 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 : MXXOBJECT et MXXPROPERTY sont des attributs inventés pour l'article, ils pourraient être n'importe quels autres attributs.

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 passons le XML au serveur, nous pouvons également lui envoyer certaines informations supplémentaires qu'un contrôle particulier pourrait avoir besoins, ou l'avertir à propos des autres contrôles présents dans la page 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>

Ces XMLDataIslands ne fonctionneront pas encore telles quelles. Pour cela, il nous faut 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 de formulaire, tableau, spans, divs, iFrames, et tout ce à quoi vous avez accès via le DOM et un identifiant ID valide)
  2. Construire un gestionnaire pour établir un DOM à envoyer au serveur et analyser la réponse renvoyée aux contrôles.

Tout ce qu'un gestionnaire de contrôle doit faire est d'être capable de faire les mises à jour d'une valeur de contrôle. Cela signifie que toutes les entrées texte peuvent partager un même gestionnaire, en sélectionner un différent, etc. Une façon de faire ça, est de regrouper les contrôles d'un 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 à appliquer au contrôle. Dans ce cas, la valeur nodevalue sera utilisée pour l'attribut control.value. A select could have the options to loop through and create new Options() with or even just replace the node or innerHTML with the new payload.

Voici une page exemple.

Finalement, voici un simple exemple de tableau utilisant les Data Islands XML qui fonctionnera 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 agît comme a regular 2 tier applicationa by providing instant updates and event handling.


Informations sur le document original

Interwiki Languages Links

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

Source de la révision

<p>
{{template.Traduction_en_cours("Using XML Data Islands in Mozilla")}}
</p><p>Un des dispositif pratique d'Internet Explorer est la capacité à utiliser des îlots de données (ou Data Islands en anglais) pour lier des données aux contrôles HTML d'une page. Cette fonctionnalité n'est pas encore pleinement utilisable dans Mozilla, mais on peut facilement imiter ce comportement pour construire des applications Web multi-navigateur.
</p><p>L'îlot de données de base que nous allons utiliser est un simple élément XML qui est lié à la page, ou bien codé explicitement dans celle-ci. Dans l'immédiat, illustrons par un exemple simple :
</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 équiper n'importe quel contrôle d'une page en liant simplement l'îlot de données aux contrôles à l'aide de JavaScript et du DOM.
</p><p>Pour lier ceci, tout ce dont nous avons besoin est une fonction pour manipuler le chargement des contrôles, 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=<i>;</i>
       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 de l'utilisation des <i>DataIsland</i> XML 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 but de cet îlot de données est d'informer le serveur d'applications sur les tableaux auxquelles cette page peut accéder ou demander des informations.
</p><p>Les contrôles de cette page sont alors liés par l'intermédiaire des attributs personnalisés MXXOBJECT et MXXPROPERTY, plutôt que par les 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 : MXXOBJECT et MXXPROPERTY sont des attributs inventés pour l'article, ils pourraient être n'importe quels autres attributs.
</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 passons le XML au serveur, nous pouvons également lui envoyer certaines informations supplémentaires qu'un contrôle particulier pourrait avoir besoins, ou l'avertir à propos des autres contrôles présents dans la page ou dirigés par un contrôle. Ci-dessous, voici un exemples de <i>DataIsland</i> 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>Ces <i>XMLDataIslands</i> ne fonctionneront pas encore telles quelles. Pour cela, il nous faut 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 de formulaire, tableau, spans, divs, iFrames, et tout ce à quoi vous avez accès via le DOM et un identifiant ID valide)
</li><li>Construire un gestionnaire pour établir un DOM à envoyer au serveur et analyser la réponse renvoyée aux contrôles.
</li></ol>
<p>Tout ce qu'un gestionnaire de contrôle doit faire est d'être capable de faire les mises à jour d'une valeur de contrôle. Cela signifie que toutes les entrées texte peuvent partager un même gestionnaire, en sélectionner un différent, etc. Une façon de faire ça, est de regrouper les contrôles d'un 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 à appliquer au contrôle. Dans ce cas, la valeur <code>nodevalue</code> sera utilisée pour l'attribut <code>control.value</code>. <b>A select could have the options to loop through and create new Options() with or even just replace the node or innerHTML with the new payload.</b>
</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">simple exemple de tableau</a> utilisant les <i>Data Islands</i> XML qui fonctionnera 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 agît comme <b>a regular 2 tier applicationa by providing instant updates and event handling</b>.
</p><p><br>
</p>
<div class="originaldocinfo">
<h2 name="Informations_sur_le_document_original"> Informations sur le document original </h2>
<ul><li> Auteur(s) : Thad Hoffman (<a class="external" href="mailto:phiori@mindspring.com">phiori@mindspring.com</a>, <a class="external" href="mailto:phiori@mac.com">phiori@mac.com</a>)
</li><li> Autres contributeurs : Heikki Toivonen (<a class="external" 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="external" href="mailto:phiori@mindspring.com">Thad Hoffman</a>, <a class="external" href="mailto:heikki@netscape.com">Heikki Toivonen</a>
</li></ul>
</div>
<p><span class="comment">Interwiki Languages Links</span>
</p>{{ wiki.languages( { "en": "en/Using_XML_Data_Islands_in_Mozilla" } ) }}
Revenir à cette révision