views:

48

answers:

2

Hi, i have a "wall" on each profile, and i wish to make it smarter, so you don't need to update the page to view your inserted message you just put up.

When you insert a message, it makes a ajax call and inserts to the database, and you receive a message about it has been inserted. But right now you need to refresh the page to see your inserted message. What i want to do is if you insert a new message, it should fadein /refresh the wall with messages that is right under the form. How can I do this?

I have worked on it alittle and tried to make a new file, inserted all coding to show comments and then i set timeout to refresh each 2 seconds

 function ajax_update() {
    var wrapperId = '#box';
    var profileID = document.getElementById('profileID');
    var postFile = 'showcomments.php?id='+ profileID.value;

    _v++;
    _v2++;

    $.post(postFile, { v2: _v2 , v: _v},
      function(data){
        $(wrapperId).html(data);
      });
    setTimeout('ajax_update()', 2000);
  }   

but this isnt good, as it makes too many server calls, so hope you can help me out, since i dont know how i should do this in a cool way

Form with ajax call: http://phpbin.net/x/838833504

And my current php code that grab from db and list in messages: http://phpbin.net/x/2145692361

+2  A: 

One way is to return the newly updated wall listing from your .post() handler on the server. Then in the callback, repaint the wall area with that content (forget about using setTimeout()). You could also do the same thing, but working message by message, adding the latest message to the top of the "stack" in your wall content area.

So, repainting the whole wall:

$.post(postFile, { v2: _v2 , v: _v},
  function(data){
    // make your server return the updated wall content
    // return data.whatever
    //        data.wallcontent
    $('#wrapperId').html(data.wallcontent);
});

or message by message:

$.post(postFile, { v2: _v2 , v: _v},
  function(data){
    // make your server return the new message ready for insert
    // return data.whatever
    //        data.message_you_just_posted_formatted
    $('#wrapperId')
      .prepend( data.message_you_just_posted_formatted );
});

That's the basic idea.

Ken Redler
make this a json call, and add whether the insert was a success, and don't forget to test it on the return (which is different than error on the call itself).
Liorsion
I outlined the same concept in my answer but I don't have the time right now to fill in with the actual code. +1 for you @`Ken Redler`.
samandmoore
Im lost, I dont understand how you want me to do it, i tried read over and over again but maybe its because of my english isnt that great. Where do the PHP fit in? And the form? In a minute, im going to update my question with my form + ajax call + the coding grab from db and lists the messages.
Karem
@Karem: once you add the rest of the code we can hopefully give you a complete solution.
samandmoore
@samandmoore : I have added it now, hope you can help me out im really trying to figure and understand it.
Karem
Your php file receives the `.post()`. It inserts the posted data to the database (although I don't see this happening in your pastebin). Once this succeeds, you can 1) return a success code from the php script and `.prepend()` entirely with jQuery in your success handler; or 2) return a blob of text from the php script and then `.prepend()` that (if for example you need to do special formatting first on the server); or 3) return the whole newly updated wall, and use `.html()` in the `.post()` success handler to re-paint the entire wall container. There are a number of ways to do this.
Ken Redler
@Ken Redler if i would like to do 3) repaint the whole wall container, with .html() how should i do this? Should i then have the wall on another page to be able to load the wallcontainer again and .html it into a <div id="box"></div>? or is there a smarter way?
Karem
Karem, there's no one best way to do it. Sometimes it makes sense to build data structures on the server, send them to the client as JSON, then do the formatting there. Or, you can render up a block of complete html on the server, return it as a blob of text, then plop that into a big container with `.html()`. Avoid repeating yourself, so if you have a block of php code that builds the wall, another option is to make ALL wall drawing via ajax -- even the initial page load. Make a `getWallContent()` function, and call it both on page load, and in the success callback of your `.post()`.
Ken Redler
+1  A: 

I would suggest a slight methodology change:

  1. submit the new post to the database via AJAX
  2. in the success callback for that AJAX post, create an element with the content that was submitted and append it to the list of posts on the page.
  3. if you want it to look cool just use some of the built in animation effects (fadeIn, show, etc).

This way, you're not polling for changes all the time, and you only have to request things from the server upon page loads.

function DoWallInsert(){

  var wrapperId = '#box';
  var profileID = document.getElementById('profileID');
  $("#insert_response").html("Laddar..");

  $.ajax({ 
   type: "POST",
   url: "misc/insertWall.php",
   data: {
       value: 'y',
       BuID : $('#BuID').val(),
       uID : $('#uID').val(),
       message : $('#message').val() 
   },
   success: function(msg){
       // in here you will have to add the message to the top of the list of wall posts
       // to do this you use prepend whatever html and the message in whatever way you 
       // are using to display the messages.
       $(wrapperId).prepend("<div>" + $('#message').val() + "</div>");
   }
 });
}

html might look like this before:

<form action="javascript:DoWallInsert()" method="post">
    <input name="message" type="text" id="message" value="" size="40">
    <input type="hidden" name="BuID" id="BuID" value="123123">
    <input type="hidden" name="uID" id="uID" value="53425">
    <input name="submit" type="submit" id="submit" value="Skicka">
</form>

<div id="box">
    <div id="post-1">Some stuff</div>
    <div id="post-2">Some other stuff</div>
</div>

html should look like this after:

<form action="javascript:DoWallInsert()" method="post">
    <input name="message" type="text" id="message" value="" size="40">
    <input type="hidden" name="BuID" id="BuID" value="123123">
    <input type="hidden" name="uID" id="uID" value="53425">
    <input name="submit" type="submit" id="submit" value="Skicka">
</form>

<div id="box">
    <div>Whatever was typed in the box</div>
    <div id="post-1">Some stuff</div>
    <div id="post-2">Some other stuff</div>
</div>

If the html you want to append to the list of posts has php in it then my best suggestion is to return the html for the new div in the response from the server on the on the AJAX call to this: misc/insertWall.php

insertWall.php should return "<a href='profil.php?id=".$userinfo[id]."'>".$userinfo["full_name"]."</a>". then you can process it and display it in the success part of DoWallInsert():

   success: function(msg){
       // in here you are receiving a response, you should display it in the page
       // this assumes that you are fully formatting the message before returning it
       // and you just want to insert it here.
       $(wrapperId).prepend(msg);
   }
samandmoore
@samandmoore , please check this: its my form with the ajax call:http://phpbin.net/x/838833504 so you mean in msg == 1 { with "sucess calback" but i dont know how to create an element and append it to the lists of posts on the page. The lists of posts on the page is in PHP with a while(http://phpbin.net/x/2145692361), so how should i do that? thank you
Karem
@samandmoore with your updated answer, i have a question, the "added" message will then not look like the rest?
Karem
@Karem, in my example it won't but if you take what I wrote and then style it the way you desire the message to look then it will. I do not know what your messages are supposed to look like so I just did a simple `example`.
samandmoore
@samandmoore Ok i will give this a try, thank you i come back later
Karem
@samandmoore What if my div contains php coding, such as link to profile: echo "<a href='profil.php?id=".$userinfo[id]."'>".$userinfo["full_name"]."</a>"; ?
Karem
@ Karem: then you have two options, I will add them to my solution.
samandmoore
@samandmoore thank you, this is working good. Can i add a fadein effect to this and how? last question before im accepting
Karem
@Karem: you would have to do something like add `style="display:none"` to the main element that you're returning to the success function. then after `$(wrapperId).prepend(msg);` you'd do `$(wrapperId).children().first().fadeIn('slow');`
samandmoore
it would be better to condense that statement to a more specific selector but I don't know what your html will look like so I can't really do that for you.
samandmoore
sorry forgot to accept your answer. Thank you for your time and help!!
Karem