Update a div with ajax when there is a change

0

I want to make a div recharge only when it finds a modification in the database I currently have this so, if you can help me I would appreciate it is for a shift system that I am doing

<?php

$result = $mysqli->query("SELECT * FROM  'turnos' ORDER by 'turno' desc limit 1" ); 
$row = $result->fetch_row(); 

  echo '<script type="text/javascript">
  swal({ title: "siguiente turno : '.$row[0].'", 
  text: "Se envio correctamente", 
  type: "success",
  showConfirmButton: false,
  timer: 2000
});
 </script>'; 

This is the ajax:

 <script>
    setInterval(function() {
$('#turnos').load('./ajax/turnos.php');'// Selector de la div y el fichero a refrescar

}, 1000); // Temporizador que ejecuta el refresco cada 1 segundos
</script>

div

<div id="turnos"></div>
    
asked by Dev. Joel 27.07.2018 в 17:58
source

2 answers

4

What you are doing is basically correct. A database like MySQL is not "reactive" to trigger alerts when changes occur. What you are doing is a kind of long-polling.

However, , I think you're focusing it badly. The backend does not have to print a script . In fact, it seems like a very bad idea.

The backend should only respond with an object of the form

{turno: 5}

And on the front, you call SweetAlert if the response from the backend is different from the previous one (that you save in a variable);

In other words, on your backend:

<?php

$result = $mysqli->query("SELECT * FROM 'turnos' ORDER by 'turno' desc limit 1" ); 
$row = $result->fetch_row(); 

echo json_encode(['turno'=>$row[0]]);

And in the frontend:

var turno_actual=0;

function desplegarAlerta() {
   // despliego la alerta desde el front
   swal({
    title: "siguiente turno : " + turno_actual,
    text: "Se envio correctamente",
    icon: "success",
    button: true
  });
}

function refrescaTurno() {

   $.ajax({
     url: "./ajax/turnos.php",
     dataType:'json' // parseo la respuesta como objeto
   }).then(function(response) {
      // sólo lo ejecutas si el turno cambió
      if(response.turno != turno_actual) {
         turno_actual=response.turno;
         desplegarAlerta();
      }
      window.setTimeout(refrescaTurno,2000);
   });

}

refrescaTurno();

Note that I took the idea of Ivanrangel to trigger the new call once the backend has responded. If you put an arbitrary interval and the backend takes longer than this one, you will glue calls.

I'll give you an example where, in the absence of ajax calls, I put a function that generates a random number, which determines if the shift was increased or if it has remained the same. If the new shift is equal to the existing one, I write in the console that there are no changes.

PS: I am not using the div that you were filling at all. I do not know if it has any relevance.

PD2: you were defining the SweetAlert to self-close after 2 seconds. I removed that parameter because in your example it did not make sense (polling every 1 second, the 2 seconds were never fulfilled to self-close)

var last_turno = 1,
  intervalo;
  
function getTurno() {
  return new Promise(function(resolve,reject) {
      var random=parseInt(7*Math.random(),10);
      if(random>3) {
        window.setTimeout(function() {
          resolve({turno:last_turno+1});
        },500);
      } else {
         window.setTimeout(function() {
          resolve({turno:last_turno});
        },500);
      }
  });
}

function displayTurno(turno) {
  console.log('El nuevo turno es '+last_turno);
  swal({
    title: "siguiente turno : " + turno,
    text: "Se envio correctamente",
    icon: "success",
    button: true
  });
}

function comenzarIntervalo() {
  displayTurno(last_turno);
  intervalo = setInterval(function() {
    getTurno().then(function(response) {
      if(response.turno !== last_turno) {
        last_turno=response.turno;
        displayTurno(last_turno);  
      } else {
        console.log('No ha cambiado el turno');
      }
    });
    
  }, 5000);

}

jQuery(document).ready(function() {
  jQuery('#iniciar').on('click', function() {
    jQuery('#terminar').removeAttr('disabled');
    jQuery('#iniciar').attr('disabled', 'disabled');
    comenzarIntervalo();
  });
  jQuery('#terminar').on('click', function() {
    jQuery('#iniciar').removeAttr('disabled');
    jQuery('#terminar').attr('disabled', 'disabled');
    clearInterval(intervalo);
  });
});
.swal-icon {
float:left;
margin-left:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

<div id="turnos"></div>

<input type="button" value="terminar el refresco" id="terminar" disabled="disabled">
<input type="button" value="empezar a refrescar" id="iniciar">
    
answered by 27.07.2018 / 22:07
source
0

What you could do is load it from time to time, I'll give you an example of how you could do it.

<!DOCTYPE html>
<html lang="es">
<head>
<title>ajaxreload</title>
<style>
</style>
</head>
<body>
<div id="turnos"></div>
</body>
<script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>
<script>
function sendRequest(){
  $.ajax({
    url: "./ajax/turnos.php",
    success:
      function(result){ 
/* si es success mostramos resultados */
       $('#turnos').text(result);
    },
    complete: function() { 
/* solo una vez que la petición se completa (success o no success) 
   pedimos una nueva petición en 3 segundos */
       setTimeout(function(){
         sendRequest();
       }, 3000); /*Estos son 3 segundos*/
      }
    });
  };

/* primera petición que echa a andar la maquinaria */
$(function() {
    sendRequest();
});

</script>
</html>
    
answered by 27.07.2018 в 19:59