0

How do I check if the value has change in DOM? I'm calling Ajax function to pull some data from database. I would like to blink or do some animation the that particular DIV if the new value has been pushed. So when "availability" changes do the animation only ONCE. Only to the DIV where the value has changed.

function getRealData() {
  $.ajax({
   url: 'test_api.php',
   data: "",
   dataType: 'json',
   success: function (rows) {
     var text = '';
     for (var i in rows) {
       var row = rows[i];
       var availability = row[3];
       var hostName = row[2];
       var intranet = row[6];
       var timeRespons = row[4];
       //console.log(availability);
       if (availability == 0){
         var img = "img/tick.png";
       }
       if (availability == 1){
         var img = "img/warning.png";
       }
       if (availability == 2){
         var img = "img/alert.png";
       }
       text+= '<section class="square"><h3> ' + intranet + '</h3><img src='+img+' width="70" height="70" rel='+availability+' alt="warning"/><h4><img src="img/time_icon.png" width="20" height="20" alt="clock" class="clock" /> '+ timeRespons+'</h4>';
           text += '</section>';
       }
     $("#journey").html(text);
   }
  });
}
 setInterval(getRealData, 2000); //this refreshes data every 2seconds
 getRealData(); //call the function to display data

The output is :

<div id="journey">
    <div class="square>availability: 0 hostName: aaa intranet: ttt timeResponse:0.124</div>
    <div class="square>availability: 0 hostName: qqq intranet: hhh timeResponse:0.064</div>
    <div class="square>availability: 0 hostName: www intranet: nnn timeResponse:0.303</div>
    <div class="square>availability: 0 hostName: rrr intranet: rrr timeResponse:0.019</div>
    <div class="square>availability: 0 hostName: eee intranet: uuu timeResponse:0.025</div>
    <div class="square>availability: 0 hostName: ggg intranet: ooo timeResponse:0.158</div>
</div>
ashleedawg
  • 20,365
  • 9
  • 72
  • 105
medzi
  • 407
  • 1
  • 8
  • 20
  • is `#journey` the div that should animate? – user1 Jul 19 '13 at 13:17
  • Will you have the same number of sections every time through the database call? Also, is intranet field unique name to section? – James Jul 19 '13 at 13:18
  • yes #journey is the div that should do the animation – medzi Jul 19 '13 at 13:22
  • yes, intranet has unique name. – medzi Jul 19 '13 at 13:22
  • I am not sure if i understand the question properly. So you are checking the database every two second and if there is new data, then the `forloop` will execute and you will have new data, else the for loop doesn't execute and you will have the old data as it is. Am I correct or am i missing something? – user1 Jul 19 '13 at 13:29
  • yes, yes that's correct. So everytime the new data is pushed and the value has changed I would like to do some notification, for example blink or change something but only once to that div. – medzi Jul 19 '13 at 13:31
  • class="square" should animate...sorry :( – medzi Jul 19 '13 at 13:33
  • Just a thought, but are you sure the data that the callback is receive is an array of arrays? A json response is expected, as defined by the `dataType` option, but you are processing an array of arrays. – stackptr Jul 19 '13 at 14:41

2 Answers2

0

A simple solution is to keep a variable outside the function containing the current text, and then write to that each time your getRealData() function is called. For example:

var currentText;
function getRealData() {
  $.ajax({
    url: "...", data: "...", dataType: "...",
    success: function(rows){
       var text = ''
       // Process text variable accordingly, as you have
       if (text != currentText){
         $("#journey").html(text).performBlinkEvent();
         currentText = text;
       }
    }
  });
}

The performBlinkEvent function can be readily found with a search, for example this is one post that turned up.

Edit: Another option is to iterate through all the <section class="square"> elements on success, writing each element on success rather than the entire containing #journey class:

function (rows) {
  // Get all squares and iterate over each
  var squares = $("#journey > .square").each( function(i) {
    var row = rows[i];
    var availability = row[3];
    var hostName = row[2];
    var intranet = row[6];
    var timeRespons = row[4];
    // construct img var based on availabiliy

    var text = ... // Construct content of <section class="square">

    if ( $(this).text() != text ){
      $(this).html(text).performBlink();
     }

  });
}

This assumes that the sections are already on the page, which I think is a fair assumption to make. It also assumes a 1 to 1 correspondence between the rows you receive and the number of sections in the page. If this is not true (i.e., the number of squares change with each response) then further logic is required.

Here is the JSFiddle for the second code snippet. I've populated a few elements with data, and then create a sample response containing the old data and some new data. The function will successfully determine which data needs to be inserted and will highlight the element that is updated.

It will need to be adapted to the specific data the callback is receiving (as I noted in a comment to the question, it seems unlikely you are actually receiving an array of arrays from a JSON response), but I hope this demonstrates how to accomplish your goal.

Community
  • 1
  • 1
stackptr
  • 167
  • 1
  • 2
  • 10
  • I edited my question. Your solution would apply to every div at the same time. I need to do blink only to the particular div when the value changes. – medzi Jul 19 '13 at 13:28
  • but you have an ID selector. Meaning you can only have one div with `id = journey`. so how would it apply to all the divs? – user1 Jul 19 '13 at 13:30
  • id = journey is only container where all data are coming, now each data is wrapped in class="square" which should animate. – medzi Jul 19 '13 at 13:34
  • I updated my answer. For what it's worth, I think monitoring the DOM for changes is the wrong way to go about this, since it is possible to know exactly which elements are being updated and when. – stackptr Jul 19 '13 at 13:53
  • doesn't seem to work..nothing is displaying out with your solution :( – medzi Jul 19 '13 at 14:14
  • Basically, I think the best way would be to check if the image path has changed and based on that do the animation. But I think it has to be done outside the setinterval function otherwise it will run constantly. – medzi Jul 19 '13 at 14:34
  • Well, try reading the function I wrote and understand what it does. I don't know specifically how your code is structured. Are you getting an error in the console? Maybe allow the console to log what $(this).text() is so you know if it is comparing it properly? – stackptr Jul 19 '13 at 14:35
  • I've updated my answer with a jsfiddle to demonstrate what I'm doing. There was a typo that would explain why nothing was displaying: when you do a `.each`, you need to supply the callback with an index in order to properly fetch the data you need from the response. – stackptr Jul 19 '13 at 14:55
  • Sorry for long reply. I have created a new question to make it more clear what I would like to achieve. [HERE](http://stackoverflow.com/questions/17782967/jquery-detect-div-text-value-changes-when-ajax-pulls-new-data) I really don't know how to solve it :( – medzi Jul 22 '13 at 14:34
  • This looks an awful lot like [this answer](https://stackoverflow.com/a/1145719/8112776) – ashleedawg Jan 13 '20 at 12:49
  • @ashleedawg I did link that answer as reference in this one – stackptr Jan 14 '20 at 18:44
0

Ok, I think I now understand your question.

function getRealData() {
 $.ajax({
     url: 'test_api.php',
     data: "",
     dataType: 'json',
     success: function (rows) {

         var text = '';

         for (var i in rows) {

             var row = rows[i];

             var availability = row[3];
             var hostName = row[2];
             var intranet = row[6];
             var timeRespons = row[4];


             //console.log(availability);

             if (availability == 0){
                 var img = "img/tick.png";

             }

             if (availability == 1){
                 var img = "img/warning.png";
             }

             if (availability == 2){
                 var img = "img/alert.png";
             }

             text+= '<section class="square new"><h3> ' + intranet + '</h3><img src='+img+' width="70" height="70" rel='+availability+' alt="warning"/><h4><img src="img/time_icon.png" width="20" height="20" alt="clock" class="clock" /> '+ timeRespons+'</h4>';//added a class called new in the section here
                 text += '</section>';



             }
         $("#journey").html(text);


     }
 });

      $(".square.new").each(function(){//wrote code to animate and remove the new class
             $(this).effect( "highlight", {color: 'red'}, 3000 );
             $(this).removeClass("new");
      });
 }

  //this refreshes data every 2seconds
    setInterval(getRealData, 2000);

   //call the function to display data
   getRealData();
user1
  • 1,063
  • 1
  • 8
  • 28
  • The problem with this is that it is going to consider every `.square` as new, and animate them all, whether the data actually changes or not. If the AJAX call gets the same old data and the element therefore remains the same, there should be no `.new` applied. – stackptr Jul 19 '13 at 13:55
  • Uncaught TypeError: Object [object Object] has no method 'effect' even though I added – medzi Jul 19 '13 at 13:55
  • $(this).animate({"background-color" :"red"},3000); doesn't work either :( – medzi Jul 19 '13 at 14:01
  • @Marcel you need jquery-ui plugin for that to work. just paste this `` after the jquery plugin initialization code – user1 Jul 19 '13 at 14:05
  • @Corey as OP stated in my comment in the question, the for loop executes only when there is new data. So if there is old data the for loop doesn't execute, so it will not get the new class. so only new data will get new class – user1 Jul 19 '13 at 14:10
  • still not working after adding the link after after the jquery plugin initialization code – medzi Jul 19 '13 at 14:17
  • try this: `‌​` – user1 Jul 19 '13 at 14:23
  • ok I fixed it, but now is constantly blinking every single .square div :( – medzi Jul 19 '13 at 14:26
  • Basically, I think the best way would be to check if the image path has changed and based on that do the animation. But I think it has to be done outside the setinterval function otherwise it will run constantly. – medzi Jul 19 '13 at 14:34