IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

React Discussion :

Placer le curseur de la souris dans un input à un indice précis en dehors du callBack avec useRef


Sujet :

React

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut Placer le curseur de la souris dans un input à un indice précis en dehors du callBack avec useRef
    Bonjour tout le monde,

    J'ai un input dans lequel l'utilisateur entre une expression de cette forme :

    "TERM":"MATCH_TERM"

    Je voudrais que lorsque l'utilisateur saisit un guillemet dans l'input, un deuxième guillemet du même type soit ajouté (l'utilisateur peut utiliser des guillemets simples et doubles : " ou ') et que le curseur de la souris soit placé entre les deux guillemets qui viennent d'être créés.

    Mon code est en ReactJs.

    J'ai réussi à ajouter automatiquement un deuxième guillemet lorsque l'utilisateur en saisit un premier, au bon endroit dans la chaîne de caractère. Mais je n'arrive pas à trouver comment déplacer ensuite le curseur de ma souris entre les deux nouveaux guillemets créés.

    Pour que mon composant QuoteInput fasse cela, j'ai écrit le code suivant :

    (j'ai essayé de simplifier le code mais normalement il est reproductible)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    import * as React from "react";
    import { useEffect, useState, useRef } from "react";
     
    const QuoteInput: React.FC = () => {
     
        const inputRef = useRef<HTMLInputElement | null>(null);
     
        const [inputChoose, setInputChoose] = useState("");
        const [previousInputChoose, setPreviousInputChoose] = useState("");
     
        const [testQuoteAddition, setTestQuoteAddition] = useState(false);
        const [enterSingleQuote, setEnterSingleQuote] = useState(false);
        const [enterDoubleQuote, setEnterDoubleQuote] = useState(false);
     
        const inputHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
            setPreviousRequestChoose(requestChoose);
            const enteredRequest = event.target.value;
            setRequestChoose(enteredRequest);
     
            setTestQuoteAddition(true);
        };
     
        function addSingleQuote(indexDifference: number) {
            let newString: string = requestChoose.slice(0,indexDifference + 1) + "'" + requestChoose.slice(indexDifference + 1);
            setRequestChoose(newString);
     
            if(inputRef !== null && inputRef !== undefined) {
                if (inputRef.current !== null && inputRef.current !== undefined) {
                    console.log("3 ");
                    if (inputRef.current.setSelectionRange !== undefined) {
                        inputRef.current.setSelectionRange(indexDifference, indexDifference);
                    }
                }
            }
        }
     
        function addDoubleQuote(indexDifference: number) {
            let newString: string = requestChoose.slice(0,indexDifference + 1) + '"' + requestChoose.slice(indexDifference + 1);
            setRequestChoose(newString);
        }
     
        useEffect(()=>{
            if(testQuoteAddition === true) {
                for(let i=0; i<requestChoose.length; i++) {
                    if(previousRequestChoose.charAt(i) !== requestChoose.charAt(i))
                    {
                        if (requestChoose.charAt(i) === "'") {
                            setEnterSingleQuote(true);
                        } else if (requestChoose.charAt(i) === '"') {
                            setEnterDoubleQuote(true);
                        }
                    }
                }
            }
            setTestQuoteAddition(false);
        },[testQuoteAddition])
     
        useEffect(()=>{
            if(enterSingleQuote === true){
                let indexDifferenceInRequest: number = requestChoose.length + 1;
                let findDifference: boolean = false
                for(let i=0; i<requestChoose.length; i++) {
                    if(previousRequestChoose.charAt(i) !== requestChoose.charAt(i) && findDifference === false)
                    {
                        indexDifferenceInRequest = i;
                        findDifference = true;
                    }
                }
                addSingleQuote(indexDifferenceInRequest);
                setEnterSingleQuote(false);
            } else if (enterDoubleQuote === true){
                let indexDifferenceInRequest: number = requestChoose.length + 1;
                let findDifference: boolean = false
                for(let i=0; i<requestChoose.length; i++) {
                    if(previousRequestChoose.charAt(i) !== requestChoose.charAt(i) && findDifference === false)
                    {
                        indexDifferenceInRequest = i;
                        findDifference = true;
                    }
                }
                addDoubleQuote(indexDifferenceInRequest);
                setEnterDoubleQuote(false);
            }
        },[enterSingleQuote, enterDoubleQuote])
     
        return(
            <div>
                <input ref={inputRef} type="text" onChange={inputHandler} value={inputChoose} className="text-center" placeholder="enter an input" />
            </div>
        );
    }
     
    export default QuoteInput;
    Ce code me permet d'ajouter une nouvelle paire de guillemets mais le curseur de la souris est alors placé à la fin de la chaîne de caractère.

    Si je mets : inputRef.current ?.setSelectionRange(3, 3); dans le inputHandler (la fonction callback de mon élément input), chaque fois que l'utilisateur écrit, le curseur est remis à la troisième position de la chaîne.

    Mais si je mets cette même ligne : inputRef.current ?.setSelectionRange(indexDifference, indexDifference); dans la fonction qui ajoute un deuxième guillemet, comme dans le code ci-dessus, rien ne se passe, alors qu'en mettant console.log dans les if de ma fonction d'ajout de guillemet, il s'affiche bien donc mes conditions sont bien remplies et l'instruction devrait s'exécuter.

    Je ne vois pas du tout ce que je fais de mal, si vous pouviez m'indiquer la bonne direction, cela m'aiderait beaucoup.

    Je viens de remarquer un autre problème avec ma fonction d'ajout de guillemets pendant que j'écrivais cette question.

    Lorsque je tape à une vitesse normale dans la barre de recherche, tout fonctionne normalement. Mais si je décide soudainement d'écrire super vite, la fonction d'ajout d'un guillemet lorsqu'un utilisateur en a mis un premier cesse de fonctionner et ne fonctionne plus du tout par la suite même si je recommence à écrire à une vitesse normale.

    Une fois que l'utilisateur sera comment utiliser mon outil, il peut arriver qu'il tape très vite et ce cas d'utilisation peut se produire.

    Lorsque j'affiche mes variables d'état avec console.log, il semble qu'avant de taper très vite, tout est déclenché dans le inputHandler. Mais après avoir tapé très vite, seules les variables d'état concernant l'ancienne chaîne de caractère et la nouvelle chaîne de caractère saisie par l'utilisateur sont activées, la variable d'état booléenne pour lancer le test de vérification de l'ajout d'un nouveau guillemet n'est plus activée et ne passe donc jamais à true (Elle devrait être mise à true dans inputHandler (la fonction callback de l'élément input dans le return()) qui active alors le premier useEffect puisque la variable d'état booléenne est dans le tableau de dépendance)

    Est-ce que quelqu'un sait ce qui peut causer ce comportement entre un input, sa fonction callback et les variables d'état ? (comme ça je dirai que lorsque l'on tape très vite l'actualisation des variables d'états n'a pas le temps de se faire mais je ne comprends pas alors pourquoi cela ne reprends pas normalement lorsque je recommence à écrire à une vitesse normale dans l'input)

    Merci d'avance si vous prenez le temps de m'aider

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 699
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 699
    Par défaut
    est ce que vous avez déjà fait un exemple qui fonctionne en javascript simple ?
    j'ai fait un essai là avec l'évènement "input" :
    https://codesandbox.io/s/lingering-g...=/src/index.js

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut
    Désolé pour le temps que j'ai mis à vous répondre, en effet en vanilla javascript cela marche comme voulu mais je voulais implémenter cette logique avec les hooks de react en passant par useEffect notamment. J'ai finalement trouvé mon problème, il me manquait un useEffect pour que mon précédent code fonctionne normalement, à cause de cela, une de mes variables d'état n'avait pas le temps de se mettre à jour et cela créé les comportements étranges de reposition du curseur dans l'input.

    Au cas où cela pourrait intéresser quelqu'un je mets le code correct ici (j'ai rajouté quelques conditions de validation dans certains useEffect pour éviter des bugs d'ajout random de guillemets notamment lors d'un copier coller ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
     
    import * as React from "react";
    import { useEffect, useState, useRef } from "react";
     
    const QuoteInput: React.FC = () => {
     
        const inputRef = useRef<HTMLInputElement | null>(null);
     
        const [inputChoose, setInputChoose] = useState("");
        const [previousInputChoose, setPreviousInputChoose] = useState("");
     
     
        const [testQuoteAddition, setTestQuoteAddition] = useState(false);
        const [enterSingleQuote, setEnterSingleQuote] = useState(false);
        const [enterDoubleQuote, setEnterDoubleQuote] = useState(false);
     
        const [writeNewSingleQuote, setWriteNewSingleQuote] = useState(false);
        const [writeNewDoubleQuote, setWriteNewDoubleQuote] = useState(false);
     
        const [repositionCaretBetweenQuotes, setRepositionCaretBetweenQuotes] = useState(false);
        const [indexDifferenceInInput, setIndexDifferenceInInput] = useState(0);
     
        const inputHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
            setPreviousRequestChoose(requestChoose);
            const enteredRequest = event.target.value;
            setRequestChoose(enteredRequest);
     
            setTestQuoteAddition(true);
        };
     
        useEffect(()=>{
            if(testQuoteAddition === true && (previousInputChoose.length === inputChoose.length || previousInputChoose.length === inputChoose.length - 1)) {
                for(let i=0; i<=inputChoose.length; i++) {
                    if(previousInputChoose.charAt(i) !== inputChoose.charAt(i))
                    {
                        let previousSingleQuoteNumber = previousRequestChoose.split("'").length - 1;
                        let previousDoubleQuoteNumber = previousRequestChoose.split('"').length - 1;
                        let previousQuoteNumber: number;
                        if (previousSingleQuoteNumber !== undefined && previousDoubleQuoteNumber !== undefined) {
                            previousQuoteNumber = previousSingleQuoteNumber + previousDoubleQuoteNumber;
                        } else if (previousSingleQuoteNumber !== undefined && previousDoubleQuoteNumber === undefined) {
                            previousQuoteNumber = previousSingleQuoteNumber;
                        } else if (previousSingleQuoteNumber === undefined && previousDoubleQuoteNumber !== undefined) {
                            previousQuoteNumber = previousDoubleQuoteNumber;
                        } else {
                            previousQuoteNumber = 0;
                        }
                        previousQuoteNumber = previousSingleQuoteNumber! + previousDoubleQuoteNumber!;
     
                        let currentSingleQuoteNumber = requestChoose.split("'").length - 1;
                        let currentDoubleQuoteNumber = requestChoose.split('"').length - 1;
                        let currentQuoteNumber: number;
                        if (currentSingleQuoteNumber !== undefined && currentDoubleQuoteNumber !== undefined) {
                            currentQuoteNumber = currentSingleQuoteNumber + currentDoubleQuoteNumber;
                        } else if (currentSingleQuoteNumber !== undefined && currentDoubleQuoteNumber === undefined) {
                            currentQuoteNumber = currentSingleQuoteNumber;
                        } else if (currentSingleQuoteNumber === undefined && currentDoubleQuoteNumber !== undefined) {
                            currentQuoteNumber = currentDoubleQuoteNumber;
                        } else {
                            currentQuoteNumber = 0;
                        }
                        currentQuoteNumber = currentSingleQuoteNumber! + currentDoubleQuoteNumber!;
     
                        if (inputChoose.charAt(i) === "'" && currentQuoteNumber !== previousQuoteNumber) {
                            setEnterSingleQuote(true);
                        } else if (inputChoose.charAt(i) === '"' && currentQuoteNumber !== previousQuoteNumber) {
                            setEnterDoubleQuote(true);
                        }
                    }
                }
            }
            setTestQuoteAddition(false);
        },[testQuoteAddition])
     
        useEffect(()=>{
            if(enterSingleQuote === true){
                let findDifference: boolean = false
                for(let i=0; i<inputChoose.length; i++) {
                    if(previousInputChoose.charAt(i) !== inputChoose.charAt(i) && findDifference === false)
                    {
                        setIndexDifferenceInInput(i);
                        findDifference = true;
                    }
                }
                setEnterSingleQuote(false);
                setWriteNewSingleQuote(true);
            } else if (enterDoubleQuote === true){
                let findDifference: boolean = false
                for(let i=0; i<inputChoose.length; i++) {
                    if(previousInputChoose.charAt(i) !== inputChoose.charAt(i) && findDifference === false)
                    {
                        setIndexDifferenceInInput(i);
                        findDifference = true;
                    }
                }
                setEnterDoubleQuote(false);
                setWriteNewDoubleQuote(true);
            }
        },[enterSingleQuote, enterDoubleQuote])
     
        useEffect(()=>{
            if (writeNewSingleQuote === true) {
                let newString: string = inputChoose.slice(0,indexDifferenceInInput + 1) + "'" + inputChoose.slice(indexDifferenceInInput + 1);
                setInputChoose(newString);
     
                if(inputRef !== null && inputRef !== undefined) {
                    if (inputRef.current !== null && inputRef.current !== undefined) {
                        if (inputRef.current.setSelectionRange !== undefined) {
                            setRepositionCaretBetweenQuotes(true);
                        }
                    }
                }
            } else if (writeNewDoubleQuote === true) {
                let newString: string = inputChoose.slice(0,indexDifferenceInInput + 1) + '"' + inputChoose.slice(indexDifferenceInInput + 1);
                setInputChoose(newString);
     
                if(inputRef !== null && inputRef !== undefined) {
                    if (inputRef.current !== null && inputRef.current !== undefined) {
                        if (inputRef.current.setSelectionRange !== undefined) {
                            setRepositionCaretBetweenQuotes(true);
                        }
                    }
                }
            }
        },[writeNewSingleQuote, writeNewDoubleQuote])
     
        useEffect(()=>{
            setWriteNewSingleQuote(false);
            setWriteNewDoubleQuote(false);
            if (repositionCaretBetweenQuotes === true) {
                inputRef?.current?.setSelectionRange(indexDifferenceInInput + 1, indexDifferenceInInput + 1);
            }
            setRepositionCaretBetweenQuotes(false);
        },[repositionCaretBetweenQuotes])
     
        return(
            <div>
                <input ref={inputRef} type="text" onChange={inputHandler} value={inputChoose} className="text-center" placeholder="enter an input" />
            </div>
        );
    }
     
    export default QuoteInput;
    La question initiale est donc résolue mais je ne sais pas s'il faut marquer le poste comme résolu car je ne n'ai toujours pas trouvé de réponse pour la deuxième question que j'ai mis à la fin du post initial (fonction d'ajout de guillemet qui arrête de fonctionner si l'utilisateur saisit un grand nombre de caractères très rapidement). Vaut-il mieux faire un nouveau post uniquement pour cette deuxième question et mettre ce poste en résolu ou garder ce post ouvert en espérant que quelqu'un connaisse la réponse ?

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 213
    Par défaut
    Bonjour,
    La question initiale est donc résolue mais je ne sais pas s'il faut marquer le poste comme résolu car je ne n'ai toujours pas trouvé de réponse pour la deuxième question que j'ai mis à la fin du post initial (fonction d'ajout de guillemet qui arrête de fonctionner si l'utilisateur saisit un grand nombre de caractères très rapidement).
    de ce que je vois à chaque appui sur une touche tu retraites la totalité de texte ce qui ne sert à rien.

    La logique de la saisie devrait plutôt être dans une fonction en interceptant la touche frappée, regarde ce que t'a proposé mathieu, c'est concis et permet de traiter plusieurs caractères, je mettrais toutefois l'écouteur sur le beforeinput.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2022
    Messages : 21
    Par défaut
    Bonjour, merci pour ton aide.

    En effet vous aviez raison, j'ai mis cette fonctionnalité en vanillaJS et elle marche parfaitement.

    Mais du coup cela veut dire que la logique des hooks n'est pas optimale (ou alors c'est moi qui avais mal implémenté ma fonctionnalité ce qui causait ce ralentissement) ? J'aurai pensé qu'en passant par les hooks des composants fonctionnels ce genre de cas (auto-complétion de caractère) pouvait être entièrement pris en charge par l'architecture propre à React.

    Est-ce qu'utiliser du vanilla JS dans un composant React pour créer une fonctionnalité faisable avec la logique des hooks est quelque chose d'envisageable/conseillé (est ce que c'est une bonne pratique) ou est-ce que cela peut entraîner des comportements indésirables ?

    Je vais mettre le code quasi final en dessous pour ceux que ça pourrait intéresser mais il me reste un petit problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    import * as React from "react";
    import { useEffect, useState, useRef } from "react";
     
    const QuoteInput: React.FC = () => {
     
        const inputRef = useRef<HTMLInputElement | null>(null);
     
        const [inputChoose, setInputChoose] = useState("");
     
        const [testQuoteAddition, setTestQuoteAddition] = useState(false);
     
        const inputHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
            const enteredRequest = event.target.value;
            setRequestChoose(enteredRequest);
     
            setTestQuoteAddition(true);
        };
     
        const handleComplete = (event: KeyboardEvent) => {
            if((event.key === "'" || event.key === '"') && (-1 !== ["'", "\""].indexOf(event.key))) {
                let longueur = (event.target as HTMLInputElement)?.value.length;
                let position = (event.target as HTMLInputElement)?.selectionStart;
     
                (event.target as HTMLInputElement).value = (event.target as HTMLInputElement).value.substr(0, position? position:0) + event.key + (event.target as HTMLInputElement).value.substr(position? position:0, longueur? longueur:0);
     
                (event.target as HTMLInputElement).setSelectionRange(position, position);
            } else if (event.key === "[") {
                let longueur = (event.target as HTMLInputElement)?.value.length;
                let position = (event.target as HTMLInputElement)?.selectionStart;
     
                (event.target as HTMLInputElement).value = (event.target as HTMLInputElement).value.substr(0, position? position:0) + "]" + (event.target as HTMLInputElement).value.substr(position? position:0, longueur? longueur:0);
     
                (event.target as HTMLInputElement).setSelectionRange(position, position);
            } else if (event.key === "(") {
                let longueur = (event.target as HTMLInputElement)?.value.length;
                let position = (event.target as HTMLInputElement)?.selectionStart;
     
                (event.target as HTMLInputElement).value = (event.target as HTMLInputElement).value.substr(0, position? position:0) + ")" + (event.target as HTMLInputElement).value.substr(position? position:0, longueur? longueur:0);
     
                (event.target as HTMLInputElement).setSelectionRange(position, position);
            }
        };
     
        useEffect(() => {
            if (testQuoteAddition=== true) {
                inputRef.current?.addEventListener("keydown", e => {handleComplete(e)});
     
                // cleanup this component
                return () => {
                    inputRef.current?.removeEventListener("keydown", e => {handleComplete(e)});
                };
            }
            setTestQuoteAddition(false);
        }, [testQuoteAddition]);
     
        return(
            <div>
                <input ref={inputRef} type="text" onChange={inputHandler} value={inputChoose} className="text-center" placeholder="enter an input" />
            </div>
        );
    }
     
    export default QuoteInput;
    Comme vous pouvez le voir, l'auto-complétions de caractère se fait pour les guillemets mais je veux aussi la faire pour les parenthèses et les crochets: () et []

    Seulement, avec ce code mes parenthèses sont bien complétées mais le crochet gauche est lui complété par une parenthèse droite (alors que dans le code je demande bien de rajouter un crochet droit), est-ce que quelqu'un sait d'où vient ce résultat.

    EDIT

    En relisant ta réponse je vois que tu me conseilles d'utiliser l'évènement inputBefore. De ce que j'ai compris les évènement 'key' se déclenche sur n'importe quelle page html et les évènement 'input' uniquement si on est en train de modifier un input. Du coup si ce n'est pas pour gérer un raccourci mais une saisie d'un utilisateur tu me conseilles de toujours utiliser l'évènement input ?

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 213
    Par défaut
    Est-ce qu'utiliser du vanilla JS dans un composant React pour créer une fonctionnalité ...
    A un moment ou à un autre il te faudra bien utiliser du vanilla.

    Tu as encore beaucoup de « redite » dans ton code handleComplete, il te faut factoriser et tu devrais changer ton approche pour cela.

    Voilà une approche possible sur base de l'écoute de l'événement beforeinput
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function addClosingChar(e) {
     
      const autoChar = {
        prefix: ['"', '{', '(', '[', '<', '«'],
        suffix: ['"', '}', ')', ']', '>', '»'],
      };
     
      const index = autoChar.prefix.indexOf(e.data);
      if (index > -1) {
          e.preventDefault();   // ne pas oublier !
          insertTag(e.target, autoChar.prefix[index], autoChar.suffix[index], true);
      }
    }
    la fonction insertTag n'est pas définie ici mais reste standard en utilisant les elem.selectionStart et elem.selectionEnd.


    En relisant ta réponse je vois que tu me conseilles d'utiliser l'évènement inputBefore. De ce que j'ai compris les évènement 'key' se déclenche sur n'importe quelle page html et les évènement 'input' uniquement
    Les événements ne sont récupérables que sur les éléments pour lesquels on écoute ceux-ci.

    Pour le insertBefore c'est un choix qui me semble plus judicieux que le input ou keydown sur les éléments <input> et <textarea>, en gros :
    Avec input :
    • La moindre saisie supprime la sélection éventuelle en cours
    • Les « coller » ne sont pas pris en compte

    Avec keydown :
    • On ne supprime pas la sélection éventuelle en cours
    • Cela ne permet pas de gérer les caractères étendues comme « Alt + 0171
    • Les « coller » ne sont pas pris en compte

    Alors que beforeinput met tout le monde d'accord, c'est ce que j'en avais tiré comme conclusion après tests lors de la résolution d'une demande proche de la tienne avec insertion de tag divers.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bloquer le curseur de la souris dans une zone
    Par Andalor dans le forum IHM
    Réponses: 9
    Dernier message: 02/11/2017, 10h42
  2. Bloquer le curseur de la souris dans une zone
    Par ewp02 dans le forum Interfaces Graphiques
    Réponses: 0
    Dernier message: 25/10/2011, 15h43
  3. Curseur de la souris dans les diagrammes
    Par Teaniel dans le forum BOUML
    Réponses: 2
    Dernier message: 07/06/2011, 16h20
  4. Placer le curseur lorqu'on clique dans une zone de texte
    Par la_chevre dans le forum SWT/JFace
    Réponses: 3
    Dernier message: 17/08/2010, 14h15
  5. Réponses: 10
    Dernier message: 14/05/2006, 16h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo