2

I have a div of online users which are dynamically inserted:

<div id="users">
  <div class="privateMessage" data="John">John</div>
  <div class="privateMessage" data="Maria">Maria</div>
  <div class="privateMessage" data="Tony">Tony</div>
</div>

Then I have a div for private messages:

<div id="messageBox">
</div>

Now, I'm struggling how to dynamically append a div inside the messageBox when I click on the user.

What I need is this below:

<div id="messageBox">
   //when I click on John from users div this below should be appended
   <div class="private-chat" data-conversation-between="John"></div>
  //when I click on Maria from users div this below should be appended and John above
  //will be hidden
   <div class="private-chat" data-conversation-between="Maria"></div>
  //when I click on Tony from users div this below should be appended and John and Maria
  //will be hidden
   <div class="private-chat" data-conversation-between="Tony"></div>
</div>

Whatever I tried, the divs inside messageBox get appended more than once.

Can someone help me to solve this with jQuery please?

Link: fiddle

6
  • Would be good idea to show your JS or (event better) link a fiddle. Commented Feb 22, 2015 at 17:32
  • Seconding request for fiddle. Also providing this one - is this what you want to achieve? jsfiddle.net/pLe01k57 Commented Feb 22, 2015 at 17:35
  • Your solution creates only one div for the clicked user. I need to be able to append and keep all the divs with users in the DOM. Commented Feb 22, 2015 at 17:41
  • 1
    jsfiddle.net/pLe01k57/1 - like this? Commented Feb 22, 2015 at 17:41
  • @bardzusny almost correct, but the div with the user should be appended only once :( so lets say if Maria exists, don't append anymore Commented Feb 22, 2015 at 17:43

5 Answers 5

1

What about something like this?

http://jsfiddle.net/thetimbanks/hfuurcL7/

The click event is delegated since the users can be added to the list dynamically. I also search the messageBox for an existing div for that user in order to not add another one.

Adding code here as to not just link to fiddle:

HTML

<div id="users">
  <div class="privateMessage" data-user="John">John</div>
  <div class="privateMessage" data-user="Maria">Maria</div>
  <div class="privateMessage" data-user="Tony">Tony</div>
</div>

<div id="messageBox">
</div>

js

$("#users").on("click", ".privateMessage", function() {

    var user = $(this),
        private_chat = $("#messageBox .private-chat[data-conversation-between='" + user.data("user") + "']");

    if (private_chat.length == 0) {
        private_chat = $('<div class="private-chat" data-conversation-between="' + user.data("user") + '">Chat with ' + user.data("user") + '</div>');
        $("#messageBox").append(private_chat);
    }

    private_chat.show().siblings().hide();
});
Sign up to request clarification or add additional context in comments.

Comments

1

After short clarification in the comments, I'm posting a working solution:

$('.privateMessage').on('click', function (e) {
  $messageBox = $('#messageBox');
  var whoIsIt = $(this).attr('data');

  var isAlreadyThere = $messageBox.find('div[data-conversation-between="' + whoIsIt + '"]').length;

  if (isAlreadyThere == 0) {
    $messageBox.append('<div class="private-chat" data-conversation-between="' + whoIsIt + '"></div>');
  }
});

jsfiddle: http://jsfiddle.net/pLe01k57/2/

Basically: check if #messageBox already has conversation (div) with clicked-on user, and if not - append it there.

Comments

1

How about this?

$('.privateMessage').on('click', function (e) {
    var whoIsIt = $(this).attr('data');
    $('#messageBox').append('<div class="private-chat" data-conversation-between="' + whoIsIt + '"></div>');
    $(this).unbind();
});

https://jsfiddle.net/lemoncurry/5cq2sw8m/1/

Basically bardzusny's solution above plus a $(this).unbind().

Comments

1

Hope it does what you are expecting .Can check data-attribute before appending div's.

$('.privateMessage').on('click', function(e) {
  var isPresent = false;
  var whoIsIt = $(this).attr('data');
  $('#messageBox .private-chat').each(function(index, element) {
    if ($(this).attr('data-conversation-between') == whoIsIt) {
      isPresent = true;
    }
  });
  if (!isPresent) {
    $('#messageBox').append('<div class="private-chat" data-conversation-between="' + whoIsIt + '"></div>');
  }
});
.private-chat {
  height: 20px;
  background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


<div id="users">
  <div class="privateMessage" data="John">John</div>
  <div class="privateMessage" data="Maria">Maria</div>
  <div class="privateMessage" data="Tony">Tony</div>
</div>
<div id="messageBox"></div>

Comments

1

You should avoid using data attribute in this way.

Read more about .data() attribute

HTML:

<div id="users">
    <div class="privateMessage" data-selected="" data-who="John">John</div>
    <div class="privateMessage" data-selected="" data-who="Maria">Maria</div>
    <div class="privateMessage" data-selected="" data-who="Tony">Tony</div>
</div>
<div id="messageBox"></div>

Script:

$("#users").on("click", '.privateMessage', function () {
    if(!$(this).data('selected')){
        $(this).data('selected', 'selected');
        // do not use '.attr()', use natvie jQuery '.data()'
        var $msgTo = $(this).data('who');
        $("#messageBox").append("<div class='private-chat' data-conversation-between=" + $msgTo + ">"+$msgTo+"</div>");
    }
});

DEMO


Alternatively, you could just use .one() event, and reactivate it later for specific button (f.ex. after the person was removed from the chat):

function singleClick(el) {
    $(el).one("click", function () {
        var $msgTo = $(this).data('who');
        $("<div class='private-chat' data-conversation-between=" + $msgTo + ">"+$msgTo+"</div>").appendTo("#messageBox");
    });
}

singleClick('.privateMessage');

DEMO (with delete example using .one())

Comments

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.