Bonjour,

Voilà pour une utilisation priver entre admin, je souhaite intégrer sur mon site (panel) un genre de framapad sauf que je souhaite le dev moi même :)
Donc, j'ai commencé par faire un début de code et donc faire quelque teste et plus tard rajouté de plus en plus :D

Actuellement mon code :

<body>
        <div style="width:250px;border:1px black
    solid;font-family:Courier;" class="editeur" CONTENTEDITABLE>
            Blabla, blabla.<BR>
            Bla <B>bla</B> bla.
        </div>
        <div class="result"></div>
        <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
        <script>
            $(function(){

                $('.editeur').keyup(function () {
                    $str = $(this).text();
                    //$('.editeur').empty();

                    $format_search =  [
                        /<strong>(.*?)<\/strong>/ig,
                        /<italic>(.*?)<\/italic>/ig,
                        /<underline>(.*?)<\/underline>/ig,
                        /<line-through>(.*?)<\/line-through>/ig
                    ];

                    $format_replace = [
                        boldFunc,
                        italicFunc,
                        underlinedFunc,
                        line_throughFunc
                    ];

                    for (var i =0;i<$format_search.length;i++) {
                        $str = $str.replace($format_search[i], $format_replace[i]);
                    }

                    $('.editeur').clone().empty().append($str);
                });

                function boldFunc(str, p1) {
                    return '<strong>'+p1+'</strong>'
                }

                function italicFunc(str, p1) {
                    return '<em>'+p1+'</em>'
                }

                function underlinedFunc(str, p1) {
                    return '<span style="text-decoration:underline;">'+p1+'</span>'
                }

                function line_throughFunc(str, p1){
                    return '<span style="text-decoration:line-through;">'+p1+'</span>'
                }
            });
        </script>
    </body>

Le problème actuel, je voudrais si on colle ou si on est <strong></strong> que la chaîne de caractère soit aussitot convertie, car j'avais fait dans une div (.result) et sa convertie bien sauf que je voudrais pouvoir appliquer dans la div directement (.editeur).

Je voudrais faire (plus tard), mais si vosu pouvez me conseiller un truc :) Le truc que je selectionne le texte et je clique sur une icone pour faire le format du texte directement :D

Merci de votre aide ;)

Cordialement;

EDIT : Concernant le code : $('.result').clone().empty().append($str); ne fonctionne pas et je ne vois pas trop comment fire, car avant je utiliser empty, sauf que dans la div où j'écrit si je fait empty() sa m'enpeche décrire où je souhaite...

20 réponses


Salut !
Pour ton premier souci, tu peux regarder du côté de l'évenement onpaste. Il doit y avoir le texte collé dans l'évenement qui est lancé. Du coup du bloque le collage du presse papier et tu fais ton traitement toi même.

Pour le deuxième point je peux que te donner des pistes je suis pas expert. Il y a des méthodes en javascript mais ces deux liens te donneront ton bonheur :

J'avais essayé de coder un éditeur comme le tien en récupérant la séléction : c'est un enfer...
Regarde du côté de la fonction execCommand en JS qui va te simplifier la vie!
Exemple pour mettre un texte en gras:

 function SetToBold () {
            document.execCommand ('bold', false, null);
        }

Voici une démo que j'ai réussi à faire avec cette fonction, je te laisse inspecter le js ;) http://hugopb82.alwaysdata.net/public/s-office/

Seul bémol (car il y en a un) c'est que les navigateurs n'interprètent pas de la même façon cette fonction. Par exemple lors d'un :

document.execCommand('bold');

Certains navigateurs vont mettre un b, d'autres une span style="font-weight:bold;" ce qui peux poser problème si tu veux contrôler les balises utilisées...
Après vu que c'est un panel d'admin et non ouvert à tous les utilisateurs je suppose que ça va te convenir parfaitement ;)

Hugo

Salut, alors ton code @hugopb82 est sympa, mais comme il est fait en JS pur, je ne sais pas le lire... Car, le JS pur, j'ai vraiement beaucoup de difficulté.

@earhater pour onpaste, j'ai du mal à comprendre car là il font si on fait ctrl+V, donc, si tu peut me montré un exemple :D

@hugopb82 Merci à toi, en plus, il est propre :D

Derien! Testes-le et si cela te convient penses à mettre le sujet en résolu ;)

Bas, là j'essaye de faire le coté sélection, car je voudrais appliquer une couleur quand je sélectionne une partie du texte sur l’icône en question (YOLO), devras afficher un background sur l’icône de l'italic/
Donc, je fait :

selection = $('#rte').getSelection();
            console.log(selection);

Mais, ceci me renvoie une erreur TypeError: $(...).getSelection is not a function
Et j'ai suivie sa : https://developer.mozilla.org/fr/docs/Web/API/Window/getSelection
Après, je cherche plutôt à utiliser des balises au lieux de execCommand, tu serais faire avec se code ? Car, si je rajoute plus de fonctionnalité et c'est pas disponible avec execCommand, je vais bloqué un peu ^^
Bien sûr, j'ai regarder ton source code (du formulaire déjà fait que tu ma envoyé), mais comme c'est du pur js, je n'y arrive pas du tout à me donnée des idées...

EDIT :
Exemple, je souhaite ajouté un icône Défaut, qui à pour but de effacer tout css sur le texte sur la partie sélectionnée.

Je ne comprends pas ton problème: tu souhaites que l'icone bold soit différente si le texte sélectionné est gras?

Oui, sa oui, mais aussi qu'on n'utilise pas .execCommand() car c'est bien mais trop limité pour certaine chose.

Limité!?!?!
Voici la liste des possibilités : http://www.quirksmode.org/dom/execCommand.html
Tu n'est pas limité au gras, italique et souligné, tu peux faire des liens, des images, des tableaux, du texte en couleur....
Tu peux aussi vérifier si une commande est activé grâce à la fonction document.queryCommandEnabled
Les exemples sont simples à comprendre ;)
Hugo

Merci de ta réponse, de même si un moment je n'ai pas la commande avec execCommand, comment je pourrais faire ?
Je vais l'utiliser mais c'ets juste pour en apprendre plus aussi :D

EDIT :
Exemple, je voudrais supprimer tout les effet appliquer sur un texte, comment je peux faire ?
J'avais essayer un truc comme sa :
$('#default').click(function () {
document.execCommand('', false, null); $('#rte').focus();return false;
});
Mais, c’est de la grosse connerie ^^

EDIT :
Je viens de essayer le code pour document.queryCommandEnabled et perso, je ne vois pas trop comment il fonctionne...

EDIT: C'ets bien gentil de m'aider :) Car, je suis pas très habituer au JS, le seul truc de complexe que j'ai crée en JS (jQuery) et le messenger de facebook mobil sur un site.

  • Si tu n'as pas de commande tu fais avec la commande insertHtml et en troisième argument tu mets ton code html correspondant
  • Pour supprimer les styles essaye la commande removeformat (je suis pas sûr)
  • ex: document.queryCommandEnabled('bold') revoie true si le texte sélectionné/sur le curseur est gras et false si non. Tu as juste a faire une condition et si c'est true tu changes le background de ton bouton gras

Pour cela, j'ai essayer de faire $('#rte').select car le but est de selectioner son contenue mais comme, ce n'est pas une input alors j'ai voulue lui faire passer avec un focus, mais sa ne fait rien. Dans la function, il y avait juste un alert pour savoir si il détecter bien si je sélectionner du texte... Si tu a une idée ?

EDIT :
Alors pour removeformat, c'est parfait :)
Par contre, pour insertHtml , je bloque, car j'ai essayer plusieurs code, et même sur google, je ne trouve pas vraiment de sujet ^^

Merci de ton aide :D

Alors, voici un code que j'essaye de faire pour le insertHTML.

$('#boldTEST').click(function () {
                document.execCommand("insertHTML", false, '<strong>'+$('#rte').focus()+'</strong>');
                //$('#rte').focus();
                return false;
            });

Et à partir de la, j'ai bien du gras, mais j'ai : [object Object], donc, j'ai essayer pour savoir se que je selection sans trouvé...
Et pour document.queryCommandEnabled, j'essaye de faire en sorte quand je fait un select, si non il s'execute une fois pas plus.

ça y j'ai compris :)
Tu as besoin de ta fonction pour récupérer le texte selectionné au lieu de faire $('#rte').focus(), focus veut dire qu'on met le curseur dans ton élément, littéralement focus c'est concentrer, faire converger mais en aucun cas cette fonction récupère du texte.
Met ça en haut de ton code :

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
    }
    return text;
}

et tu remplaces ta fonction bold par:

$('#boldTEST').click(function () {
                document.execCommand("insertHTML", false, '<strong>'+getSelectionText()+'</strong>');
                $('#rte').focus();
                return false;
            });

Voila!
Met moi ton code pour queryCommandEnabled car là je ne vois pas encore le problème...

Re-bonjour :D
Bon, grace à ton code sa mas permis de bien avancer :D
J'ai fait un truc de quotes, sauf qu'il contient un span avec une class de bootstrap mais je voudrais pouvoir le retirer, j'ai donc essayer de faire sa :

$('#menuBarDiv a[title="Block Quote"]').click(function(){ queryCommandEnabled(); return false;});

        function SetQuoteDes() {
            if (document.queryCommandEnabled("formatblock")) {
                document.execCommand("insertHTML", false, '<p class="alert alert-info"  >'+getSelectionText()+'</p>'); textarea;
                //document.execCommand ('bold', false, null);
            }
            else {
                /*
                    Supprimer le quote
                */
                //alert ("Please select some content!");
            }
        }

(J'ai changer pas mal de chose dans mon code ^^ )
Ici, le but etait de vérifier si c'ets un formatage par defaut, si oui on applique la quotes sinon on lui retire :D
Mais sa pas trop fonctionner ^^
Par contre, j'ai cette erreur : ReferenceError: queryCommandEnabled is not defined
Donc, tu aurait une petite idée pour le faire, car après avoir plus réfliche, si je suis la logique de mon code si quelqu'un à mis un texte en italic sa vas bloquer ^^
Merci de ton aide :D
EDIT : Par contre, quand je fait entré sa recrée la div de nouveau et je ne vois pas trop comment contourner ceci a par faire un contrôle sur la touche 13, mais je vois pas plus ^^
Après, si je fait shif+enter, c’est parfait sa reste dedans :D

Alors, j'ai essayer de faire se genre de code :

$('#menuBarDiv a[title="Block Quote"]').click(function(){ SetQuoteDes(); return false;});

        function SetQuoteDes() {
            if(getSelectionText().hasClass('alert')){
                //Retirer
            }
            else
            {
                document.execCommand("insertHTML", false, '<p class="alert alert-info"  >'+getSelectionText()+'</p>'); textarea;
            }
        }

Mais sa ne fonctionne pas aussi... As tu une idée ?

Salut, alors j'ai bien avancer :D
Mais, je recherche à faire en sorte de afficher le numéro de ligne sur le coté, tu à une idée car j'ai regarder sur google et j'ai rien trouvé...

salut, tu peux faire un tableaux sur le côté de ta div en contentEditable et qui contient des numéros ...
Après pour tes autres problèmes je ne peux pas te dire... je ne suis pas une bête en JS ;)

Ok, à tu une idée pour faire un truc comme un paste, sauf que c'est avec des caractères spécial.
J'ai fait sa :

$(DivCone+' .Special_Character').click(function () {
        document.execCommand('insertText', false, $(this).text());
        textarea;
    });

Je clique sur le caractères, sauf qu'il ne se met pas à la position du cursor... Merci de ton aide (encore ^^)