August 16, 2010

AJAX + PHP + HTML HELP: AJAX refresh ruining layout of site

Question by ritch

Can anyone help me here, when i run this code the page repeats its self. I also need it to refresh which it isnt doing.

Like this:
alt text

EDITED Code Below:

<?php include 'config.php' ?>
<script language="javascript">
function createRequestObject() {

   var req;

   if(window.XMLHttpRequest){
      // Firefox, Safari, Opera...
      req = new XMLHttpRequest();
   } else if(window.ActiveXObject) {
      // Internet Explorer 5+
      req = new ActiveXObject("Microsoft.XMLHTTP");
   } else {
      // There is an error creating the object,
      // just as an old browser is being used.
     alert("Your Browser Does Not Support This Script - Please Upgrade Your Browser ASAP");
   }

   return req;

}

// Make the XMLHttpRequest object
var http = createRequestObject();

function sendRequest(page) {

   // Open PHP script for requests
   http.open('get', page);
   http.onreadystatechange = handleResponse;
   http.send(null);

}

function handleResponse() {

   if(http.readyState == 4 && http.status == 200){

      // Text returned FROM the PHP script
      var response = http.responseText;

      if(response) {
         // UPDATE ajaxTest content
         document.getElementById("msgstatus").innerHTML = response;
      }

   }

}


function repeatloop()
{
sendRequest('test.php'); // replace "inbox-status.php" with your php page's url
setTimeout("repeatloop()", 10000);
}

var replacementDiv = document.createElement("div");
replacementDiv.innerHTML = response;
document.getElementById("msgstatus").innerHTML = replacementDiv.firstChild.innerHTML;

window.onload=function() {
repeatloop();
}
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
</head><body>

<?php // Collet Latest Posts

$query = "
    SELECT Users.UserID, Wall.Message, Users.Forename, Users.Surname 
    FROM Wall
    INNER JOIN Users ON Wall.UserID = Users.UserID
    ORDER BY Wall.MessageID DESC
    LIMIT 20;";
$result = mysql_query($query) or die('Invalid query: ' . mysql_error());

// Collet Post User
    ?>
    <div id ="container">
        <div id="insideleft">
            <ul>
                <li><a href="index.php">Home</a></li>
                <li><a href="profile.php">Edit Profile</a></li>
                <li><a href="wall.php">Community Wall</a></li>
                <li><a href="logout.php">Logout</a></li>
            </ul>
        </div>
        <div id="insideright">
            <h1>Community Wall</h1>
            <br />
            <div id="postcontainer">
                <form method="post" action="wall.php" name="wallpost" id="wallpost">
                    <input type="text" name="message" id="message" class="message" />
                    <input type="submit" name="messagesub" id="messagesub" value="Post Message" class="post"/><br /><br />
                 </fieldset>
                </form>
            </div>
            <span id="msgstatus">
            <?php while ($row = mysql_fetch_assoc($result)) { ?>
            <div id="messagecontainer">
            <img class="pic" src="dummy.gif">
            <p class="messageposter">
            <?php echo "<b>{$row['Forename']} {$row['Surname']}</b><br />"; ?>
            </p>
            <p class="message">
            <?php echo stripslashes($row['Message']); ?>
            </p>
            </div>
            </span>
<?php
} ?>

Answer by Rudu

K so first – as Michael pointed out, you should be using a div for msg status:

Second – assuming the example file is called test.php, you’re loading the entire content of the page back into the msgstatus sub-element (rather than just the SQL). You’d actually be doing this to infinity, except that browsers don’t allow executable code to be posted in an AJAX reply (so the second embedded tier is being ignored).

I’m assuming you’ve simplified out of your code, but following is the updated code based on what you posted. NOTE there’s a bit of a style difference (feel free to ignore ;)!), you also included a BR in p.MESSAGEPOSTER when the paragraph was handling the newline (so I removed it).

<?php 

include 'config.php' 

function latestPosts() {
    $query = "
    SELECT Users.UserID, Wall.Message, Users.Forename, Users.Surname 
    FROM Wall
    INNER JOIN Users ON Wall.UserID = Users.UserID
    ORDER BY Wall.MessageID DESC
    LIMIT 20;";

    $result = mysql_query($query) or die('Invalid query: ' . mysql_error());

    while ($row=mysql_fetch_assoc($result)) {
        echo "<div id="messagecontainer">
    <img class="pic" src="dummy.gif">
    <p class="messageposter">
        <b>".$row["Forename"]." ".$row["Surname"]."</b>
    </p>
    <p class="message">
        ".stripslashes($row["message"]."
    </p>
</div>n";
    }
}


//Test for AJAX on the post - only output the values.
if ($_REQUEST['ajax']==1) {
    latestPosts();
    exit();
}


?>
<script language="javascript">
function createRequestObject() {

   var req;

   if(window.XMLHttpRequest){
      // Firefox, Safari, Opera...
      req = new XMLHttpRequest();
   } else if(window.ActiveXObject) {
      // Internet Explorer 5+
      req = new ActiveXObject("Microsoft.XMLHTTP");
   } else {
      // There is an error creating the object,
      // just as an old browser is being used.
     alert("Your Browser Does Not Support This Script - Please Upgrade Your Browser ASAP");
   }

   return req;

}

// Make the XMLHttpRequest object
var http = createRequestObject();

function sendRequest(page,vars) {

   // Open PHP script for requests
   http.open('get', page+'?'+vars);
   http.onreadystatechange = handleResponse;
   http.send(null);

}

function handleResponse() {

   if(http.readyState == 4 && http.status == 200){

      // Text returned FROM the PHP script
      var response = http.responseText;

      if(response) {
         // UPDATE ajaxTest content
         document.getElementById("msgstatus").innerHTML = response;
      }

   }
}


function repeatloop()
{
    sendRequest('test.php','ajax=1'); // replace "inbox-status.php" with your php page's url
    setTimeout("repeatloop()", 10000);
}

window.onload=function() {repeatloop();}
</script>
<link rel="stylesheet" href="style.css" type="text/css" />
</head><body>
    <div id ="container">
        <div id="insideleft">
            <ul>
                <li><a href="index.php">Home</a></li>
                <li><a href="profile.php">Edit Profile</a></li>
                <li><a href="wall.php">Community Wall</a></li>
                <li><a href="logout.php">Logout</a></li>
            </ul>
        </div>
        <div id="insideright">
            <h1>Community Wall</h1>
            <br />
            <div id="postcontainer">
                <form method="post" action="wall.php" name="wallpost" id="wallpost">
                    <input type="text" name="message" id="message" class="message" />
                    <input type="submit" name="messagesub" id="messagesub" value="Post Message" class="post"/><br /><br />
                 </fieldset>
                </form>
            </div>
        <div id="msgstatus">
<?php
//Output the current posts - you may not even want to do this since AJAX will fill it in right after load
latestPosts();?> 
        </div>
    <!-- ... we have some truncating! -->
?>

Some other points:

If you’re going with an AJAX solution, you might want to consider leaving the box empty in the starting HTML (drop latestsPosts(); at line 118), and then load the list once the page is rendered.

The way this is currently coded, every 10 seconds the complete list is reloaded by AJAX, you may want to track the latest post (perhaps by ID?) and pass that back to the AJAX command so that either:

  1. An update is only provided when there’s been a change. (JS response processing would ignore an empty return – current code would overwrite status with blank)
  2. Only new entries are provided. (JS response processing would prepend the new response to the existing msgstatus object).

Because this is a dynamic AJAX script you should be using the POST verb, not GET (it also requires some changes to how you post variables – the +'?'+vars in the http.open line needs to be in the body instead). Technically GET allows the browser to cache the results – I particularly notice this on Internet Explorer (ironically it seems they followed the W3C spec on this while the others don’t). Long story short – some users may complain the messages don’t stay up to date.

Answer by Starx

Well…… I didn’t read your all post, but when you are loading something through ajax, who only have to load a portion of the layout… not the entire layout itself,,, that would just be wrong…….. and get the effect like in your case.

SO since you are using PHP, try to filter the ajax request and then try to output the required portion only back the JavaScript………..

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!