skip to Main Content

I have asked this question before also, but the solution didn’t work. I have a messaging website. I fetch the messages via AJAX with Java Script that runs per 1 second. The problem is that it fetch all the values from starting to end. So I thought of passing the last message ID via AJAX. But I don’t know how to use that value in the Java Script, so that I can use it to fetch the messages which will be more than it.

Also I want the div to be in it’s bottom position, until the user scrolls it. And whenever a new message is fetched the div should automatically reach the bottom.

Here is my CSS, HTML, Java Script and AJAX code:

<style>
.readarea{
  padding: 10px;
  margin-top: 10px;
  background-color: #FFFFFF;
  height: 450px;
  overflow-x: hidden;
}
</style>

<body>

<div class="readarea" id="readarea">

<!--Messages is to be displayed here.-->

</div>

<div class="inputarea">
<textarea placeholder="Type your message" style="width: 800px; overflow: hidden" id="msg"></textarea>
<input type="submit" value="Send" style="padding: 10px 25px" id="sendmsg">
</div>
</body>

<script>

function fetchdata(){
var lm =                                        //last message ID
var cuser =                                     //user ID of the 1st person
var ouser =                                     //user ID of the 2nd person
 $.ajax({
  url: "readmessagesprocess.php",
  type: "POST",
  data : {cuser:cuser, ouser:ouser, lm:lm},
  success: function(read){
    $("#readarea").html(read);
  }
 });
}

$(document).ready(function(){
 setInterval(fetchdata,1000);
});


</script>

Here is my PHP code to fetch the messages:

<?php

$cuser = mysqli_real_escape_string($conn,$_POST['cuser']);
$ouser = mysqli_real_escape_string($conn,$_POST['ouser']);
$lastmessage = mysqli_real_escape_string($conn,$_POST['lm']);

$sql = "SELECT id, fromid,message,toid FROM messages WHERE ((fromid={$cuser} AND toid={$ouser}) OR (fromid={$ouser} AND toid={$cuser})) AND id>{$lastmessage}";
$result = mysqli_query($conn, $sql) or ("Query Failed");

while($row=mysqli_fetch_assoc($result)){
  if($row["fromid"]==$cuser){
    echo "<div class='cuser'>".$row["message"]."</div>";
  }else{
    echo "<div class='ouser'>".$row["message"]."</div>";
  }
  $lm = $row["id"];                                                       //last message id
}
?>

Here I want the $lm("lm") to use in Java Script as the last message ID (var lm) and the rest of the code to concatenate in the . Also I want this div to be in the bottom part when the page loads or new message is fetched.

2

Answers


  1. I have turned your code into a working chat-snippet. I am using a slightly quirky method for mimicking an external PHP server, that would be handling the actual chat data in a database. I realize that parts of my script will seem terse and even cryptic. So, here are a few rudimentary explanations:

    The code starts with an IIFE, an "immediatel invoked functional expression". This expression provides a scope for setting up a "chat database", i. e. the object msg with a first message in it. This msg object is visible for the functions setmsg() and getmsg() which I also define in the same scope through w[setm]=... (w and setm are arguments of the IIFE and set to window and 'setmsg' when the IIFE is called) and w[getm]=....

    The function qs() is simply a shorthand notation for calling document.querySelector() which I find a bit clunky to hanlde. The optional argument el makes it possible to search within an element context. Without it the search starts on the document level.

    Oh, yes, and the blb() function is a little trick I picked up here. Stackoverflow does not provide a way of doing CORS Ajax calls and this method is a workaround that allows at least GET calls (you cannot POST to the URL.createObjectURL() object). The functions getmsg() and setmsg() use this blb() utility to mimick an external server. They return an object that can be used in place of a server-URL that is usually supplied in the jQuery Ajax call.

    // for AJAX testing: set up a setter, a getter and a utility "querySelector" function qs:
    ((w,setm,getm,qs)=>{ 
     const blb=da=>URL.createObjectURL(new Blob([JSON.stringify(da)],{type: "text/json"}));
     const msg=[{cuser:'abc', ouser:'def', txt:'the first message'}];
     w[setm]=da=>(msg.push(da), blb({lm:msg.length}));  // setter ajax function
     w[getm]=lm=>blb(msg[lm]);                          // getter ajax function
     w[qs]=(s,el)=>(el||document).querySelector(s);     // query Selector with context 
    })(window,'setmsg','getmsg','qs');
    
    function fetchdata(){
     let lm = +(qs("li:last-child")||{dataset:{id:-1}}).dataset.id + 1;
     $.ajax({
      url: getmsg(lm),           //  "readmessagesprocess.php",
      type: "GET",               //  "POST", data : ...
      success: dat=>dat.cuser && //  action ONLY if dat.cuser exists!
        $("#readarea").append(`<li data-id="${lm}">${lm}: ${dat.cuser} says: ${dat.txt}</li>`)
     });
    }
    
    var intFD; // setInterval handle
    const scanStart=()=>(intFD=setInterval(fetchdata,1000));
    $(document).ready(function(){
     scanStart();
     qs('#resume').onclick=scanStart;
     qs('#stop')  .onclick=()=>clearInterval(intFD);
     qs('#send')  .onclick=()=>{
       $.getJSON(setmsg({cuser:'cars10m',txt:qs('#msg').value}), 
          function(da){console.log('server response: message count='+da.lm)} );
       qs('#msg').value="";
     }
    })
    .readarea{
      padding: 10px;
      margin-top: 10px;
      background-color: #FFFFFF;
      height: 150px;
      overflow-x: hidden;
    }
    button, [type=submit] {padding: 10px 25px}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul class="readarea" id="readarea"></ul>
    
    <div class="inputarea"><p>... and this is the input area.</p>
    <textarea placeholder="Type your message" style="width: 800px; overflow: hidden" id="msg"></textarea><br>
    <input type="submit" id="send" value="send"/>&nbsp;&nbsp;
    <button id="stop">stop</button>
    <button id="resume">resume</button>
    </div>

    A few word on how the chat system works: the regular message scan starts once the page is loaded with scanStart(). This function in turn calls fetchdata() which will try to find the id of the latest post that is already shown on the browser. I used the CSS selector "li:last-child" for this purpose. Unlike in the original version I am using <li> elements for each post here. And the above selector will get the last one posted. I then grab its id and put it in lm (lm is always the message index of the last message found in msg plus 1) and start the $.ajax() call to getmsg() with lm.

    The buttons [stop] and [resume] can be used to stop and resume the message scanning.

    Login or Signup to reply.
  2. this shouldn’t be done via AJAX, but with sockets. have your favourite websearch give you results for "nodejs chat"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search