Kommunauty
Connexion
Inscription

Javascript : permettre les tabulations dans une zone de texte

le 4 aout 2011 • Programmation • par Lucas

Vous en avez marre de marteler la barre d'espace pour indenter un code posté sur votre site ou pour faire des alinéas dans un paragraphe, parce que les textareas ne permettent pas d'utiliser la touche tabulation ?

Alors ce tutoriel va vous expliquer comment utiliser le javascript pour permettre ce type d'action !

Introduction

Comme indiqué plus haut, les textareas ou zone de texte dans un site ne permettent pas d'utiliser la touche "tabulation", sinon quoi la page sélectionne le lien ou le champ de texte suivant, pour plus d'accessibilité.

Mais voilà, comment faire pour utiliser quand même cette touche ?

La solution est... LE JAVASCRIPT !

En effet, au cours de ce tutoriel nous allons voir une technique qui utilise le javascript pour ajouter un alinéa lorsque l'on appuie sur cette touche.

Info : le script réalisé au cours de ce tutoriel est compatible avec tous les navigateurs.

(testé sous safari, firefox et IE, le reste doit techniquement marcher)…

(Si ce n’est pas le cas, ayez la gentillesse de poster un commentaire pour que je vois d’où vient le problème)

Mise en place

Pour ce faire, nous aurons besoin de 2 fichiers :

  • index.html (qui contiendra le formulaire)
  • script.js (qui contiendra le script)

dans index.html, nous pouvons déjà mettre le contenu de la page, en l’occurrence un formulaire avec une zone de texte :

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Tabulations en javascript</title>
    </head>
    <body>
        <form>
            <!-- Une zone de texte -->
            <textarea>

            </textarea>
        </form>
    </body>
</html>

Ensuite, nous allons inclure le script dans la page.

Il faut rajouter cette ligne entre les balises <head></head> d'index.html :

<script type="text/javascript" src="script.js"></script>

Développement

Maintenant que tout est prêt, on peut attaquer la partie la plus intéressante : le code !

Tout d'abord, nous voulons récupérer toutes les zones de texte de la page.

Entrons ceci dans script.js :

var textareas = document.getElementsByTagName("textarea");

Explications :

  • on crée une variable "textareas"
  • on lui applique la valeur de "document.getElementsByTagName("textarea")", fonction qui retourne les éléments de la page en fonction du paramètre passé dans les parenthèses (le nom de la balise)
  • Cette fonction retourne les éléments sous la forme d'un tableau (un Array)

Nous allons tout de suite regarder ce que contient cette variable.

Pour savoir combien d'éléments "textareas" contient, faites :

alert(textareas.length);
  • alert() est une fonction qui affiche un message d'alerte contenant la valeur passée en paramètre.
  • textareas.length retourne un nombre : le nombre d'éléments que contient "textareas".

- Mais, pourquoi ?

Et bien, tout simplement parce que le code Javascript est toujours exécuté au début du chargement de la page, et donc avant que le textarea soit affiché.

Donc nous allons rajouter ceci :

window.onload = function(){
var textareas = document.getElementsByTagName("textarea");
alert(textareas.length);
};

window.onload est appelé quand la page a fini de charger, et on lui applique une fonction. Les codes suivants seront tous à placer à l'intérieur de window.onload.

Et maintenant :

Vous pouvez vous amuser à mettre autant de textareas que vous le souhaitez, ce nombre changera en conséquence.

Nous allons maintenant appliquer des actions à toutes les zones de texte, donc nous allons parcourir le tableau grâce à une boucle for :

for(var i = 0, t = textareas.length; i < t; i++){

}

  • dans la boucle for est créée une variable "i" = 0
  • dans la boucle for est créée une variable "t" = le nombre de textareas
  • tant que "i" < "t", i = i + 1 à chaque fin de boucles.

Nous allons maintenant ajouter un événement aux textareas : la pression d'une touche de clavier :

textareas[i].onkeydown = function(e){
     
};

  • textareas
  • [i] retourne le textarea correspondant au passage de la boucle for

  • onkeydown est l'événement qui se déclenche lors de la pression d'une touche
  • function(e) est la fonction que l'on assigne à l’événement, e est un paramètre qui nous permettra d'obtenir des informations sur l’événement venant de se produire.

Si vous mettez un alert() dans la fonction, vous verrez que le message d'alerte s'affiche bien quand on enfonce une touche, sinon... bah... vous vous êtes trompés dans le code.

Nous voulons récupérer l'id de la touche entrée. Pour cela, nous allons utilisé la paramètre e.

1er problème : Internet Explorer

Comme toujours, IE veut faire le malin en ne passant pas ce paramètre automatiquement.

Donc pour obtenir les infos avec tous les navigateurs Web, il faudra utiliser :

e || window.event;

  • || signifie "OU", donc infos = "e" si il existe et s'il n'est pas vide, sinon infos = "window.event"

Pour récupérer le caractère entré :

(e || window.event).keyCode;

Si vous faites un alert(), quand vous appuyez sur une touche ça retourne un nombre : en fait, toute les touches correspondes à un nombre ASCII. (Voir tous les nombres ici)

Si l'on regarde à la ligne 4 du tableau, on voit que "tab" en ASCII vaut 9.

Donc pour savoir si la touche entrée est la tabulation, nous allons utiliser un boolean : une variable qui vaut true (vrai) ou false (faux).

var tab = (e || window.event).keyCode == 9;

if(tab){ // Si la touche tab est enfoncée
   // le reste du code
}

Puis récupérons le texte de tabulation, avec la fonction fromCharCode() qui prend pour paramètre le code ASCII.

Comme cette fonction appartient à l'objet "String" (chaîne de caractères), nous devons l'appeler comme cela :

var tabString = String.fromCharCode(9);

Le dilemme : IE vs. Opéra vs. Les autres navigateurs

Rogntudju !!

IE se fait encore remarquer en proposant une autre alternative pour récupérer la sélection : infos.

Pour tester si l'utilisateur utilise IE, on pourrait faire :

if(document.selection){

seulement Opéra possède aussi cet objet mais le gère très mal . Il faut donc mettre dans la condition un élément que seul IE gère.

ActiveXObject est une solution.

voici le récapitulatif du code depuis le début :

window.onload = function(){
var textareas = document.getElementsByTagName("textarea");
for(var i = 0, t = textareas.length; i < t; i++){
textareas[i].onkeydown = function(e){
var tab = (e || window.event).keyCode == 9;
if(tab){
var tabString = String.fromCharCode(9);

if(window.ActiveXObject){
// Si Internet Explorer
}
else {
// Sinon
}
}
};
}
};

Récupérer la sélection avec IE

voici les fonctions que nous allons utiliser pour récupérer la position du curseur de texte ou de la sélection :

  • createRange() : Permet de récupérer la sélection sous forme de l'objet TextRange
  • moveStart() : permet de déplacer le début de la sélection (par rapport à la fin de la sélection actuelle)
  • moveEnd() : permet de déplacer la fin de la sélection (par rapport à la fin de la sélection actuelle)
var textR = document.selection.createRange();
var selection = textR.text; // On récupère le texte de la sélection

// On modifie la sélection de manière à ce qu'il y ai la tabulation devant.
textR.text = tabString + selection;

// On déplace la sélection du nombre de caractères de la sélection vers la gauche.
textR.moveStart("character",-selection.length);
textR.moveEnd("character", 0);

// On sélectionne le tout
textR.select();

ATTENTION :

Lorsque la tabulation est insérée dans le texte avec IE, sa taille est irrégulière, car les tabulations dans IE fonctionnent comme des colonnes :

Si le début de la tabulation que l'on ajoute se trouve décalé par rapport à une colonne, IE modifie la taille pour que la fin de la tabulation se termine bien au début de la colonne suivante...

Vous pouvez, dans la partie concernant ce navigateur, changer la valeur de tabString par des espaces :

tabString = "    ";

Le seul inconvénient étant que lorsque l'on veut supprimer la tabulation il faudra quand-même appuyer 4 fois sur la touche "delete".

Récupérer la sélection chez les autres navigateur

L'approche sera un peu plus différente qu'avec IE, car on ne peut pas récupérer directement la sélection (il y a bien «getSelection()» avec Firefox mais ce n’est pas compatible partout). Nous utiliserons les propriétés suivantes :

  • substring() : permet de "couper" une chaine de texte à partir d'un texte jusqu'à un autre texte.
  • textarea.selectionStart : retourne le texte AVANT la sélection
  • textarea.selectionEnd : retourne le texte APRÈS la sélection
  • textarea.setSelectionRange() : permet de modifier la position de la zone de sélection
var beforeSelection = this.value.substring(0, this.selectionStart);
var selection = this.value.substring(this.selectionStart, this.selectionEnd);
var afterSelection = this.value.substring(this.selectionEnd);
               
// On modifie le contenu du textarea
this.value = beforeSelection + tabString + selection + afterSelection;
               
// On modifie la sélection
this.setSelectionRange(beforeSelection.length + tabString.length, beforeSelection.length + tabString.length + selection.length);

Et enfin, après les if et else des navigateurs mais toujours dans le if(tab), nous allons rajouter :

this.focus(); // Met le focus sur le textarea

// Annule l'action de la touche "tabulation". (Empêche de sélectionner le lien suivant)
return false;

Récapitulatif

Voici le code complet sans les commentaires pour les feignasses qui ont la flemme de suivre le tuto jusqu'au bout : (je les comprends, il est - un peu - long et pas toujours très compréhensible)

window.onload = function(){
    var textareas = document.getElementsByTagName("textarea");
    for(var i = 0, t = textareas.length; i < t; i++){
        textareas[i].onkeydown = function(e){
            var tab = (e || window.event).keyCode == 9;
            if(tab){
                var tabString = String.fromCharCode(9);
                
                if(window.ActiveXObject){
                    var textR = document.selection.createRange();
                    var selection = textR.text;
                    textR.text = tabString + selection;
                    textR.moveStart("character",-selection.length);
    textR.moveEnd("character", 0);
                    textR.select();
                }
                else {
                    var beforeSelection = this.value.substring(0, this.selectionStart);
                    var selection = this.value.substring(this.selectionStart, this.selectionEnd);
                    var afterSelection = this.value.substring(this.selectionEnd);
                    this.value = beforeSelection + tabString + selection + afterSelection;
                    this.setSelectionRange(beforeSelection.length + tabString.length, beforeSelection.length + tabString.length + selection.length);
                }                
                this.focus();
                return false;
            }
        };
    }
};

Améliorations

La dernière partie !

Le code est presque terminé mais il subsiste quelque défauts :

  • Quand le texte entré dans le textarea est long et que du coup il y a une barre défilante, à chaque fois que je fais "tab" ça me remonte la barre de scroll de la textarea en haut...
  • Quand on a d'autres scripts utilisant window.onload dans la page, ce script les efface ou alors il ne fonctionne pas

1 - pour résoudre ce problème, au début du if(tab), on stocke le scroll de la textarea :

var scroll = this.scrollTop;

et juste après le this.focus(); on ajoute :

this.scrollTop = scroll;

2 - nous allons modifier le script de manière à ce que ce qui s'exécute ne soit pas appliqué à window.onload mais lui soit "ajouté" en plus de sa valeur d'origine.

On remplace window.onload par une fonction tabulation() :

function tabulation(){
   // LE CODE ICI
}

puis on écrit au début du script :

if(window.addEventListener) // IE
    window.addEventListener("load", tabulation, false);
else // LES AUTRES
    window.attachEvent("onload", tabulation);

Conclusion

Bon, ce tutoriel touche à ça fin.

J'espère vous avoir apporté plus de connaissances en javascript, et si jamais vous avez des questions n'hésitez pas à laisser des commentaires !

Allez, et le code final :

script.js
Fermer ce cadre


if(window.addEventListener)
    window.addEventListener("load", tabulation, false);
else
    window.attachEvent("onload", tabulation);
    
function tabulation(){
    var textareas = document.getElementsByTagName("textarea");
    for(var i = 0, t = textareas.length; i < t; i++){
        textareas[i].onkeydown = function(e){
            var tab = (e || window.event).keyCode == 9;
            if(tab){
                var tabString = String.fromCharCode(9);
                var scroll = this.scrollTop;
                
                if(window.ActiveXObject){
                    var textR = document.selection.createRange();
                    var selection = textR.text;
                    textR.text = tabString + selection;
                    textR.moveStart("character",-selection.length);
    textR.moveEnd("character", 0);
                    textR.select();
                }
                else {
                    var beforeSelection = this.value.substring(0, this.selectionStart);
                    var selection = this.value.substring(this.selectionStart, this.selectionEnd);
                    var afterSelection = this.value.substring(this.selectionEnd);
                    this.value = beforeSelection + tabString + selection + afterSelection;
                    this.setSelectionRange(beforeSelection.length + tabString.length, beforeSelection.length + tabString.length + selection.length);
                }                
                this.focus();
                this.scrollTop = scroll;
                return false;
            }
        };
    }
}

Et n'oubliez pas : nous sommes des rebelles .

  
9 commentaires

Soyons des rebelles, yeah.

*Se garde le tutô sous le coude*

le 4 aout 2011

Pas mal le tutoriel très bien expliqué je garde ça de coté, peut toujours servir .

Merci à toi.

le 4 aout 2011

Bravo , beau tuto

le 4 aout 2011

hu hu... Merci !

le 4 aout 2011

bon, je l'ai pas lu, mais je m'en souvient, c'est vrai que c'est super utile

le 4 aout 2011

J'aime ! Bravo.

le 5 aout 2011

Salut,

Bon tuto mais ne fonctionne pas sous chrome

Cdmt,

Neoblast

le 15 aout 2013

@Lucas : Tu peux t'inspirer d'un script pour comprendre tes erreurs. Ce script fonctionne chez moi

http://code.seebz.net/p/textareatab/

Bonne continuation

Neoblast

le 15 aout 2013

super tuto, il marche nickel, il ma bien aidé, merci beaucoup !

le 7 octobre 2015



Ajoute un commentaire !

Ajouter une image... Trouvée sur internet » De mon PC »
Adresse URL :
Adresse de la page de la vidéo :
Taille du texte :
Couleur du texte :

Article lu 10561 fois.