PCDestroy. Index du Forum
PCDestroy.
Comunauté Informatique & Graphique.
 
PCDestroy. Index du ForumFAQRechercherS’enregistrerConnexion

:: [Tutoriel-Progamation]Insertion de balises dans une zone de texte. ::

 
Poster un nouveau sujet   Répondre au sujet    PCDestroy. Index du Forum -> Informatique. -> Ressources Informatiques
Sujet précédent :: Sujet suivant  
Auteur Message
Lucius
Administrateur

Hors ligne

Inscrit le: 27 Jan 2008
Messages: 362
Masculin XP Métamorphose Firefox
Age: 17

MessagePosté le: Mar 8 Juil - 19:26 (2008)    Sujet du message: [Tutoriel-Progamation]Insertion de balises dans une zone de texte. Répondre en citant

Mise en place du HTML
Tout d'abord, nous allons créer la page HTML qui contiendra le système d'insertion. Voici le code simple :


Code : HTML - Formulaire
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
Code:
<form action="" method="post">
   <div>
      <p>
         <input type="button" value="G" />
         <input type="button" value="I" />
         <input type="button" value="Lien" />
         <input type="button" value="Image" />
         <input type="button" value="Citation" />
         <select onchange="insertTag('<' + this.options[this.selectedIndex].value + '>', '</' + this.options[this.selectedIndex].value + '>');">
            <option value="none" class="selected" selected="selected">Taille</option>
            <option value="ttpetit">Très très petit</option>
            <option value="tpetit">Très petit</option>
            <option value="petit">Petit</option>
            <option value="gros">Gros</option>
            <option value="tgros">Très gros</option>
            <option value="ttgros">Très très gros</option>
         </select>
         <img src="http://users.teledisnet.be/web/mde28256/smiley/smile.gif" alt="smiley" />
         <img src="http://users.teledisnet.be/web/mde28256/smiley/unsure2.gif" alt="smiley" />
      </p>
      <p>
         <input name="previsualisation" type="checkbox" id="previsualisation" value="previsualisation" />
         <label for="previsualisation">Pr&eacute;visualisation automatique</label>
      </p>
   </div>
   <textarea id="textarea" cols="150" rows="10"></textarea>
   <div id="previewDiv"></div>
   <p>
      <input type="button" value="Visualiser" onclick="view('textarea','viewDiv');" />
   </p>
   <div id="viewDiv"></div>

</form>




Donc en gros, comme vous pouvez le voir, le code se compose de différents éléments INPUT qui feront office de boutons pour insérer les balises. Un élément SELECT est aussi présent pour insérer des balises avec des valeurs, comme dans la zForm. Les deux petites images sont des smilies, et réagiront de la même manière que les boutons d'insertion, mais pour insérer des smilies.

J'ai déjà mis une case à cocher pour activer ou non la prévisualisation.
previewDiv et viewDiv seront les deux éléments dans lesquels la prévisualisation et la visualisation seront affichées.

Maintenant que le HTML est en place, commençons le javascriptage.


Le script d'insertion
Le script d'insertion n'est absolument pas compliqué (d'ailleurs, il n'y a rien de compliqué dans ce tuto
).
Je vais créer la fonction insertTag() qui permettra d'insérer une balise autour de la sélection (ou juste le curseur, s'il n'y a pas de sélection).


Code : JavaScript - Fonction insertTag()
Code:
1
2
3
4
5
6
7
Code:
function insertTag(startTag, endTag, textareaId, tagType) {
        var field = document.getElementById(textareaId); // On récupère la zone de texte
        field.focus(); // On remet le focus sur la zone de texte, suivant les navigateurs, on perd le focus en appelant la fonction.
       
        // Reste du code ici ^^
       
}




Les arguments startTag et endTag représentent respectivement la balise d'ouverture et la balise de fermeture. textareaId est l'ID de la zone de texte dans laquelle sera insérée la balise. tagType servira pour après pour les insertions de balises "exotiques", comme les citations, les liens, enfin, pour tout ce qui demande un traitement autre que simplement ajouter une balise d'ouverture et une balise de fermeture.


Maintenant que la fonction principale est définie, on peut créer les appels au sein du code HTML, avec un événement onClick :

Code : HTML
Code:
1
Code:
onclick="insertTag('<balise>','</balise>','textarea');"





Donc, ajoutez cet événement sur les différents éléments cliquables, comme ceci :

Code : HTML
Code:
1
Code:
<input type="button" value="G" onclick="insertTag('<gras>','</gras>','textarea');" />




Comme cela, quand l'utilisateur cliquera sur le bouton G (pour mettre en gras), les balises <gras> et </gras> seront insérées de part et d'autre du curseur, ou de la sélection.

Fonctionnement de la fonction d'insertion

Dans un premier temps, il faut récupérer la portion de texte sélectionnée (la sélection). Ensuite, il faut introduire, de part et d'autre de la sélection les balises. Dans les deux cas, la manière de procéder diffère suivant les navigateurs. Internet Explorer ne gère pas du tout les sélections de la même façon que les autres navigateurs. Enfin, en réalité, IE gère bien la sélection, car il est possible de ne récupérer que la sélection directement, alors qu'avec les autres navigateurs, il faut faire un peu plus d'analyses.


Récupérer la sélection

La première étape de la fonction insertTag() est de récupérer la sélection. Si l'utilisateur n'a rien sélectionné, la sélection est vide (ouais, logique ça
).
Internet Explorer possède son propre système pour récupérer une sélection.


Internet Explorer

Internet Explorer utilise l'objet selection pour manipuler les sélections de texte (pas seulement dans les zones de texte). Le principe est le suivant : on récupère la sélection (on crée un TextRange) avec la méthode createRange(), et on convertit cette sélection en texte pour pouvoir l'utiliser. La méthode createRange() récupère en fait le début et la fin de la sélection, c'est pour cela qu'il faut transformer, avec la propriété text :

Code : JavaScript
Code:
1
2
Code:
var textRange = document.selection.createRange(); // On récupère sous forme de TextRange
var currentSelection = textRange.text;            // On convertit ce TextRange en chaine de caractères




La variable currentSelection contient donc le texte de la sélection.


Les autres navigateurs

La méthode n'est pas du tout la même que pour Internet Explorer. Ici, il faut récupérer la position du début de la sélection, ainsi que la fin, et récupérer "manuellement" la sélection courante. Pour trouver le début et la fin de la sélection, on doit utiliser respectivement les propriétés selectionStart et selectionEnd :


Code : JavaScript
Code:
1
2
3
Code:
var startSelection   = field.value.substring(0, field.selectionStart);
var currentSelection = field.value.substring(field.selectionStart, field.selectionEnd);
var endSelection     = field.value.substring(field.selectionEnd);





Remarquez que field intervient ici, car les propriétés doivent s'appliquer sur l'objet considéré (le textarea), au contraire d'IE qui récupère une sélection n'importe où dans la page !



Mais en fait, quelle était l'utilité de récupérer la sélection ?


Bah c'est assez simple en fait : ça permet de savoir où se trouve le curseur (le curseur est en fait une sélection dont le début est égal à la fin, elle est nulle). Et en connaissant ça, on va pouvoir injecter les balises avant et après... De plus, on pourra agir et analyser le texte sélectionné pour faire des insertions spéciales, comme des liens ou des citations.

Réintroduire les balises

Ici encore, les méthodes pour les deux navigateurs sont différentes.

Internet Explorer

On continue avec l'objetselection ! On va reprendre la variable textRange et modifier son contenu. La sélection dans le champ de texte est alors "mise à jour" :

Code : JavaScript
Code:
1
Code:
textRange.text = startTag + currentSelection + endTag;




En théorie, tout fonctionne. Mais en pratique, il y a quelque chose d'embêtant : le curseur d'écriture : il n'est plus dans le champ ! Ce qu'on veut arriver à faire, c'est resélectionner ce qui se trouve entre les balises fraîchement insérées. Ainsi par exemple, réinsérer une nouvelle paire de balises sans devoir resélectionner.

Internet Explorer offre 3 méthodes permettant d'agir sur une sélection : move() moveStart() et moveEnd().

  • move() sert à déplacer la sélection complète. On ne va pas l'utiliser, mais elle peut être utile ;
  • moveStart() sert à déplacer le début de la sélection ;
  • moveEnd() sert donc à déplacer la fin de la sélection.


Voici comment effectuer ces déplacements :

Code : JavaScript
Code:
1
2
Code:
textRange.moveStart("character", -endTag.length - currentSelection.length);
textRange.moveEnd("character", -endTag.length);




Les méthodes move(sUnit, iCount) prennent deux arguments : sUnit et iCount. sUnit est un peu spécial : c'est la manière de déplacer la sélection. En indiquant character on indique qu'on veut déplacer lettre par lettre. D'autres valeurs sont acceptées comme word ou sentence. iCount, c'est tout simplement la grandeur du déplacement.

Dans le cas du moveStart(), iCount vaudra la longueur de la balise de fin (endTag) plus la longueur de la sélection. C'est présenté sous la forme d'une soustraction car on recule le début de la sélection.


Dans le cas du moveEnd(), iCount vaudra juste la longueur de endTag, toujours en négatif.

Pour terminer, on applique la méthode select() à notre TextRange pour remplacer sélectionner.


Code : JavaScript
Code:
1
Code:
textRange.select();




Les autres navigateurs

Le principe n'est toujours pas le même que pour IE. Ici, nous allons tout simplement remplacer le contenu de la zone de texte par le nouveau contenu comprenant les balises :

Code : JavaScript
Code:
1
2
Code:
field.value = startSelection + startTag + currentSelection + endTag + endSelection;
field.focus(); // On remet le focus sur la zone de texte




Comme avec Internet Explorer, on va redéfinir la sélection. On va utiliser la méthode setSelectionRange(Debut, Fin) que l'on va appliquer sur field.

Cette méthode requiert deux arguments : la position de départ de la sélection, et la position de fin. Pas besoin de deux méthodes comme avec Internet Explorer.


  • La position de départ se calcule en faisant la somme de tout ce qu'il y a avant : startSelection et startTag.
  • Pour la position de fin, on ajoute simplement la longueur de currentSelection.

Code : JavaScript
Code:
1
Code:
field.setSelectionRange(startSelection.length + startTag.length, startSelection.length + startTag.length + currentSelection.length);




Récapitulatif du script

Pour détecter si le navigateur est Internet Explorer, il suffit théoriquement de vérifier s'il gère l'objet document.selection . J'ai bien dit théoriquement, car il y a un petit fauteur de trouble qui est... Opera.

Opera, non content de supporter le JavaScript, supporte aussi le JScript, qui est l'implémentation de Javascript dans Internet Explorer. Les exceptions que nous avons vue précédemment pour IE sont en fait du JScript, qui ajoutait à l'époque des fonctions en plus au Javascript.

Donc, comme Opera gère le JScript, si on fait un document.selection , la valeur retournée sera true .


Mais si Opera gère le JScript, où est le problème ?


Le problème est juste que Opera gère mal le JScript et plus particulièrement le repositionnement du curseur si il n'y a pas de sélection. C'est plutôt gênant. Il faut donc faire en sorte que seul IE utilise les portions de code en Jscript, et pour cela, il suffit de tester si le naviagteur prend en charge ActiveX, que seul IE gère !

Voici donc ce que peut donner le script :

Code : JavaScript
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Code:
function insertTag(startTag, endTag, textareaId, tagType) {
        var field = document.getElementById(textareaId);
        field.focus();
       
        if (window.ActiveXObject) { // C'est IE
                var textRange = document.selection.createRange();           
                var currentSelection = textRange.text;
               
                textRange.text = startTag + currentSelection + endTag;
                textRange.moveStart("character", -endTag.length - currentSelection.length);
                textRange.moveEnd("character", -endTag.length);
                textRange.select();     
        } else { // Ce n'est pas IE
                var startSelection   = field.value.substring(0, field.selectionStart);
                var currentSelection = field.value.substring(field.selectionStart, field.selectionEnd);
                var endSelection     = field.value.substring(field.selectionEnd);
               
                field.value = startSelection + startTag + currentSelection + endTag + endSelection;
                field.focus();
                field.setSelectionRange(startSelection.length + startTag.length, startSelection.length + startTag.length + currentSelection.length);
        }       
}




Et voilà. Le script principal est quasi fini. Il est temps maintenant de l'améliorer pour qu'il puisse gérer les différentes sortes d'insertions (comme les liens, les citations...).

Les insertions spéciales
Ce que je qualifie d'insertions spéciales, ce sont les insertions qui, par exemple, demandent quelque chose à l'utilisateur comme pour l'insertion de liens ou encore de citations...

Le type d'insertion sera renseigné dans l'argument tagType de la fonction insertTag(). Pour garder un script simple, je vais procéder en 3 étapes :


  1. on récupère la sélection ;
  2. on regarde si le tagType est renseigné. S'il ne l'est pas, on ne fait rien ;
  3. on insère le tout.


J'obtiens donc ce code :

Code : JavaScript
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
Code:
function insertTag(startTag, endTag, textareaId, tagType) {
        var field = document.getElementById(textareaId);
        field.focus();
       
        /* === Partie 1 : on récupère la sélection === */
        if (window.ActiveXObject) {
                var textRange = document.selection.createRange();           
                var currentSelection = textRange.text;
        } else {
                var startSelection   = field.value.substring(0, field.selectionStart);
                var currentSelection = field.value.substring(field.selectionStart, field.selectionEnd);
                var endSelection     = field.value.substring(field.selectionEnd);               
        }
       
        /* === Partie 2 : on analyse le tagType === */
        if (tagType) {
                switch (TagType) {
                        case "lien":
                                // Si c'est un lien
                        break;
                        case "citation":
                                // Si c'est une citation
                        break;
                }
        }
       
        /* === Partie 3 : on insère le tout === */
        if (window.ActiveXObject) {
                textRange.text = startTag + currentSelection + endTag;
                textRange.moveStart("character", -endTag.length - currentSelection.length);
                textRange.moveEnd("character", -endTag.length);
                textRange.select();     
        } else {
                field.value = startSelection + startTag + currentSelection + endTag + endSelection;
                field.focus();
                field.setSelectionRange(startSelection.length + startTag.length, startSelection.length + startTag.length + currentSelection.length);
        }       
}




J'utilise un switch(). Ce n'est pas vraiment utile dans mon cas, puisque je n'ai que deux choix et donc un simple if()...else() aurait suffi. Mais le switch sera plus simple à utiliser si vous faites plus de balises spéciales.
Je n'ai pas non plus mis de default. Ce n'est pas utile non plus, puisqu'il n'y a rien à faire si TagType ne correspond pas, et comme c'est vous qui le définissez, je suppose que vous saurez bien le définir.




Mais on aurait très bien pu analyser le TagType et puis récupérer la sélection, non ?


Non, car on va se servir du contenu de CurrentSelection pour déterminer quoi faire avec l'analyse du TagType. Regardez, voici la partie qui s'occupe des liens. En gros, on analyse le CurrentSelection et on réagit en fonction. Le code est commenté et est très simple, c'est surtout une question de logique
:

Code : JavaScript
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Code:
case "lien":
        endTag = "</lien>";
        if (currentSelection) { // Il y a une sélection
                if (currentSelection.indexOf("http://") == 0 || currentSelection.indexOf("https://") == 0 || currentSelection.indexOf("ftp://") == 0 || currentSelection.indexOf("www.") == 0) {
                        // La sélection semble être un lien. On demande alors le libellé
                        var label = prompt("Quel est le libellé du lien ?") || "";
                        startTag = "<lien url=\"" + currentSelection + "\">";
                        currentSelection = label;
                } else {
                        // La sélection n'est pas un lien, donc c'est le libelle. On demande alors l'URL
                        var URL = prompt("Quelle est l'url ?");
                        startTag = "<lien url=\"" + URL + "\">";
                }
        } else { // Pas de sélection, donc on demande l'URL et le libelle
                var URL = prompt("Quelle est l'url ?") || "";
                var label = prompt("Quel est le libellé du lien ?") || "";
                startTag = "<lien url=\"" + URL + "\">";
                currentSelection = label;                     
        }
break;





Mais pourquoi redéfinis-tu currentSelection ?


Bonne question.
Il faut garder à l'esprit que l'insertion se fait avec trois choses : startTag + currentSelection + endTag. Dans le premier if(), je conclus que currentSelection est l'url. Or, l'url se place en attribut dans startTag, et à la place de currentSelection, c'est le libellé qui vient.


Voici, en total bonus, la partie pour analyser une citation :


Code : JavaScript
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Code:
case "citation":
        endTag = "</citation>";
        if (currentSelection) { // Il y a une sélection
                if (currentSelection.length > 30) { // La longueur de la sélection est plus grande que 30. C'est certainement la citation, le pseudo fait rarement 20 caractères
                        var auteur = prompt("Quel est l'auteur de la citation ?") || "";
                        startTag = "<citation nom=\"" + auteur + "\">";
                } else { // On a l'Auteur, on demande la citation
                        var citation = prompt("Quelle est la citation ?") || "";
                        startTag = "<citation nom=\"" + currentSelection + "\">";
                        currentSelection = citation;   
                }
        } else { // Pas de selection, donc on demande l'Auteur et la Citation
                var auteur = prompt("Quel est l'auteur de la citation ?") || "";
                var citation = prompt("Quelle est la citation ?") || "";
                startTag = "<citation nom=\"" + auteur + "\">";
                currentSelection = citation;   
        }
break;




Listes déroulantes et smilies
Les listes déroulantes

Les listes déroulantes sont un bon moyen pour présenter des options sans prendre trop de place, et permet généralement de rassembler plusieurs options ayant le même thème.

Mettre en place une liste déroulante est relativement simple. Il suffit d'appeler insertTag() via l'évènement onChange. Il convient, lors de l'appel de la fonction, de récupérer la valeur de l'option sélectionnée, comme ceci :

Code : JavaScript
Code:
1
Code:
this.options[this.selectedIndex].value;




Voilà donc ce que l'appel de la fonction insertTag() peut donner pour la liste déroulante permettant de choisir la taille :

Code : JavaScript
Code:
1
Code:
insertTag('<taille valeur="' + this.options[this.selectedIndex].value + '">', '</taille>', 'textarea');




Et voici ce que ça donne une fois dans le code HTML :

Code : HTML
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Code:
<select onchange="insertTag('<taille valeur="' + this.options[this.selectedIndex].value + '">', '</taille>', 'textarea');">
   <option value="none" class="selected" selected="selected">Taille</option>
   <option value="ttpetit">Très très petit</option>
   <option value="tpetit">Très petit</option>
   <option value="petit">Petit</option>
   <option value="gros">Gros</option>
   <option value="tgros">Très gros</option>
   <option value="ttgros">Très très gros</option>

</select>




Les smilies

Bah ce n'est pas bien compliqué, il suffit de réutiliser notre fonction insertTag() pour lui faire insérer un smiley et non une balise. Mais attention, vous devez bien faire attention à échapper correctement les caractères qui doivent l'être !

Code : JavaScript - Exemple avec insertTag
Code:
1
Code:
insertTag(':D', '', 'textarea');




Bien évidemment, utilisez l'évènement onClick des éléments IMG pour appeler la fonction :

Code : HTML
Code:
1
2
Code:
<img src="http://users.teledisnet.be/web/mde28256/smiley/smile.gif" alt=":)" onclick="insertTag(':)', '', 'textarea');" />
<img src="http://users.teledisnet.be/web/mde28256/smiley/unsure2.gif" alt=":euh:" onclick="insertTag(':euh:', '', 'textarea');" />




La prévisualisation
Introduction

Faire une prévisualisation en temps réel est assez facile. Il suffit de détecter quand l'utilisateur entre un caractère dans la zone de texte, puis de récupérer le contenu, convertir les balises à coup de regex et afficher le résultat dans un DIV.

Tout bon script de preview (prévisualisation) qui se respecte se doit de demander à l'utilisateur s'il souhaite activer cette prévisualisation. On le fera à l'aide d'une case à cocher, décochée par défaut. J'insiste sur le décochée. Personnellement, je déteste ce genre de truc, et je préfère que ce soit désactivé pas défaut.



Détecter la frappe dans le textarea

Pour cela on va tout simplement utiliser les événements onKeyUp et onSelect dont dispose l'élément textarea. On leur associera la fonction preview(), laquelle comportera un argument textareaId représentant le textarea et un argument previewDiv qui contiendra l'ID de l'élément dans lequel on inscrira le texte prévisualisé. On utilisera this pour définir textareaID, ça nous permettra de ne pas s'embêter avec un getElementById() pour récupérer le contenu du textarea
:


Code : HTML
Code:
1
Code:
<textarea onkeyup="preview(this, 'previewDiv');" onselect="preview(this, 'previewDiv');" id="textarea" cols="150" rows="10"></textarea>




Et voici la déclaration de la fonction :

Code : JavaScript
Code:
1
2
3
Code:
function preview(textareaId, previewDiv) {
    var field = textareaId.value; // Le contenu du textarea est dans la variable field
}




À coups de regex

Pour convertir les balises zCode en balises HTML affichables dans le previewDiv, on va utiliser la méthode replace() qui contiendra une regex.

Voici toute la fonction de prévisualisation. Je ne donne que les regex qui servent à convertir ce que les boutons peuvent insérer (eh oh, j'allais pas tout écrire quand même
) :

Code : JavaScript
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
Code:
function preview(textareaId, previewDiv) {
   var field = textareaId.value;
   if (document.getElementById('previsualisation').checked && field) {
      
      var smiliesName = new Array(':magicien:', ':colere:', ':diable:', ':ange:', ':ninja:', '&gt;_&lt;', ':pirate:', ':zorro:', ':honte:', ':soleil:', ':\'\\(', ':waw:', ':\\)', ':D', ';\\)', ':p', ':lol:', ':euh:', ':\\(', ':o', ':colere2:', 'o_O', '\\^\\^', ':\\-°');
      var smiliesUrl  = new Array('magicien.png', 'angry.gif', 'diable.png', 'ange.png', 'ninja.png', 'pinch.png', 'pirate.png', 'zorro.png', 'rouge.png', 'soleil.png', 'pleure.png', 'waw.png', 'smile.png', 'heureux.png', 'clin.png', 'langue.png', 'rire.gif', 'unsure.gif', 'triste.png', 'huh.png', 'mechant.png', 'blink.gif', 'hihi.png', 'siffle.png');
      var smiliesPath = "http://www.siteduzero.com/Templates/images/smilies/";
   
      field = field.replace(/&/g, '&amp;');
      field = field.replace(/</g, '&lt;').replace(/>/g, '&gt;');
      field = field.replace(/\n/g, '<br />').replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
      
      field = field.replace(/&lt;gras&gt;([\s\S]*?)&lt;\/gras&gt;/g, '<strong>$1</strong>');
      field = field.replace(/&lt;italique&gt;([\s\S]*?)&lt;\/italique&gt;/g, '<em>$1</em>');
      field = field.replace(/&lt;lien&gt;([\s\S]*?)&lt;\/lien&gt;/g, '<a href="$1">$1</a>');
      field = field.replace(/&lt;lien url="([\s\S]*?)"&gt;([\s\S]*?)&lt;\/lien&gt;/g, '<a href="$1" title="$2">$2</a>');
      field = field.replace(/&lt;image&gt;([\s\S]*?)&lt;\/image&gt;/g, '<img src="$1" alt="Image" />');
      field = field.replace(/&lt;citation nom=\"(.*?)\"&gt;([\s\S]*?)&lt;\/citation&gt;/g, '<br /><span class="citation">Citation : $1</span><div class="citation2">$2</div>');
      field = field.replace(/&lt;citation lien=\"(.*?)\"&gt;([\s\S]*?)&lt;\/citation&gt;/g, '<br /><span class="citation"><a href="$1">Citation</a></span><div class="citation2">$2</div>');
      field = field.replace(/&lt;citation nom=\"(.*?)\" lien=\"(.*?)\"&gt;([\s\S]*?)&lt;\/citation&gt;/g, '<br /><span class="citation"><a href="$2">Citation : $1</a></span><div class="citation2">$3</div>');
      field = field.replace(/&lt;citation lien=\"(.*?)\" nom=\"(.*?)\"&gt;([\s\S]*?)&lt;\/citation&gt;/g, '<br /><span class="citation"><a href="$1">Citation : $2</a></span><div class="citation2">$3</div>');
      field = field.replace(/&lt;citation&gt;([\s\S]*?)&lt;\/citation&gt;/g, '<br /><span class="citation">Citation</span><div class="citation2">$1</div>');
      field = field.replace(/&lt;taille valeur=\"(.*?)\"&gt;([\s\S]*?)&lt;\/taille&gt;/g, '<span class="$1">$2</span>');
      
      for (var i=0, c=smiliesName.length; i<c; i++) {
         field = field.replace(new RegExp(" " + smiliesName[i] + " ", "g"), "&nbsp;<img src=\"" + smiliesPath + smiliesUrl[i] + "\" alt=\"" + smiliesUrl[i] + "\" />&nbsp;");
      }
      
      document.getElementById(previewDiv).innerHTML = field;
   }
}




Remarquez, je vérifie avec l'if() si la case à cocher est cochée, et s'il y a quelque chose dans le textarea.

La conversion des smilies est un peu particulière. Un array, smiliesName, contient les noms des smilies. Un autre, smiliesUrl, contient le nom des images (qui correspond bien sûr au nom des smilies du premier array). J'utilise ensuite une boucle for, qui va appliquer une regex pour chaque élément de l'array. Comme j'ai besoin de spécifier une variable au sein de l'expression régulière, je crée cette dernière de façon explicite, avec new Regexp .


Quand toutes les conversions sont faites, on écrit la valeur de field dans le div qui sert à la prévisualisation à l'aide d'innerHTML.

Les regex ici sont relativement simples. Mon but n'est pas de vous apprendre à faire des regex ni même à analyser des portions de texte pour faire un système de prévisualisation qui gère des conversions plus avancées (comme plus de 3 attributs...).

La visualisation finale
Fonctionnement

La création d'une visualisation finale se fait avec AJAX, en exploitant l'objet XMLHttpRequest.

XMLHttpRequest va nous permettre d'envoyer le contenu de la zone de texte vers une page contenant un script PHP. Ce script va convertir le contenu en HTML un peu comme le faisait javascript pour la prévisualisation. Ce contenu est renvoyé par XMLHttpRequest et est affiché dans un DIV. L'intérêt, c'est que tout se fait sans devoir recharger la page.




Mais, quelle est donc l'utilité de ce système ?


Franchement, pour visualiser des balises GRAS et des LIEN, javascript suffit amplement. Le traitement par PHP peut être plus pratique pour par exemple colorer le code, trouver des erreurs d'imbrication de balises...

Par exemple, sur le Site du Zér0, la visualisation finale (via XMLHttpRequest et PHP) permet de visualiser le code coloré, les tableaux, d'avoir une gestion des erreurs, et le convertisseur est plus performant que le convertisseur javascript (car c'est un parseur XML qui est utilisé).

Le script javascript


L'utilisation d'XMLHttpRequest n'est pas l'objet de ce tuto, je ne vais donc pas l'expliquer en profondeur. Mais ne vous inquiétez pas, j'ai aussi rédigé un big-tuto sur les techniques AJAX, dont un très gros chapitre sur XMLHttpRequest, dans lequel tout est expliqué en détail. D'ailleurs, je reprends le même script d'instanciation (parce que c'est le meilleur
).


Voici donc la fonction d'instanciation que j'utilise. Elle sert à définir un objet XMLHttpRequest, suivant les différents navigateurs :


Code : JavaScript
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Code:
function getXMLHttpRequest() {
   var xhr = null;
   
   if (window.XMLHttpRequest || window.ActiveXObject) {
      if (window.ActiveXObject) {
         try {
            xhr = new ActiveXObject("Msxml2.XMLHTTP");
         } catch(e) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
         }
      } else {
         xhr = new XMLHttpRequest();
      }
   } else {
      alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
      return null;
   }
   
   return xhr;
}




Mise en place

Commencez par mettre un événement onClick sur le bouton servant à visualiser, comme ceci :

Code : HTML
Code:
1
Code:
<input type="button" value="Visualiser" onclick="view('textarea', 'viewDiv');" />




Maintenant, il s'agit de créer la fonction pour traiter l'envoi et la réception des données du textarea :

Code : JavaScript
Code:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Code:
function view(textareaId, viewDiv){
   var content = encodeURIComponent(document.getElementById(textareaId).value);
   var xhr = getXMLHttpRequest();
   
   if (xhr && xhr.readyState != 0) {
      xhr.abort();
      delete xhr;
   }
   
   xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && xhr.status == 200){
         document.getElementById(viewDiv).innerHTML = xhr.responseText;
      } else if (xhr.readyState == 3){
         document.getElementById(viewDiv).innerHTML = "<div style=\"text-align: center;\">Chargement en cours...</div>";
      }
   }
   
   xhr.open("POST", "view.php", true);
   xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   xhr.send("string=" + content);
}




La fonction view(), tout comme la fonction preview() reçoit deux arguments : textareaId qui contient l'ID de la zone de texte, et viewDiv qui contient l'ID du DIV dans lequel le code visualisé sera inséré.

La fonction view() se charge donc de récupérer le contenu de la zone de texte et de l'envoyer (en l'ayant préalablement encodé, avec encodeURIComponent) à la page view.php qui contient le script PHP nécessaire pour convertir le code afin qu'il soit visualisé. Le code converti est renvoyé, et réceptionné puis est affiché dans le viewDiv au moyen d'un innerHTML.


La page view.php

La page view.php contient en fait un script simple, quasi identique à celui de la fonction preview(). Pour les besoins du tuto, je n'allais pas utiliser un parseur XML bien compliqué. L'important ici c'est que vous compreniez. Cependant, si vous voulez utiliser un parseur XML, allez voir ce tuto.

Code : 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
Code:
<?php
if (isset($_POST["string"])) {
        $content = $_POST["string"];
        if (get_magic_quotes_gpc()) {
      $content = stripslashes($content);
   }

        $From = array( 
                '`<italique>(.+)</italique>`isU', 
                '`<gras>(.+)</gras>`isU',
                '`<barre>(.+)</barre>`isU',
                '`<lien>(.+)</lien>`isU',
                '`<lien url="(.+)">(.+)</lien>`isU',
                '`<image>(.+)</image>`isU',
                '`<citation>(.+)</citation>`isU',
                '`<citation nom="(.+)">(.+)</citation>`isU',
                '`<citation lien="(.+)">(.+)</citation>`isU',
                '`<taille valeur="(.+)">(.+)</taille>`isU'
        ); 

        $To = array( 
                '<em>$1</em>', 
                '<strong>$1</strong>',
                '<del>$1</del>',
                '<a href="$1">$1</a>',
                '<a href="$1">$2</a>',
                '<img src="$1" alt="Image utilisateur" />',
                '<br /><span class="citation">Citation</span><div class="citation2">$1</div>',
                '<br /><span class="citation">Citation : $1</span><div class="citation2">$2</div>',
                '<br /><span class="citation"><a href="$1">Citation</a></span><div class="citation2">$2</div>',
                '<span class="$1">$2</span>'
        );
 
        $content = preg_replace($From, $To, $content); 
        $content = preg_replace('`\n`isU', '<br />', $content);
        echo $content;
}
?>




Comme vous le voyez, c'est un bête script de conversion avec des regex. Pour plus de simplicité, c'est organisé en deux tableaux.
Le contenu de la zone de texte est récupéré dans la variable $_POST["string"] , exactement comme si on récupérait le contenu d'un formulaire via POST.
Le contenu est converti, et est écrit directement dans la page. C'est ce qui est écrit qui va être récupéré par le code javascript et affiché dans la zone de visualisation.

______________________________________

Couleur Modérateur / Couleur Joueur
Revenir en haut
MSN
Publicité






MessagePosté le: Mar 8 Juil - 19:26 (2008)    Sujet du message: Publicité

PublicitéSupprimer les publicités ?
Revenir en haut
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    PCDestroy. Index du Forum -> Informatique. -> Ressources Informatiques Toutes les heures sont au format GMT + 1 Heure
Page 1 sur 1

 
Sauter vers:  

Index | creer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
WorkStation[electro] © theme by larme d'ange 2006
Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com