Tengo un formulario con dos elementos de entrada que están algo entrelazados. En el elemento n. ° 1 (el elemento n. ° 2 está justo después del elemento n. ° 1 en el orden de tabindex), una vez que el usuario intenta abandonar ese campo, ejecuto una llamada ajax para verificar si el valor ingresado ya está en la base de datos y, de ser así, uso el diálogo de confirmación de javascript para hacerle una pregunta al usuario. El segundo elemento, al obtener el foco, muestra automáticamente una ventana modal con opciones que el usuario puede hacer. Estoy usando Jquery.
Me gustaría ejecutar la llamada ajax "¿Existen estos datos?" tan pronto como el usuario abandone el primer elemento. el evento Blur parecía ser lo que quería, ya que se necesita esta verificación de datos existente, ya sea que el usuario haya realizado un cambio o no.
Sin embargo, mi problema al usar el desenfoque es que su controlador se ejecuta DESPUÉS de que el primer elemento pierde el foco y el foco salta al elemento #2. Entonces, el controlador de desenfoque del elemento n. ° 1 muestra la pantalla de confirmación al mismo tiempo que el controlador de enfoque del elemento n. ° 2 muestra el modal de opciones y ahora tengo 2 ventanas emergentes abiertas al mismo tiempo.
Me gustaría darle al usuario la oportunidad de responder la pregunta en la alerta de confirmación antes de que aparezcan las opciones para el elemento #2.
¿Hay un evento de Jquery similar al desenfoque, pero que se ejecuta justo ANTES de que se pierda el enfoque? O, ¿hay alguna manera de evitar que el siguiente elemento obtenga el foco hasta que se complete el controlador de desenfoque del primer elemento?
Intentar detener la propagación o prevenirDefault() en el controlador de desenfoque no hace nada porque el enfoque en el elemento n.º 2 ya sucedió antes de que se ejecute el controlador de desenfoque.
Intenté configurar el índice de tabulación del elemento n. ° 2 en -1 y luego enfocarme programáticamente en ese elemento cuando sea necesario, pero tabular lejos de este elemento se convierte en un problema, y la tabulación inversa lo omite (saltando directamente al elemento n. ° 1) - Todavía quiero ese elemento en el orden de tabindex, pero simplemente no quiero que gane el foco hasta que el elemento n. ° 1 complete su controlador que debe ejecutarse cuando pierde el foco.
También intenté establecer variables de estado, pero cuando agrego código para manejar la transición entre los dos elementos, termino con problemas similares y presenta una complejidad adicional de casos extremos. También intenté jugar con los eventos de mousedown y keydown y tratar de evitar el procesamiento predeterminado, pero eso también agregó una complejidad significativa y un margen de error.
Cualquier idea sería bienvenida. Gracias.
Esta solución es un poco complicada, pero logra su objetivo. El truco consiste en colocar lo que equivale a un elemento "no operativo" que acepta el enfoque en el desenfoque. Luego controlando la pestaña después de la solicitud de AJAX.
En cada evento de "desenfoque", hacemos pruebas para asegurarnos de capturar el elemento <input> correcto (te dejaré esos detalles a ti).
Una vez completada la solicitud de AJAX, concéntrese en el siguiente <input> .
Para esta demostración, escriba 2 en la segunda entrada, luego presione el tab . Agregué un breve retraso para que pueda ver que funciona.
$("input").on('blur', function(e){ if(this.value == 2) { console.log("do ajax request"); setTimeout((function(){ $(this).next().next('input').focus(); }).bind(this), 500); } }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <input tabindex="1" /> <input tabindex="2" /> <div tabindex="3"></div> <input tabindex="3" />¿Algo como esto haría el truco?
Tenga una variable que indique si está bien mostrar la segunda ventana emergente
let allowSecondPopup = true;Tener una variable que indique si se pospuso mostrar la segunda ventana emergente
let secondPopupPostponed = false;Establecer la variable cuando la primera entrada recibe el foco
$("#input1").on("focus", fuction () { allowSecondPopup = false; });Enviar ajax en desenfoque
$("#input1").on("blur", function () { //$("#input1").disabled(true); //$("#input2").disabled(true); $.post("https://example.com", { }, fuction (response) { if (secondPopupPostponed) { // Only show second popup after the ajax-call has finished showSecondPopup(); allowSecondPopup = true; secondPopupPostponed = false; } }); });Y cuando la segunda entrada reciba el foco, verifique la variable
$("#input2").on("focus", fuction () { if (allowSecondPopup) { showSecondPopup(); } else { // We're still waiting for the ajax-call to complete. // When the ajax-call completes, the callback will show the second popup. secondPopupPostponed = true; } });