Balise de code dans un éditeur de texte.

Résolu
Bonjour à tous,

Étant en train de créer mon forum, qui est encore plutôt basique, voir vide, je me suis dit qu'il pourrait être sympas d'insérer divers balises de mises en forme de style dans mon éditeur de texte qui n'était composé que d'un <textarea>. Ça, j'ai réussi à le faire.

Maintenant j'aimerais mettre un bouton pour ajouter une balise de code, ce que je n'arrive pas à faire. En somme, je voudrais faire comme le bouton "<>" de CCM quoi...

Merci de votre aide !

hcp7kuz

4 réponses

  1. Modérateur
    A ma connaissance, un textarea ne tolère pas la mise en forme, voir plutôt avec une div editable :
    https://www.w3schools.com/tags/att_global_contenteditable.asp
    J'interviens principalement en VB6 et VB.NET, avec un peu de C#, mais la modération m'amène souvent sur d'autre langages.
    En VB.NET pensez à activer "Option Explicit" et "Option Strict"
    0
    1. Merci de ta réponse

      En effet, je crois que j'ai oublié de préciser que j'avais modifié mon <textarea> en <div> (éditable, bien sûr), autant pour moi.

      Mais le problème reste le même, comment ajouter une balise de code autour du texte sélectionné...
      0
  2. Modérateur
    Bonjour,

    Tout est expliqué ici :
    https://openclassrooms.com/courses/insertion-de-balises-dans-une-zone-de-texte

    function insertTag(startTag, endTag, textareaId, tagType) {
            var field  = document.getElementById(textareaId); 
            var scroll = field.scrollTop;
            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);
            } 
            field.scrollTop = scroll;     
    }
    


    Et pour l'associer à un bouton
    <input type="button" value="G" onclick="insertTag('<gras>','</gras>','textarea');" />
    <textarea id="textarea" cols="150" rows="10">ici tu as du texte .. que tu peux selectionner en parti pour y ajouter les balises ..</textarea>
    


    0
    1. Merci ! Ça marche !

      Mais n'y a-t'il pas un moyen de faire la même chose dans un <div> éditable, pour faire un éditeur WISISYG, sauf pour la balise code ?
      0
    2. Modérateur
      @hcp7kuzOui bien sûr..
      Tu modifies simplement la "cible" dans le ONCLICK en pointant sur l'ID de ta div éditable ... ça doit faire la même chose je pense...
      0
  3. Justement, lorsque j'essaie sur un <div> éditable, en modifiant l'id des boutons de style, les balises de mise en forme ne se mettent pas sur le texte sélectionné, ni nul part d'ailleurs.

    Mon code :

    Style :
    <style>
    #div_editeur {
        width: 500px;
        height: 200px;
        border: 1px solid black;
        padding: 5px;
        overflow: auto;
    }
    </style>


    Script JS :
    <script>
    function getSelected() {
     texte = document.getElementById(textareaId).value;
     if (texte == '') {
      return false;
     }
     else {
      return true;
     }
    }
    
    function insertTag(startTag, endTag, textareaId, tagType) {
            var field  = document.getElementById(textareaId); 
            var scroll = field.scrollTop;
            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
                                    var adresse_lien = prompt("Entrez l'adresse du lien :");
            startTag = '<lien adresse="' + adresse_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);
            } 
            field.scrollTop = scroll;     
    }
    </script>



    Code HTML :

    <input class=btn_edit_txt type="button" value="<>" onclick="insertTag('<code>','[/code]','txtbx_rep');" />
    <input class=btn_edit_txt type="button" value="G" style="font-weight: bold;" onclick="insertTag('<gras>','</gras>','txtbx_rep');" />
    <input class=btn_edit_txt type="button" value="I " style="font-style: italic;" onclick="insertTag('<italique>','</italique>','txtbx_rep');" />
    <input class=btn_edit_txt type="button" value="S" style="text-decoration: underline;" onclick="insertTag('<souligne>','</souligne>','txtbx_rep');" />
    <input class=btn_edit_txt type="button" value="Lien" style="text-decoration: underline; color: blue;" onclick="insertTag('<lien>','</lien>','txtbx_rep', 'lien');" /><br />
    <textarea id="txtbx_rep" cols="150" rows="10">Textarea (fonctionne)</textarea>
    
    <br /><br />
    <input class=btn_edit_txt type="button" value="<>" onclick="insertTag('<code>','[/code]','div_editeur');" />
    <input class=btn_edit_txt type="button" value="G" style="font-weight: bold;" onclick="insertTag('<gras>','</gras>','div_editeur');" />
    <input class=btn_edit_txt type="button" value="I " style="font-style: italic;" onclick="insertTag('<italique>','</italique>','div_editeur');" />
    <input class=btn_edit_txt type="button" value="S" style="text-decoration: underline;" onclick="insertTag('<souligne>','</souligne>','div_editeur');" />
    <input class=btn_edit_txt type="button" value="Lien" style="text-decoration: underline; color: blue;" onclick="insertTag('<lien>','</lien>','div_editeur', 'lien');" /><br />
    <div id=div_editeur contenteditable="true">Div éditable (ne fontionne pas)</div>


    Encore merci pour ton aide.
    0
    1. Modérateur
      Sans aller plus loin
      <div id=div_editeur
      

      N'aurais tu pas oublié les quotes autour de l'attribut id ??

      Pour le reste ... regarde dans la console de debug de ton navigateur (pour ça je te conseille d'utiliser Firebug pour FIREFOX )
      si il n'y aurait pas des messages d'erreurs dans le script.
      0
    2. Pour l'id, c'était une erreur d’inattention.

      Lorsque j'appuie sur un bouton de mise en forme destiné au <div>, il me met : "field.value is undefined".
      0
    3. Modérateur
      @hcp7kuz.. sûrement parce qu'une DIV n'a pas d'attribut "value"
      Remplace les .value par .innerHTML
      0
    4. Toujours pas...
      Lorsque je clique sur l'un des boutons de mise en forme, le texte contenu à l’intérieur de celui-ci se répète trois fois.
      0
  4. Je crois que j'ai trouvé !

    Code CSS :
    #div_editeur {
        width: 500px;
        height: 200px;
        border: 1px solid black;
        padding: 5px;
        overflow: auto;
    }


    Code JS :

    function getSelected() {
        if (window.getSelection) {
            return window.getSelection();
        }
        else if (document.getSelection) {
            return document.getSelection();
        }
        else {
            var selection = document.selection && document.selection.createRange();
            if (selection.text) {
                return selection.text;
            }
             return false;
        }
        return false;
    }
    
    function pasteHtmlAtCaret(html) {
        var sel, range;
        if (window.getSelection) {
            // IE9 and non-IE
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                range.deleteContents();
    
                // Range.createContextualFragment() would be useful here but is
                // non-standard and not supported in all browsers (IE9, for one)
                var el = document.createElement("div");
                el.innerHTML = html;
                var frag = document.createDocumentFragment(), node, lastNode;
                while ( (node = el.firstChild) ) {
                    lastNode = frag.appendChild(node);
                }
                range.insertNode(frag);
                
                // Preserve the selection
                if (lastNode) {
                    range = range.cloneRange();
                    range.setStartAfter(lastNode);
                    range.collapse(true);
                    sel.removeAllRanges();
                    sel.addRange(range);
                }
            }
        } else if (document.selection && document.selection.type != "Control") {
            // IE < 9
            document.selection.createRange().pasteHTML(html);
        }
    }
    
    function balise(startTag, endTag, divID, tagType) {
     switch (tagType) {
      case "lien": //si c'est un lien
          var adresse_lien = prompt("Entrez l'adresse du lien :");
             document.getElementById(divID).focus();
             pasteHtmlAtCaret("<a href=" + adresse_lien + " rel="nofollow noopener noreferrer" target="_blank">" + getSelected() + endTag);
       break;
      default: //sinon :
             document.getElementById(divID).focus();
             pasteHtmlAtCaret(startTag + getSelected() + endTag);
       break;
     } 
    }
    


    Code HTML :

    <input type="button" value="<>" onclick="balise('[code]','[/code]','div_editeur');" />
    <input type="button" value="G" style="font-weight: bold;" onclick="balise('<b>','</b>','div_editeur');" />
    <input type="button" value="I" style="font-style: italic;" onclick="balise('<em>','</em>','div_editeur');" />
    <input type="button" value="S" style="text-decoration: underline;" onclick="balise('<u>','</u>','div_editeur');" />
    <input type="button" value="Lien" style="text-decoration: underline; color: blue;" onclick="balise('<a>','</a>','div_editeur', 'lien');" /><br />
    <div id="div_editeur" contenteditable="true">Div éditable</div>


    Sujet résolu : merci pour votre aide ^^
    0