I am trying to create a system to display messages on 2 or more separate chats( with different messages stored in a db) on the same page. The chats each have ids to differentiate them and I have created a function to go through each chat in use and print the approprite messages for them but only 1 chat gets the messages. The Code: The HTML
<div class="full_wrap">
<div class="force-overflow"></div>
<div id="Sidenav" class="side">
<h2>Chat Settings & Info</h2>
<a id="closebtn" href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
<div class="authr">
<a>
<div class="authr_img"></div>
</a>
<form action="mypage.php" method="post">
<div class="authr_name">
<button value="<?php echo $chat_authr ?>" name="userlink" class="subm_as_text"><?php echo $chat_authr; ?></button>
</div>
</form>
</div>
<div class="chat_info">
<div class="chat_descy">
<h2>Chat Description</h2>
<div class="descc">
<h3><?php echo $chat_description; ?></h3>
</div>
</div>
<div class="chat_fol"><h2>Chat users: <?php echo $num_users; ?></h2></div>
<div class="chat_back">
<h2> Change Chat Wallpaper</h2>
<form method="post" action="picture.php" enctype="multipart/form-data">
<input type="file" id="upload" class="custom-file-input" name="chat_wall">
<input type="submit" class="chat_wall_subm" value="Change"/>
</form>
</div>
</div>
<form method="post" action="chat.php" >
<!--<input type="submit" class="chat_leave" name="" value="Leave Chat">-->
<button class="chat_leave" name="chat_leave" value="<?php echo $chat_index; ?>" >Leave Chat</button>
</form>
</div>
<div class="mnav">
<span onclick="openNav()">☰</span>
<i class="material-icons" id="chat_un_small" onclick="chat_un_small()">arrow_upward</i>
<h1><?php echo $chat_title ?></h1>
</div>
<!--one ting-->
<div class="conceal_wrapper">
<div class="msgs" id="5e2dbe2be3b5927c588509edb1c46f7d">
</div>
<form method="post" id="form_5e2dbe2be3b5927c588509edb1c46f7d" class="comform">
<div class="wcom" >
<input maxlength="140" type = "text" id="5e2dbe2be3b5927c588509edb1c46f7d" class="comin" placeholder="My message..." name="sendmsg" autocapitalize="off" autocorrect="off"/>
<input class="hidden_index" type="text" value="5e2dbe2be3b5927c588509edb1c46f7d" name="chat_index"/>
</div>
</form>
</div>
<div class="chat_enlarge">
<div class="chat_enlarge_full" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_full()"></div>
<div class="chat_enlarge_standard" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_standard()"></div>
<div class="chat_enlarge_small" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_small()"></div>
</div>
</div>
<div class="full_wrap">
<div class="force-overflow"></div>
<div id="Sidenav" class="side">
<h2>Chat Settings & Info</h2>
<a id="closebtn" href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
<div class="authr">
<a>
<div class="authr_img"></div>
</a>
<form action="mypage.php" method="post">
<div class="authr_name">
<button value="<?php echo $chat_authr ?>" name="userlink" class="subm_as_text"><?php echo $chat_authr; ?></button>
</div>
</form>
</div>
<div class="chat_info">
<div class="chat_descy">
<h2>Chat Description</h2>
<div class="descc">
<h3><?php echo $chat_description; ?></h3>
</div>
</div>
<div class="chat_fol"><h2>Chat users: <?php echo $num_users; ?></h2></div>
<div class="chat_back">
<h2> Change Chat Wallpaper</h2>
<form method="post" action="picture.php" enctype="multipart/form-data">
<input type="file" id="upload" class="custom-file-input" name="chat_wall">
<input type="submit" class="chat_wall_subm" value="Change"/>
</form>
</div>
</div>
<form method="post" action="chat.php" >
<!--<input type="submit" class="chat_leave" name="" value="Leave Chat">-->
<button class="chat_leave" name="chat_leave" value="<?php echo $chat_index; ?>" >Leave Chat</button>
</form>
</div>
<div class="mnav">
<span onclick="openNav()">☰</span>
<i class="material-icons" id="chat_un_small" onclick="chat_un_small()">arrow_upward</i>
<h1><?php echo $chat_title ?></h1>
</div>
<!--one ting-->
<div class="conceal_wrapper">
<div class="msgs" id="9503e253936e716f18d9c57b4f97d618">
</div>
<form method="post" id="form_9503e253936e716f18d9c57b4f97d618" class="comform">
<div class="wcom" >
<input maxlength="140" type = "text" id="9503e253936e716f18d9c57b4f97d618" class="comin" placeholder="My message..." name="sendmsg" autocapitalize="off" autocorrect="off"/>
<input class="hidden_index" type="text" value="9503e253936e716f18d9c57b4f97d618" name="chat_index"/>
</div>
</form>
</div>
<div class="chat_enlarge">
<div class="chat_enlarge_full" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_full()"></div>
<div class="chat_enlarge_standard" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_standard()"></div>
<div class="chat_enlarge_small" onmouseover="chat_action(this)" onmouseout="chat_action_negative(this)" onclick="chat_enlarge_small()"></div>
</div>
</div>
So there are 2 chats separated by the full_wrap class. The msgs have different id for the chat index stored unique for each chat in the db
The Javascript:
$( document ).ready(function() {
chat_receivemsgs();
});
function chat_receivemsgs(){
var cusid_ele = document.getElementsByClassName('msgs');
if(cusid_ele.length == 0) {
console.log("hi");
} else {
for (var i = 0; i < cusid_ele.length; ++i) {
var item = cusid_ele[i];
var item_id = item.id;
console.log(cusid_ele.length);
for (var i = 0; i < cusid_ele.length; ++i) {
var item = cusid_ele[i];
var item_id = item.id;
console.log(item_id);
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("yes");
console.log(item_id);
// document.getElementById(item_id).innerHTML = this.responseText;
$("#"+item_id).html(this.responseText);
}else{
console.log("no");
console.log(item_id);
}
}
xmlhttp.open("GET","receivemsg.php?q="+item_id,true);
xmlhttp.send();
}
}
}
}
receivemsgs.php just selects all messages in the messages table with the index of the index given by item_id. The problem is as stated that only the chat with 9503e253936e716f18d9c57b4f97d618 id receives the messages.
I heard that the requests repeat 4 times but I am not an expert in this field. By using the console, I understood that it ignores the first chat and only generates the messages for 9503e253936e716f18d9c57b4f97d618.
Any help would appreciate. Also if there is a better way to control more than one chat on the same page, I wold love to know how to. Thank you for your time.
The problem lies in how you're using XMLHttpRequest.
See this snippet:
function Obj() {
}
Obj.prototype = {
callFunc: function() {
setTimeout(this.func, 1000);
}
};
function test() {
var ids = ['id1', 'id2'];
for (var i = 0 ; i < 2 ; ++i) {
var id = ids[i];
var obj = new Obj();
obj.func = function() {
console.log(id);
};
obj.callFunc();
}
}
test();
As you can see, the code prints "id2" twice to the console. That's similar to your problem.
What happens is that, in obj.func
(in your code, that's xmlhttp.onreadystatechange
), the id
variable (respectively item_id
) comes from the outer function. Its value when obj.func
is assigned is not "saved". When the function finally gets executed, it will use the last known value for that variable.
So here's what happens:
i = 0
id = ids[0] = 'id1'
obj1
) and assigned to obj
obj1.func
is createdobj1.callFunc
is called, it programs obj1.func
to be called lateri = 1
id = ids[1] = 'id2'
obj2
) and assigned to obj
obj2.func
is createdobj2.callFunc
is called, it programs obj2.func
to be called laterobj1.func
gets called, it prints the last value of id
, that is "id2"obj2.func
gets called, it prints the last value of id
, that is "id2"There are a few ways around that behavior. You could retrieve item_id
from PHP's output somehow. You could set item_id
to a member of xmlhttp
and use that in your function (xmlhttp.item_id = item_id;
then inside the function this.item_id
). Or you could use bind
. With the latter solution, your code becomes:
xmlhttp.onreadystatechange = function(this_item_id) {
if (this.readyState == 4 && this.status == 200) {
console.log("yes");
console.log(this_item_id);
// document.getElementById(this_item_id).innerHTML = this.responseText;
$("#"+this_item_id).html(this.responseText);
}else{
console.log("no");
console.log(this_item_id);
}
}.bind(xmlhttp, item_id);
xmlhttp.open("GET","receivemsg.php?q="+item_id,true);
xmlhttp.send();
By the way, I don't understand why you're iterating twice on cusid_ele
(you have two nested loops).
</div>