2

Tengo un formulario, el cual tiene una funcion que hace que ciertos campos se autocompleten basandose en una tabla de mi base de datos aparte.

El detalle aquí es que se implementó ahora el código QR, el cúal solo escanean una sola vez cada caja, hasta un máximo de 36, el problema es que cuando escanea la última caja, el escaner llena los campos y manda el formulario, cuando aparece la notificación de que se escaneo correctamente todo, atras se ve como se terminan de autollenar los datos, sin embargo, estos datos que se autollenaron de la última caja no se mandan al formulario.

Interfaz de escaneo

Ahora lo que quiero es atrasar el envio al menos un segundo (que es lo que tarda en hacer el autollenado) para que los datos se manden completos.

<form method="post" name="crear-in" id="crear_in" action="modelo-in.php" onsubmit="return validar();">

                      <!-- Los datos se pueden desplegar hasta 40 veces -->
                      <?php
                      for ($i = 1; $i <= $n; $i++) { ?>
                        <tr class="fila-fija">

                          <input type="hidden" style="width : 140px;" id="customer<?php echo ($i); ?>" required name="customer[]" placeholder="customer" />
                          <input type="hidden" id="folio<?php echo ($i); ?>" name="folio[]" value="<?php echo $f; ?>">
                          <td><input type="text" style="width : 25px;" id="customer<?php echo ($i); ?>" value="<?php echo ($i); ?>" disabled /></td>
                          <td><input onchange="consult(), validarskmx(this);" type="text" style="width : 90px;" id="skmx_pn<?php echo ($i); ?>" required name="skmx_pn[]" placeholder="SKMX PN" /></td>
                          <td><input type="text" style="width : 180px;" id="description<?php echo ($i); ?>" required name="description[]" placeholder="Description" readonly /></td>
                          <td><input type="text" style="width : 90px;" id="customer_pn<?php echo ($i); ?>" required name="customer_pn[]" placeholder="Customer PN" readonly /></td>
                          <td><input onchange='return validarSO(this)' type="text" style="width : 120px;" id="shop_order<?php echo ($i); ?>" required name="shop_order[]" placeholder="# Shop Order" /></td>
                          <td><input type="text" style="width : 70px;" id="po<?php echo ($i); ?>" required name="po[]" placeholder="# P.O." readonly></td>
                          <td><input onchange='return validarQT(this)' class="quantity" type="text" style="width : 60px;" id="quantity<?php echo ($i); ?>" required name="quantity[]" placeholder="Quantity" /></td>
                          <td><input onchange='return validarLOTE(this)' type="text" style="width : 100px;" id="lote<?php echo ($i); ?>" required name="lote[]" placeholder="Lote" /></td>
                          <td><input type="text" style="width : 60px;" id="location<?php echo ($i); ?>" required name="location[]" placeholder="Location" value="PASILLO" readonly /></td>
                          <td><input type="text" style="width : 60px;" id="incoming<?php echo ($i); ?>" required name="incoming[]" placeholder="" readonly /></td>

                        </tr>
                      <?php } ?>

                      <!-- </table> -->
                      <div class="box-footer">
                        <br>
                        <input type="hidden" name="registro" value="nuevo">
                        <button type="submit" id="btn-in-out" class="btn btn-primary btn-lg">Crear</button>
                        <a href="in-out.php" class="btn btn-danger btn-lg">Cancelar</a>

                      </div>

                    </form>

Aquí mi función de autollenado.

                 function consult() {
                    $.ajax({
                      url: "consulta.php",
                      type: "POST",
                      dataType: "json",
                      success: function(data) {
                        cambioOpciones(data);
                      }
                    })
                  }

                  function cambioOpciones(data) {

                    let id_cpn1 = document.getElementById('skmx_pn1').value;
                    if (id_cpn1 = 'skmx_pn1') {
                      // Obtener y almacenar el valor de skmx_pn

                      let id_cpn1 = document.getElementById('skmx_pn1').value;

                      //Buscar el elemento en arreglo de datos
                      let item = data.find(element => element[1] == id_cpn1);
                      //Verificar que se encontró el elmento.
                      if (typeof item == 'undefined' || !item) {
                        console.log(`No se encontró ${id_cpn1}`);
                        return;
                      }

                      document.getElementById('customer1').value = item[2];
                      document.getElementById('customer_pn1').value = item[3];
                      document.getElementById('description1').value = item[4];
                      document.getElementById('incoming1').value = item[5];
                    }

Aquí manejo mi alerta cuando se termina de escanear.

$("#crear_in").on("submit", function (e) {
    e.preventDefault();

    var datos = $(this).serializeArray();
    //Crear llamado Ajax
    $.ajax({
      type: $(this).attr("method"),
      data: datos,
      url: $(this).attr("action"),
      dataType: "json",
      success: function (data) {
        console.log(data);
        var resultado = data;

        if (resultado.respuesta == "exito") {
          swal("Correcto", "Se han registrado correctamente", "success");
          setTimeout(function () {
            window.location.href = "in-out.php";
          }, 1500);
        } else {
          swal(
            "Error!",
            "El Folio ya pertenece a otra tarima, Intente nuevamente",
            "error"
          );
        }
      },
    });

Espero me haya dado a entender bien, y que me puedan ayudar, si saben de alguna manera de poder hacerlo, se los agradecería mucho.

  • 1
    mas que retrasar un segundo necesitas realizar una [asincronia](https://es.stackoverflow.com/questions/277690/qu%c3%a9-diferencias-hay-entre-callbacks-promises-y-async-await) para que tu código espere a que tenga todo lo que necesitas – Nicolas Oñate Jun 09 '21 at 15:21
  • Me parece que una forma más fácil de lograrlo es tener el botón de `submit` desactivado mientras se escanean los QR y cuando retorne `success` el ajax de escaneo, activarlo. Sin necesidad de timeouts (que no me parecen una solución óptima) – Camilo Gomez Jun 09 '21 at 15:32
  • ¿Por qué redirigir a otra página? En general, el uso de AJAX es para evitar redirigir o recargar páginas, teniendo la posibilidad de actualizar el DOM para actualizar o mostrar nuevos elementos. – Triby Jun 09 '21 at 15:39

1 Answers1

3

bueno parece que quieres meterle setTimeout al envio del ajax.

En teoría deberías meter el ajax en un setTimeout tal cual lo haces con el redireccionar:

function delayedAjax(datos,$this){
    $.ajax({
      type: $this.attr("method"),
      data: datos,
      url: $this.attr("action"),
      dataType: "json",
      success: function (data) {
        console.log(data);
        let resultado = data;
        if (resultado.respuesta == "exito") {
          swal("Correcto", "Se han registrado correctamente", "success");
          setTimeout(function () {
            window.location.href = "in-out.php";
          }, 3000);
        } else {
          swal(
            "Error!",
            "El Folio ya pertenece a otra tarima, Intente nuevamente",
            "error"
          );
        }
      },
    });
}

$(document).on("submit","#crear_in", function (e) {
    e.preventDefault();
    let datos = $(this).serializeArray();
    let $this = $(this);
    setTimeout(function(){ window.delayedAjax(datos,$this) }, 5000); // este ejemplo tiene un delay de 5 segundos
}); 
ArcanisGK507
  • 3,526
  • 4
  • 16
  • 47
  • Si funciona en cuanto a retrasar el envio, pero sigue el mismo problema de que no manda la información de la úlitma caja escaneada, el autocompletado. – JoseFernando Jun 09 '21 at 15:57
  • entonces tu problema es la captura de datos, no retrasar 1 segundo el envió. estas seguro que la ultima caja esta dentro del elemento: #crear_in – ArcanisGK507 Jun 09 '21 at 16:06
  • Intenta usando $(document).serializeArray(); no es lo mas optimo pero prueba a ver si de esta manera se logra. lo otro que veo es que tu tabla no tiene los tag de tabla y cabecera etc... – ArcanisGK507 Jun 09 '21 at 16:09
  • mi respuesta responde a tu pregunta pero tu problema es otro... creo que debes validar este POST como resuelvo y reformular la pregunta en otro post y agregar las pruebas que te he mencionado. – ArcanisGK507 Jun 09 '21 at 16:10
  • Tengo un for, el cúal, dependiendo de la cantidad que requiera el usuario, son las veces que se va a desplegar, en algunos casos este problema no se presenta, osea que, escanear dos veces la misma cantidad de cajas, en una puede ir completo el formulario y en el otro le puede faltar la informacion de la ultima caja, hablando solo del autocompletado. – JoseFernando Jun 09 '21 at 16:11
  • eso no responde lo que te estoy diciendo que necesitas hacer... – ArcanisGK507 Jun 09 '21 at 16:13
  • los tr deben estar dentro de una estructura de tabla: https://www.w3schools.com/html/tryit.asp?filename=tryhtml_table_intro – ArcanisGK507 Jun 09 '21 at 16:14
  • Fijate que actualice la respuesta estoy utilizando un metodo delegado de jquery, estoy casi seguro que ese es el problema ya que has agregado contenido con ajax... – ArcanisGK507 Jun 09 '21 at 16:17
  • Marcare tu respuesta como correcta, responde a mi pregunta pero no resolvio mi problema, igual te lo agradezco. – JoseFernando Jun 09 '21 at 16:30
  • validaste el cambio que realice??? – ArcanisGK507 Jun 09 '21 at 16:30
  • Si, el formulario tarda el tiempo que uno le asigna para mandar la alerta, pero cuando reviso los datos, estos siguen haciendo lo mismo, no se manda el de la ultima caja. Ademas, mis tr estan dentro de la estructura table, pero no lo agrege a la pregunta. – JoseFernando Jun 09 '21 at 16:32
  • ok entiendo pero hiciste este cambio? `$(document).on("submit","#crear_in", function (e) {` – ArcanisGK507 Jun 09 '21 at 16:33
  • y este otro: `$(document).serializeArray();` – ArcanisGK507 Jun 09 '21 at 16:34
  • Claro, realize los primeros cambios, y la segunda edición que le hiciste a tu respuesta. – JoseFernando Jun 09 '21 at 16:36
  • y nada??? intenta entonces lo siguiente, revisa los name de los campos si en las lineas tiene algo como esto `name="location[]"` no sirve debe ser igual al ID: `name="incoming" ` en tu backend si es php suponiendo puedes hacer un var_dump($_POST); y validar que llego – ArcanisGK507 Jun 09 '21 at 16:39