3

I am retrieving data from a MySQL database and displaying it on a website using the EventSource API. So far everything is working as expected, but I want to display the data in a fixed height div, and fix the scrollbar to the bottom of this div - i.e always show the latest feed results first.

Now when I load the page the scrollbar is fixed to the top.

I have tried the suggestion here but it doesn't seem work. Is it because I am working with live data and AJAX requests in order to populate the div?

My cose so far is;

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
    <style type="text/css">
        #result {
            overflow: auto;
            max-height:224px;
            width: 500px;
        }   
    </style>
    <script type="text/javascript">
              // scrollbar to bottom
              $("document").ready(function(){
                  var objDiv = document.getElementById("result");
                  objDiv.scrollTop = objDiv.scrollHeight;
              });
              // retrieve data from server and display in div
              $("document").ready(function(){
                  var source = new EventSource("data.php");
                  var offline;
                  $.ajax({
                      type: "POST",
                      url: 'data.php',
                      data: {lastSerial: true},
                      dataType: 'json',
                      success: function(data){
                          $.each(data, function(key, value) {
                              document.getElementById("result").innerHTML += "New transaction: " + value.SerialNo + ' ' + value.TimeStamp + "<br>";
                          });
                         } // end success
                     });
          });//end dom ready
    </script>
</head>
<body>
    <div id="result"><!--Server response inserted here--></div>
</body>
</html>

The strange this is, whenever I remove the live feed javascript and manually add some (lorem ipsum) text into the <div id="result"> it works, the scrollbar appears at the bottom of the div.

I could be doing something very silly :)

Any advice is appreciated.

TheOrdinaryGeek
  • 2,273
  • 5
  • 21
  • 47

4 Answers4

3

When you load more data via ajax, the size of the content will change. Have you tried setting the scroll again after you've rendered the content? i.e.:

  success: function(data){
      var objDiv = document.getElementById("result");

      $.each(data, function(key, value) {
          objDiv.innerHTML += "New transaction: " + value.SerialNo + ' ' + value.TimeStamp + "<br>";
      });
      objDiv.scrollTop = objDiv.scrollHeight;
     } // end success
 });

Thus setting the scroll value the same way you do when the page loads.


Alternatively, here's another completely different option:

If you want the most recent values to be most prominent, you could simply output them in reverse order, so the newest ones are at the top of the div, where the user will see them first. You can use jQuery's .prepend() method to add content to the beginning of the div, above the previous results. Then there's no need for messing about with scrolling. http://api.jquery.com/prepend/ I'd argue this is more user-friendly, but it's up to you obviously.

ADyson
  • 57,178
  • 14
  • 51
  • 63
2

I'm not 100% sure about this but one issue that I see is that you're making an asynchronous AJAX call to the server after you scroll to the bottom of the div.

Maybe try something along the lines of this:

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
    <style type="text/css">
        #result {
            overflow: auto;
            max-height:224px;
            width: 500px;
        }   
    </style>
    <script type="text/javascript">
              // retrieve data from server and display in div
              $("document").ready(function(){
                  var source = new EventSource("data.php");
                  var offline;
                  $.ajax({
                      type: "POST",
                      url: 'data.php',
                      data: {lastSerial: true},
                      dataType: 'json',
                      success: function(data){
                          $.each(data, function(key, value) {
                              document.getElementById("result").innerHTML += "New transaction: " + value.SerialNo + ' ' + value.TimeStamp + "<br>";
                          });
                         var objDiv = document.getElementById("result");
                         objDiv.scrollTop = objDiv.scrollHeight;
                         } // end success
                     });
          });//end dom ready
    </script>
</head>
<body>
    <div id="result"><!--Server response inserted here--></div>
</body>
</html>

Explanation: The div gets populated after you scroll to the bottom of it. Therefore when the scrolling is executed the scrollHeight property is still at the original height value of the div. Now, if you execute the scroll action after you populate the div, it should work fine.

tomcek112
  • 1,516
  • 10
  • 16
2
var objDiv = document.getElementById("result");
objDiv.scrollTop = objDiv.scrollHeight;

that code doesn't say "anchor" the scrollbar to the bottom, it just says scroll down the actual height of the div once, but since you put this code before your ajax request, your div must be empty, so just put theese two lines at the end of your ajax "success" function.

success: function(data){
    $.each(data, function(key, value) {
        document.getElementById("result").innerHTML += "New transaction: " + value.SerialNo + ' ' + value.TimeStamp + "<br>";
    });
    var objDiv = document.getElementById("result");
    objDiv.scrollTop = objDiv.scrollHeight;
}
Neil
  • 390
  • 2
  • 14
1

It was just small line which you were missing, please add below code

 $.ajax({
  type: "POST",
  url: 'data.php',
  data: {lastSerial: true},
  dataType: 'json',
  success: function(data){
      var objDiv = document.getElementById("result");

      $.each(data, function(key, value) {
          objDiv.innerHTML += "New transaction: " + value.SerialNo + ' ' + value.TimeStamp + "<br>";
      });
      objDiv.scrollTop = objDiv.scrollHeight;
     } // end success
 });
spankajd
  • 934
  • 7
  • 13