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)
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.
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;
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![]()
Partager