Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery and PHP unique Chat window for each user and database saved chat history

Tags:

jquery

php

I managed to create the chat windows open uniquely depending on what user is clicked but I cannot send messages on any chat window except the first one.

I am trying to achieve this: enter image description here

I am trying to achieve exactly that ^

Here is what I have so far:

<script> //CHAT SYSTEM
    function chatWith(id, status, username){ 
        $("#chats").append('<div class="chat_window" id="chat_'+id+'"><div class="chat_top"><span class="chat_username">'+status+username+'</span><span class="chat_x"><a href="javascript:void(0)" onclick="minChat('+id+')">-</a> <a href="javascript:void(0)" onclick="closeChat('+id+')">X</a>  </span> </div>  <div class="chat_content"></div> <form method="post" name="chat" action=""> <textarea class="chat_text" maxlength="200" name="chat_text" id="chat_text_'+id+'" placeholder="Start typing..."></textarea> </form> </div></dv>'); 
        $("#chat_"+id).slideToggle("fast");             
    } 

    //send messages
    var user_id = '<?php echo $session_user_id;?>';
    var auto_refresh = setInterval(function () {
        var b = $("#chat_"+user_id+":last").attr("id");     
        $.getJSON("chat.php?user_id="+user_id,function(data){
            $.each(data.posts, function(i,data) {               
                if(b != data.id)  { 
                    var div_data="<span id='"+data.id+"'>"+data.user_id+": "+data.msg+"</span>";                        
                    $(div_data).appendTo("#chat_"+user_id);
                }
            });
        });
    }, 2000);   
    $(document).ready(function(){
        $(document).keypress(function(e) {
            if(e.which == 13) {
                var boxval = $(".chat_text").val();                 
                var user_id = '<?php echo $session_user_id;?>';
                var dataString = 'user_id='+ user_id + '&msg=' + boxval;

                if(boxval.length > 0) { 
                    $.ajax({
                        type: "POST",
                        url: "chat.php",
                        data: dataString,
                        cache: false,
                        success: function(html){                     
                            $(".chat_content").append(html);
                            $(".chat_text").val('');
                            $(".chat_text").focus();
                            $(".chat_content").animate({scrollTop: $(".chat_text").offset().top}, 500);
                        }
                    });             
                }
                return false;
            }
        });
    });

</script>

this is my chat.php

  if($_POST){
    $user_id = $_POST['user_id'];
    $msg = $_POST['msg'];

    mysql_query("INSERT INTO chat(user_id, msg) VALUES ('$user_id', '$msg')");

    $chat_results = mysql_fetch_assoc(mysql_query("SELECT * FROM `users` WHERE user_id='".$user_id."' LIMIT 1"));

    echo '<span style="font-size:0.9em;font-weight:bold;">'.$chat_results['username'].'</span>: <span style="font-size:0.9em;">'.$msg.'</span><br>';
}
if($_GET['user_id']){
    $user_id=$_GET['user_id'];
    $row=mysql_fetch_array(mysql_query("SELECT * FROM chat order by id desc limit 1"));
    $user_idx = $row['user_id'];
    $id = $row['id'];
    $msg = $row['msg'];
    if($user_idx != $user_id){
        echo '{"posts": [{  "id":"'.$id.'", "user_id":"'.$user_idx.'", "msg":"'.$msg.'" },]}';
    } 
}

and the div it all opens on:

<div id="chats"> 

</div>

Will really appreciate any help, been breaking my head on this for weeks now!

like image 213
Gadgetster Avatar asked Mar 26 '14 06:03

Gadgetster


3 Answers

your problem is here:

            var boxval = $(".chat_text").val(); //<-- here it is                
            ...

            $(".chat_content").append(html);//<-- here it is  
            $(".chat_text").val('');//<-- here it is  
            $(".chat_text").focus();//<-- here it is  
            $(".chat_content").animate({scrollTop: $(".chat_text").offset().top}, 500);//<-- here it is  

its obvious that each "chat window" has the classes ".chat_content",".chat_text"

so how should your js be able to guess which one is the right ? So it obviously takes only the first occurrence what would explain it works only in the first window.

So 1000 ways to Rome

i will recommend one:

at very first correct the chatWith append, the last

 </dv>

is unnesesary and must be removed

function chatWith(id, status, username){ 
    $("#chats").append('<div class="chat_window" id="chat_'+id+'"><div class="chat_top"><span class="chat_username">'+status+username+'</span><span class="chat_x"><a href="javascript:void(0)" onclick="minChat('+id+')">-</a> <a href="javascript:void(0)" onclick="closeChat('+id+')">X</a>  </span> </div>  <div class="chat_content"></div> <form method="post" name="chat" action=""> <textarea class="chat_text" maxlength="200" name="chat_text" id="chat_text_'+id+'" placeholder="Start typing..."></textarea> </form> </div>'); 
    $("#chat_"+id).slideToggle("fast");             
} 

then you first need to send the correct value you rather delegate the keypress to the textareas and not the document like

$(document).on('keypress','.chat_text',function(e){ //<-- heres the event context passed as argument now, just like you did (copy) yourself
  if(e.which == 13) {
    //wow,now you have the correct textarea in this-context 
    //dont loose it 
    $current=$(this);
    var boxval = $current.val();
    // and prove it!!
    console.log("the currently entered text is: "+boxval);

    //should be correct, now the requesting and appending part
    var user_id = '<?php echo $session_user_id;?>';
    var dataString = 'user_id='+ user_id + '&msg=' + boxval;
    // prove it ! 
    console.log("dataString is: "+dataString+" and therefore correct");
    if(boxval.length > 0) { 
       $.ajax({
            type: "POST",
            url: "chat.php",
            data: dataString,
            cache: false,
            success: function(html){  
                    // better prove if user_id is really correct:
                    console.log("box that will be filled is from user id: "+html.user_id);   
                    // now you have the userid on which you can match to the 
                    // id of the generated chat windows like in answer above mentioned                   
                    $boxToBeFilled=$("#chat_" + html.user_id);

                    $boxToBeFilled.append(boxval);
                    $boxToBeFilled.find('textarea').val('').focus();
                    $boxToBeFilled.children(".chat_content").animate({scrollTop: $(this).find(".chat_text").offset().top}, 500);
            }
        });             
    }
 } 
});

there you go

like image 173
john Smith Avatar answered Oct 13 '22 20:10

john Smith


I had a similar kind of problem when i was making a comment system on my website.

The first thing.

You are appending the content in the divs having same class attributes.

Change the class attributes like this

<script> //CHAT SYSTEM
function chatWith(id, status, username){ 
    $("#chats").append('<div class="chat_window_'+id+'" id="chat_'+id+'"><div class="chat_top_'+id+'"><span class="chat_username">'+status+username+'</span><span class="chat_x"><a href="javascript:void(0)" onclick="minChat('+id+')">-</a> <a href="javascript:void(0)" onclick="closeChat('+id+')">X</a>  </span> </div>  <div class="chat_content_'+id+'"></div> <form method="post" name="chat" action=""> <textarea class="chat_text_'+id+'" maxlength="200" name="chat_text" id="chat_text_'+id+'" placeholder="Start typing..."></textarea> </form> </div></div>'); 
    $("#chat_"+id).slideToggle("fast");             
} 

//send messages
var user_id = '<?php echo $session_user_id;?>';
var auto_refresh = setInterval(function () {
    var b = $("#chat_"+id).attr("id");     
    $.getJSON("chat.php?user_id="+user_id,function(data){
        $.each(data.posts, function(i,data) {               
            if(b != data.id)  { 
                var div_data="<span id='"+data.id+"'>"+data.user_id+": "+data.msg+"</span>";                        
                $(div_data).appendTo("#chat_"+id);
            }
        });
    });
}, 2000);   
$(document).ready(function(){
    $(document).keypress(function(e) {
        if(e.which == 13) {
            var boxval = $(".chat_text_'+id+'").val();                 
            var user_id = '<?php echo $session_user_id;?>';
            var dataString = 'user_id='+ user_id + '&msg=' + boxval;

            if(boxval.length > 0) { 
                $.ajax({
                    type: "POST",
                    url: "chat.php",
                    data: dataString,
                    cache: false,
                    success: function(html){                     
                        $(".chat_content_'+id+'").append(html);
                        $(".chat_text_'+id+'").val('');
                        $(".chat_text_'+id+'").focus();
                        $(".chat_content_'+id+'").animate({scrollTop:    $(".chat_text_'+id+'").offset().top}, 500);
                    }
                });             
            }
            return false;
        }
    });
});

like image 44
lakshya_arora Avatar answered Oct 13 '22 18:10

lakshya_arora


I will answer your questions one by one as follow.

I managed to create the chat windows open uniquely depending on what user is clicked but I cannot send messages on any chat window except the first one.

When you attempt to append a message you should assign the content to a specific Chat Box. Let's first have an unique ID attribute for each chat_window class like:

<div id="chats"> 
<div class="chat_window" id="chat_4321"></div> 
</div>

This way you know exactly what windows are specific to what users. Returning a JSON of POST Request, you tell to client that the content needs to append to your ID only:

if($_POST){
    $user_id = $_POST['user_id'];
    $msg = $_POST['msg'];
    mysql_query("INSERT INTO chat(user_id, msg) VALUES ('$user_id', '$msg')");

    $chat_results = mysql_fetch_assoc(mysql_query("SELECT * FROM `users` WHERE user_id='".$user_id."' LIMIT 1"));
    $json_response = [
      'user_id' => $user_id,
      'user_name' => $chat_results['username'],
      'message' => $msg
    ];
    echo json_encode($json_response);
}

And your JavaScript

if(boxval.length > 0) { 
                    $.ajax({
                        type: "POST",
                        url: "chat.php",
                        data: dataString,
                        cache: false,
                        success: function(json){                     
                            $("#chat_" + json.user_id).append(boxval); // Or json.message
                            $("#chat_" + json.user_id).find('textarea').val('').focus();
                            $("#chat_" + json.user_id).children(".chat_content").animate({scrollTop: $(this).find(".chat_text").offset().top}, 500);
                        }
                    });             
                }

This depends on how you format that boxval variable and of course there are many ways you can achieve your needs. But before having this Chat System I recommend you to take a look at some APIs like PubNub or Pusher and also concepts like Long Polling, WebSockets, Node.js, Comet. However if you got misunderstandings feel free to ask.

Good luck!

like image 37
Eugen Zaharia Avatar answered Oct 13 '22 20:10

Eugen Zaharia