www.webdeveloper.com
Results 1 to 14 of 14

Thread: Live Updates List Using Ajax

  1. #1
    Join Date
    Dec 2010
    Posts
    232

    Live Updates List Using Ajax

    In my site I allow users to make posts similar to twitters update list these posts are inserted via ajax/php into a mysql database when a user makes them and retrieved in the same way.

    However the user has to refresh the page several times sometimes to see these new updates. I now want to set it up to work in a similar manner to twitter and facebook i.e. a user makes a new post and that post appears live on the 'wall' of updates right at the top.

    Is there any way to do something similar using ajax or javascript? A tutorial that explains this perhaps?

    Any help would be greatly appreciated.

  2. #2
    Join Date
    Mar 2010
    Posts
    128
    It should be relatively simple. I have created an example, but this is very simplified in terms of what your looking for, though it should display the technology your looking for. You will need two scripts, one a server side script which fetches the posts from the database and prints the results to the screen. This will be your data block that we will import into main page. For simplicity, the example I use prints the current time so that you can see the content update with each request of the ajax call.

    Code:
    <?php echo date("H:i:s"); ?>
    In this file you would simply put your post results and print them out. Next is the javascript that will make the asynchronous request to the php file and display the results. On this page you will need a div that contains the content, the other is the snipped of javascript that makes it happen. For simplicity I used the jquery Ajax method.

    Code:
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script>
    	function loadPosts(){
    		$.ajax({
    			url: 'posts.php',
    			success: function(data) {
    				$("#post-list").html(data);
    				setTimeout("loadPosts()", 10000);
    			}
    		});
    	}
    	$(function(){
    		loadPosts();
    	});
    </script>
    <div id="post-list">
        Loading Posts...
    </div>
    So in a nutshell, here is what happens. On page load complete, the loadPosts function is run which contains two things. An ajax request and a setTimeout method. The ajax request makes a call to posts.php, which returns the current time (but in your case would return a list of posts) and the setTimeout function calls the loadPosts method again after 10 seconds, and repeat.

    Hope this helps.

  3. #3
    Join Date
    Dec 2010
    Posts
    232
    Hi rproctor83. Thanks for the reply.

    The problem is in the site I'm making I don't want to have to include the jquery library unless absolutely necessary and would prefer to use pure javascript and ajax if possible.

    Also I would only like to load the latest posts rather than the entire posts list. What you suggested seems to reload the entire posts list. Is this how Twitter and Facebook deal with posts do you know? I thought they only loaded in the last items that were created between the time the user loaded the page and the users new post?

    For example if a user goes onto the site and load the updates page they should be presented with the list of updates as it is at that time. This list should remain static until the user posts a new update as a totally live updates list would be a bit crazy. Then however whenever they post an update it should be inserted along with all the other updates that have been posted by anyone else since they started viewing the page. Does that make sense?

    For example user a goes to the updates page and see all the updates that have been posted by users. Then as he's viewing the page users b and c post updates. Then user a posts his update and then users b and cs updates are shown followed by his new update similar to facebook and twitter.

    Or would reloading such an update list via ajax only load in the new items anyway? I'm just considering performance.
    Last edited by jimmyoneshot; 04-21-2011 at 03:50 PM.

  4. #4
    Join Date
    Dec 2010
    Posts
    232
    Also I've noticed on facebook for example if you are viewing a message thread and when a seperate user that is involved in that thread makes a new post it updates automatically showing their new post to you by adding it to the list of messages in the thread.

    Is this also done via the message thread periodically reloading or some background ajax constantly checking to see if to see if there are any new thread messages or something?

  5. #5
    Join Date
    Apr 2010
    Location
    Salem,Ma
    Posts
    623
    when you post a new message they most likely run the same function during the submit process, as far as "real-time" updates, they pretty much run the ajax call on a timer useing setInterval in most cases.

    the data returned depends completely upon the code in the posts.php file becuase that is what provides JS with the resulting data to display.

    you can find examples all over google in regards to how to do the same job using straight JS instead of Jquery. ( i always use jquery, it's saves a lot of headaches cross browser)


    example that might be helpful to you - http://designgala.com/refreshing-div-content-with-ajax/ - this one is better, also includes adding random data to the request string to get around a page caching issue in internet explorer
    Last edited by DanInMA; 04-21-2011 at 04:37 PM.

  6. #6
    Join Date
    Mar 2010
    Posts
    128
    As far as I know, there is no way to have the server send a request to the client, on a client to send a request to the server. What I mean is this:

    1) UserA views posts.html (page that lists the posts)
    2) UserB makes a new post
    3) On successful post, server sends an update request to ClientA with new post

    What you probably need to do is:

    1) UserA views posts.html
    2) UserA client makes a timed request to check for new posts, no new posts, nothing happens.
    3) UserB makes a new post
    4) UserA client makes a timed request to check for new posts, new post found, new post is returned

    So, what I am trying to explain is that you will need to have the users client constantly checking for updated, like once every 10 seconds or so depending on how fast you want the new posts to show.

    Instead of replacing the post divs contents with the return from the ajax request, you would instead just append/prepend the return onto your list div. You will also need some mechanism for knowing which posts to return from the server side script.

    Hope this makes more sense.

  7. #7
    Join Date
    Dec 2010
    Posts
    232
    @DaninMa - Yes that's a very good idea and I must admit I was having a lot of trouble in IE8 getting the updates list to refresh. Basically the way I have it at the moment is a user posts an update and then when you click the updates tab the updates list refreshes perfectly in chrome showing the newly added item however in IE8 it simply doesn't refresh at all and only the updates since when the user first viewed the updates page are shown no matter how many time you click the update tab. Is this the page cache problem you were speaking of? I'll check out that example you posted

    @rproctor83 - Yep that definitely makes sense. And I've often wondered how the hell does your system know if someone else makes a post directed at you and I think the only way to do it is to be constantly checking for such updates as you said. I suppose the beauty of using ajax for this is that the user front end experience won't be affecting as this is being done in the background.

    I'm wondering how would I stop such a loop though? What I mean is this timeout/constant checking for updates loop should only be taking place when the updates section is being viewed and when the user switches to another section this should sttop. I suppose that's simple enough to do though.

  8. #8
    Join Date
    Mar 2010
    Posts
    128
    Well, this is down to site architecture. If you have 5 pages on your site, and only on one page do you want the updated posts to show then you would only put that code on that single page, that way it is only executed if someone is on that page...

    In regards to IE not showing updates it is because by default IE has its cache set to something like every time the browser loads. There is a setting to change this. Tools > Internet Options > Browser History Settings > Check for newer versions of stored pages > Every time I visit the webpage. This will force IE to stop caching the results.

    Using this ajax request will also force IE to not cache the page, regardless of what it has in its settings.

    Really what your trying to do isn't that difficult. I think the most challenging part will be trying to return the right results from the database. If instead of replacing the post list with the updated results you are trying to only append new posts to the list it will be a difficult process since the server side script which makes the call will not know what to be looking for. I'm thinking to achieve this you may need to pass the ids of the current posts in the list to the script that is making the request for the new list so that the query will know not to select posts which are already there... Its getten a little confusing...

  9. #9
    Join Date
    Mar 2010
    Posts
    128
    Alright, I made a demo of this since I was interested in figuring it out myself. You can see the example at: http://stclement.compucastweb.com/test/ Feel free to enter a couple entries. It will only be online for a day or so and then I will take it down.

    So, the way this works is every 5 seconds an ajax request is made to a server side script, in the case of the demo, fetch.php. The php file serves two main purposes, storing a session and fetching data. The session contains a row count from the entry table. Every time the file is accessed it checks to see if the current row count is equal to your session row count. If they are not equal than the file queries the database for the difference of the new total and your sessions total. Finally it updates your session total with the new total.

    Each time the index page (entry listing page) is loaded it sets the sessions total to 0, ensuring that fetch.php will produce results. When the fetch function runs and successfully returns data it will remove any entry past 10. This is to keep the page from getting ridiculously long. The new entry will be appended to the list and I have it set to fade in purely for aesthetic purposes.

    Also, I used jQuery to tie it all together, feel free to create your own functions for handling the http request and dom manipulation. Below is the source code.

    index.php
    HTML Code:
    <?php
    session_start();
    $_SESSION["total"] = 0;
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Entry list</title>
            <style>
                #list, p, h1{
                    border:1px solid #CCCCCC;
                    padding:10px;
                    margin:10px;
                }
                #list p{
                    display:none;
                }
            </style>
            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
            <script>
                function fetch(){
                    $.ajax({
                        url: 'fetch.php',
                        success: function(data) {
                            $("#list").prepend(data);
                            if($("#list p").length > 10){
                                $('#list p:gt(9)').remove();
                            }
                            $("#list p").fadeIn();
                            setTimeout("fetch()", 5000);
                        }
                    });
                }
                $(function(){
                    fetch();
                });
            </script>
        </head>
        <body>
            <h1>Entry List</h1>
            <p>Entries are updated every 5 seconds. A max total of 10 entries can be shown at a time. The newest entries are shown first, if a new entry makes the list extend past 10 then the oldest entry will be removed from the bottom and the new entry will be appended to the top. Feel free to add a new entry in a new tab, once you submit it the entry will be shown ~5 seconds later in the list for users who are currently viewing the listing page, otherwise it will show imediately on page load.</p>
            <p>&raquo; <a href="submit.php" target="_blank">Add a new Entry</a></p>
            <div id="list">
                <p>Loading...</p>
            </div>
        </body>
    </html>
    fetch.php
    PHP Code:
    <?php
    session_start
    ();
    include(
    $_SERVER['DOCUMENT_ROOT']."/config.php");

    $sql "SELECT COUNT(`entry_id`) AS total_entries
            FROM `entries`"
    ;
    $result mysql_fetch_assoc(mysql_query($sql));
    $total_entries $result["total_entries"];

    if(
    $_SESSION["total"] != $total_entries){
        
    $limit $total_entries $_SESSION["total"];
        
    $sql "SELECT *
                FROM `entries`
                ORDER BY `entry_id` DESC
                LIMIT "
    .$limit;
        
    $result mysql_query($sql);
        if(
    mysql_num_rows($result)>0){
            while(
    $row mysql_fetch_assoc($result)){
                echo 
    "<p>".$row["entry_title"]."</p>";
            }
        }
        
    $_SESSION["total"] = $total_entries;
    }
    ?>
    And, if your curious, the source for submit.php
    Code:
    <?php
    include($_SERVER['DOCUMENT_ROOT']."/ccms_config.php");
    include($admin_sys_path."/functions.php");
    $msg = "";
    if(isset($_POST["submit"])){
        $sql = "INSERT INTO entries
                (`entry_title`)
                VALUES
                ('".secure($_POST["title"])."')";
        mysql_query($sql);
        $msg = "<p>Success! Entry submitted.</p>";
    }
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Submit</title>
            <style>
                fieldset, p, h1{
                    border:1px solid #CCCCCC;
                    padding:10px;
                    margin:10px;
                }
            </style>
        </head>
        <body>
            <h1>Submit an Entry!</h1>
            <?php if(!empty($msg)){ echo $msg; } ?>
            <form method="post" action="submit.php">
                <fieldset>
                    <legend>Entry Form</legend>
                    <label for="title">Test Title:</label>
                    <input type="text" name="title" />
                    <input type="submit" name="submit" value="Submit" />
                </fieldset>
            </form>
        </body>
    </html>
    Hope this is helpful.
    Last edited by rproctor83; 04-21-2011 at 08:34 PM.

  10. #10
    Join Date
    Dec 2010
    Posts
    232
    That is excellent rproctor. Thanks so much for that

    I'm going to use that code in my site if it's ok and once I've edited it to use javascript and no jquery I'll post it here or send it to you.

    I really like the fade in effect when each item is added. Is that easy to emulate with javascript?

    I'm thinking I could use that in my messages section i.e. if a user is reading a message and another user posts a new message it adds the new message live whereas my updates will be static until the current user posts a new update.

    I think that's the best way because if a user is interacting with one of the updates in some way and a new update is added then the list will move down and they may click on the wrong update which could prove embarassing in some cases ha.

  11. #11
    Join Date
    Apr 2010
    Location
    Salem,Ma
    Posts
    623
    @rproctor - very similiar to how I do it but my environment is ASP instead of php.
    Quick question, how are you addressing the page cache issue in IE? Most users cannot be bothered to change internal browser settings so for some it will still arise as an issue. I typically just add a random value in the querystring ( most users on our intranet are using ie6 or 7)

    the following usually is sufficient for myself
    Code:
                function fetch(){
                 var randval = math.random();      
                    $.ajax({
                        url: 'fetch.php?='+randval,

  12. #12
    Join Date
    Mar 2010
    Posts
    128
    @Jimmy, I hope that the code helps you out. I will likely be using this on some sites as well, though I will stick with jQuery. Why is it exactly you want to avoid jQuery? It's a great framework, lightweight (usually even cached by goog) and has a giant community. You could easily write your own ajax request, the animation might be a little more tricky, and the managing the dom shouldn't be too difficult. But, remember that jQuery for the most part is cross browser stable. So, write less, do more

    @Dan, I am not sure that IE has a problem caching the ajax request, in my tests with IE even when I turn the cache to never update I still see the new entries show up as they are supposed to. Are you having problems viewing the entries in IE? Also, I am not too familiar with the inner workings of the IE cache, but something is telling me dynamic pages like php are less likely to get stuck in the cache than something like an html file.

  13. #13
    Join Date
    Nov 2012
    Posts
    1

    two queries per 1000s

    I know the thread is old but it helped me a lot. I have this code:
    http://pastebin.com/G75CFDxc
    But the code does two queries and loads the ajax php script two times before going to the time out and saving the last time. What is wrong?
    Thank you

  14. #14
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by rproctor83 View Post
    And, if your curious, the source for submit.php
    Code:
    <?php
    include($_SERVER['DOCUMENT_ROOT']."/ccms_config.php");
    include($admin_sys_path."/functions.php");
    $msg = "";
    if(isset($_POST["submit"])){
        $sql = "INSERT INTO entries
                (`entry_title`)
                VALUES
                ('".secure($_POST["title"])."')";
        mysql_query($sql);
        $msg = "<p>Success! Entry submitted.</p>";
    }
    Hope this is helpful.
    i don't want to be a bummer, but that code is WIDE open for having your whole database table dropped from a basic sql injection.

    also, the naive regurgitation of user-submitted data means your users are wide open to onmouseover xss attacks.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles