Quiero poder evitar que un usuario ingrese caracteres en un cuadro de texto en función de cuál sería el texto del cuadro de texto si se ingresa el carácter.
El pensamiento inicial es hacer algo como esto:
<input type="text" id="test" /> document.getElementById("test").addEventListener("keypress", (e) => { // Get the current text const currentText = e.target.value; // Get the new char entered by the user const newChar = String.fromCharCode(e.keyCode); // The problem is that we don't know where the cursor is, // ie we CANNOT guarantee that the new text will be: const newText = `${currentText}${newChar}`; // ...because that assumes the cursor is at the end of the current text // I want to check that newText is valid before allowing the event to go through if(!someCustomCheck(newText)) { e.preventDefault(); } });Los comentarios explican mi problema, pero aquí hay otro ejemplo: imagina que tenemos una entrada que permite agregar números con 2 decimales:
1 en él; esto es válido, así que lo permitimos. en él, que de nuevo es válido, entonces 2 y 31.234 :4 puede ser 1.234 , que no es válido, pero también puede ser 41.23 o 14.23 , que es válido No puedo ver una forma de obtener la posición del cursor en el event en el evento de clic, ni puedo ver una propiedad en e.target (como puede ver en el evento keyup ) que proporciona el texto final de la entrada.
¿Hay alguna forma de hacer esto?
La respuesta, para futuros lectores, es usar e.target.selectionStart . Eso le permite encontrar dónde el usuario presionó la tecla y le permite construir cuál sería la cadena final si se permite ingresar la entrada.
const newChar = String.fromCharCode(e.keyCode); const cursorPos = e.target.selectionStart; const inputText = e.target.value; const proposedNewText = `${inputText.slice(0, cursorPos)}${newChar}${inputText.slice(cursorPos, inputText.length)}`; Vale la pena señalar que esto puede volverse más complicado si el usuario ha seleccionado un rango de texto (es decir, un cuadro de texto con 5 caracteres y el usuario hace clic y arrastra para seleccionar el 2º -> 5º carácter) y luego escribe. En ese caso, deberá obtener la posición del cursor inicial y final ( e.target.selectionStart y e.target.selectionEnd ) y .splice() la cadena, agregando el nuevo carácter del usuario.
Luego tiene el problema de que al cambiar el valor de la entrada (usando e.target.value = newText ) el cursor saltará automáticamente al final del texto. Hay mucho que considerar dependiendo de su caso de uso.
Esperemos que esto ayude a señalar a alguien en la dirección correcta.