andreaem
andreaem

Reputation: 1655

jQuery chat box with ajax calls works only with first user

I'm doing a project that include an internal chat between the users, is a simple fb like box opened by clicking in the chat box and after selecting user will load the chat history and show the box.

I'm taking the data from a database using PHP and populating the user list with a foreach loop.

Fiddle https://jsfiddle.net/znj0Lvyo/1/

HTML

<div class="chat-wrapper">
  <div class="chat-holder">
        <div class="chat-header">
            <i class="fa fa-circle text-success"></i> Chat (2)
        </div>
        <div class="chat-box">
          <?php 
          $userID = $user->id;
          $usersList = DB::select("SELECT * FROM users WHERE id != '$userID' AND active = 1 ORDER BY role_id");

          foreach ($usersList as $userItem) {
            $roleID = $userItem->role_id;
            $userRole = DB::select("SELECT name FROM roles WHERE ID = '$roleID';");
            $userPic = site_url('upload/img/users/' . $userItem->username);
            print '<div class="media chat-user-item chat-' . $userItem->username . '" data-user="' . $userItem->id . '" data-uname="' . $userItem->username . '" data-from="' . $userID . '">';
            print '<div class="media-left">';
            print '<a href="#">';
            print '<img class="media-object img-circle" src="' . $userPic .'.jpg" alt="..." style="width:50px">';
            print '</a>';
            print '</div>';
            print '<div class="media-body">';
            print '<h4 class="media-heading">' . $userItem->realname . '</h4>';
            print '<small>' . $userRole[0]->name. '</small>';
            print '</div>';
            print '</div>';
          }
          ?>
        </div>
    </div>

    <div class="chat-user-holder hidden">
      <div class="chat-user-header">
              <i class="fa fa-circle text-success"></i> <span class="box-userName">Noh</span> <a class="dismiss-chat" href=""><i class="fa fa-close pull-right "></i></a>
          </div>
          <div class="chat-user-box slimScroll">
              Noh
          </div>
          <div class="msgHolder">
            <input class="form-control sendMessage" placeholder="Scrivi Messaggio..."/>
          </div>
    </div>
 </div>

JS

$(document).on('load',function(){  /* hide elements on load */
  $('.chat-box').css('display','none'),
  $('.chat-user-holder').hide(),
  $('.msgHolder').hide(500)
  });

  $('.chat-header').click(function(){ /* chat list open */
    $('.chat-box').slideToggle(500); 
  });

  var fromUID = $('.chat-user-item').data("user");
  var fromUname = $('.chat-user-item').data("uname");
  var boxName = '.chat-' + fromUname;
  var userID = $('.chat-user-item').data('from');

  function update() {
    $.ajax({ /* update ajax call */
      data: {
        touid: userID,
        fromuid: fromUID
      },
      url: '/echo/html/',
      method: 'POST',
      dataType: "html",
      cache: false,
      success: function(response){                    
            $(".chat-user-box").html(response); 
        }
    });
    $('.chat-user-box').scrollTop($('.chat-user-box').prop("scrollHeight"));
  }

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

  $(boxName).click(function() { /* user chat box open */
    $('.chat-user-holder').show();
    $('.chat-user-holder').toggleClass('hidden');
    $('.chat-user-box').hide().slideToggle(500);

    $.ajax({ /* Ajax call get username */
      data: {
        uname : fromUID,
      },
      url: '/echo/html/john',
      method: 'POST',
      dataType: 'html',
      success: function(response){
        $(".box-userName").html(response)
      }
    });

    update();

      $('.chat-box').slideToggle(500);
      $('.msgHolder').show(500);
      $('.chat-user-box').scrollTop($('.chat-user-box').prop("scrollHeight"));
  });

  $('.chat-user-header').click(function() { /*  */
      $('.chat-user-box').slideToggle(500);
      $('.msgHolder').slideToggle(500);
  });

  $( ".dismiss-chat" ).click(function( event ) { /* close box using cross button */
  event.preventDefault();
   $('.chat-user-holder').hide();
});

$('.sendMessage').bind("enterKey",function(e){
  $.ajax({ /* Chiamata ajax insert messaggio */
    data: {
      toID: fromUID,
      fromID: userID,
      message: $('.sendMessage').val()
    },
    url: '/echo/html/',
    method: 'POST',
    success: function(response){
      update();}
  });
  $('.sendMessage').val('');
});
$('.sendMessage').keyup(function(e){
  if(e.keyCode == 13)
    {
      $(this).trigger("enterKey");
    }
}); 

This fully work with only the first user, but, when I click on the second user the box will be not shown.

Fiddle https://jsfiddle.net/znj0Lvyo/1/

Upvotes: 1

Views: 1730

Answers (1)

Piou
Piou

Reputation: 1066

You are missing to bind the user relative part of the code for each user element:

$('.chat-user-item')

Is returning 2 elements, one for each user. But as jQuery by default takes the first one when accessing DOM element arrays without index, your are actually doing all the code bellow this statement only for the first user.

Thus the javascript variables fromUID , fromUname, boxName and userID are all related only to the first user.

As a solution you can wrapp you code in a jQuery each instruction as follow:

$.each($('.chat-user-item'), function(i, el){
   var $el = $(el);
   //...
}

Here is a fork of your fiddle working as expected: https://jsfiddle.net/Djul/pur11o8y/2/

(I did not fix the problem that both users are bound to the same chat box but that's another story)

Upvotes: 2

Related Questions