0

I am facing a problem with jQuery code. The problem is I am designing one chat application. Here the users list will get from the backend through ajax and need to be display in the frontend. I called the ajax I am getting the data I am able to display the data. Here I am creating a element as following:

function display_users_list(html) {
    var users_list = JSON.parse(html);
    var display_users = '';
    for (var key in users_list) {
        display_users += '<div class="user user-list" data-user-id='+users_list[key].userid+'>';
        display_users += users_list[key].username;
        display_users += '</div>';
    }
    $(".chat-body").html(display_users);
}

But the problem is when I created a element using jquery with css class I am unavailable to call that css class in same jquery file. I am pasting the code may be you guys will understand my problem. I am calling the css as following:

$(".chat-body > .user-list").each(function() {
    $(this).on("click", function() {
        var uId = $(this).data('user-id');
        var innerTxt = $(this).text();
        console.log("uid:"+uId+"innerTxt:"+innerTxt);
        //$(".chat-box").after(generate_msg_box(uId, innerTxt))
    });
});

Entire code is following: html code:

<div class="chat-box">
    <div class="chat-head">Users List</div>
    <div class="chat-body">
        No User Found
    </div>
</div>

<div class="msg-box">
    <div class="msg-head">
        User 1
        <div class="close-msg">x</div>
    </div>
    <div class="msg-wrap">
        <div class="msg-body">
            <div class="sender-msg">This is sender message</div>
            <div class="recevier-msg">This is recevier message</div>
            <div class="sender-msg">This is sender message</div>
            <div class="recevier-msg">This is recevier message</div>
            <div class="sender-msg">This is sender message</div>
            <div class="recevier-msg">This is recevier message</div>
            <div class="recevier-msg">This is recevier message</div>
        </div>
        <div class="msg-footer">
            <textarea class="msg-input">Sample</textarea>
        </div>
    </div>
</div>

jquery code:

$(document).ready(function() {
$(".msg-box").hide();
get_users_list();
$(".chat-head").click(function() {
    $(".chat-body").slideToggle("slow");
});

function get_users_list() {
    $.ajax({
        url: "phpActions/actions.php",
        method: "post",
        data: "actions=getData",
        success:function(html) {
            display_users_list(html);
        }
    });
}

function display_users_list(html) {
    var users_list = JSON.parse(html);
    var display_users = '';
    for (var key in users_list) {
        display_users += '<div class="user user-list" data-user-id='+users_list[key].userid+'>';
        display_users += users_list[key].username;
        display_users += '</div>';
    }
    $(".chat-body").html(display_users);
}

$(".chat-body > .user-list").each(function() {
    $(this).on("click", function() {
        var uId = $(this).data('user-id');
        var innerTxt = $(this).text();
        console.log("uid:"+uId+"innerTxt:"+innerTxt);
        //$(".chat-box").after(generate_msg_box(uId, innerTxt))
    });
});

});

2 Answers 2

2

As you are already using jQuery.on(), you could make use of delegated events and get rid of the event binding loop. Using delegated events makes sure, your events are fired even on the elements that are added at a later point in time, which is your case.

From documentation:

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.

$(".chat-body").on("click", ".user-list", function(event) {
  var $listElement = $(event.target);
  var uId = $listElement.data('user-id');
  var innerTxt = $listElement.text();
  console.log("uid:" + uId + "innerTxt:" + innerTxt);
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks sreekanth. I will try the example.
just wanted to add that using delegated events also reduces the amount event listeners you have. So in the example Sreekanth gave you you would have one event listener for the "chat-body" instead of one event listener per "user-list". On larger pages you get a nice performance benefit as well.
Oh Okay Thanks Aliester
0

Seems you binding the click function before the element is on DOM, make sure you event binding code comes after $(".chat-body").html(display_users);

From your current code it will always be that your event binding call gets executed before the ajax calls returns the data try this

create a new function for event binding say

 function bindClick(){
     $(".chat-body > .user-list").each(function() {
        $(this).on("click", function() {
         var uId = $(this).data('user-id');
         var innerTxt = $(this).text();
         console.log("uid:"+uId+"innerTxt:"+innerTxt);
        //$(".chat-box").after(generate_msg_box(uId, innerTxt))
     });
   });
 }

and call after your

 $(".chat-body").html(display_users); 
 bindClick();

1 Comment

Thanks vinod Louis. I will try this example too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.