Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
JavaScript
//Client JS File


var socket = io.connect(),
    userEnterDiv = document.getElementById('userEnterDiv'),
    userNameErrorMsg = document.getElementById('userNameErrorMsg'),
    userNameInput = document.getElementById('userNameInput'),
    enterBtn = document.getElementById('enterBtn'),
    mainDiv = document.getElementById('mainDiv'),
    usersDivContainer = document.getElementById('usersDivContainer'),
    displayUsers = document.getElementById('displayUsers'),
    chatDivContainer = document.getElementById("chatDivContainer"),
    chatOutput = document.getElementById('chatOutput'),
    typingOutput = document.getElementById('typingOutput'),
    msg = document.getElementById('messageTextArea'),
    chatBtn = document.getElementById('chatButton');


//Enter to Chat
enterBtn.addEventListener('click', function(e){
    e.preventDefault();
    socket.emit('new user', userNameInput.value, function(data){
        if(data) {
            userEnterDiv.style.display = "none";
            mainDiv.style.display = "block";
        } else {
            userNameErrorMsg.innerHTML = 'Error: try again';
        }
    });
});
//display usernames on chat inside div displayUsers
// socket.on('usernames', function(data){
//     displayUsers.innerHTML = '';
//     for(var i=0; i<data.length; i++){
//       displayUsers.innerHTML += `${`<div id="nameOnDisplay-${data[i]}">${data[i]}</div>`}`;    // '<div id="nameOnDisplay-data[i]">' + data[i] + '</div>';
//       //var htmlStr = `${`<h2>${nameX}</h2>`}`;		//using Template Literal concept
//   }
// });


//choose a person to chat with
var div_ele=displayUsers.childNodes;
socket.on('usernames', function(data){
    displayUsers.innerHTML = '';
    var htmlStr = '';
    for(var i=0; i<data.length; i++){
      htmlStr = '<p>' + data[i]+'</p>';
      var innerDisplayUsers = document.createElement('div');
      innerDisplayUsers.id = data[i];// + '-innerDisplayUser';
      innerDisplayUsers.innerHTML = htmlStr;
      displayUsers.appendChild(innerDisplayUsers);
    }
    for (var i=0; i<div_ele.length; i++) {
         //console.log(div_ele[i]);
         div_ele[i].addEventListener('click', chooseUserToChatWith(div_ele[i]));
    }
});
function chooseUserToChatWith(data){
    return function(){
      console.log(data);       console.log(data.id);
      chatDivContainer.style.display = "block";
      sendMessageToUser(data.id);
    };
}


//send message to chosen client
function sendMessageToUser(client) {
  console.log(client);
  chatBtn.addEventListener('click', function(e) {  e.preventDefault();
    socket.emit('send message',  {  'client': client, 'msg': msg.value} );
    msg.value = '';
  });
}


//add event listener on msg typing
msg.addEventListener('keypress', function(){
    socket.emit('typing message', userNameInput.value);
});

//message output
socket.on('new message', function(data){
  chatDivContainer.style.display = "block";
    typingOutput.innerHTML="";
    var htmlStr = '';
    htmlStr += '<p>' + data.sender +': '+ data.message + '</p>';
    var innerChatOutput = document.createElement('div');
    innerChatOutput.id = data.client;
    innerChatOutput.innerHTML = htmlStr;
    chatOutput.appendChild(innerChatOutput);

    //keep scroll on bottom
    var xH = chatMessagesContainer.scrollHeight;
    chatMessagesContainer.scrollTo(0, xH);
});

//Listen on events
// socket.on('new message', function(data){
//   chatDivContainer.style.display = "block";
//     typingOutput.innerHTML="";
//     chatOutput.innerHTML += '<p>' + data.sender +': '+ data.message + '</p>';
//     //keep scroll on bottom
//     var xH = chatMessagesContainer.scrollHeight;
//     chatMessagesContainer.scrollTo(0, xH);
// });

socket.on('typing message', function(data){
    console.log(data + '  typing message')
    typingOutput.innerHTML = '<p>' + data + ' is typing message...</p>';
});






JavaScript
//SERVER JS file
//A Server File, all console.log() will be printed in terminal window


//Server setup
var express = require('express'),
    app = express(),    //simply one line var app = require('express')();
    server = require('http').createServer(app),
    usersNames = {},
    io = require('socket.io').listen(server);

server.listen(3000, function(){ console.log('listening port 3000')});

//Express Routing as soon as we go to http://host:port this page will be served
// app.get('/', function(req, res){
//     res.sendFile(__dirname + '/index.html');
// });
app.use(express.static('public'));

//listen on events client side
io.sockets.on('connection', function(socket) {
    //user enters onto chat
    socket.on('new user', function(data, callback){
        if(data in usersNames) { callback(false); }
        else {
          callback(true);
          socket.userName = data;
          usersNames[socket.userName] = socket;  //userName is key : socket
          updateUsersNames();
        }
    });
    //usersNames object keys updated
    function updateUsersNames() {
          io.sockets.emit('usernames', Object.keys(usersNames));
    }
    //if user leaves chat, then username removed from UsersNames[]
    socket.on('disconnect', function(data){
        if(!socket.userName) return; //if there s no username simply return
        delete usersNames[socket.userName];
        updateUsersNames();
    });

    //user sends message from clientside
    socket.on('send message', function(obj){
      console.log(obj.client);
      socket.broadcast.to(obj.client).emit('new message', {
        //  io.sockets.emit('new message', {
          sender: socket.userName,
          message: obj.msg,
          client: obj.client
        });
    });

    socket.on('typing message', function(data){
        socket.broadcast.emit('typing message', socket.userName); //server sends msg to all excluding me
    });
});


What I have tried:

im really stuck on here, hope someone who is more clever than me can do a help please

PM CHAT construction idea was each person can PM to each other by clicking on the username.
lets say Alex, Kate, David enters PMchat.
Alex clicks on Kate and sends private message to her,

soAlex sends a message to KAte, so Only Kate can see the message received from ALex, nobody else, this is not happening here, im bit stuck


used pure javascript, socket io, node js, express module, css/html.
Posted
Updated 22-Feb-18 1:27am

1 solution

//in case If front page

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>

<style>
#userEnterDiv{

}
#mainDiv{
  width: 600px;
  height: 500px;
  margin: left;
  border: 1px solid #ddd;
  box-shadow: 1px 2px 5px rgba(0,0,0,0.05);
  border-radius: 2px;
  display: none;
}
#usersDivContainer{
  float: left;
  width: 20%;
  height: 100%;
  overflow-y: auto;
}

#chatDivContainer{
  height: 100%;
  width: 80%;
  float: right;
  display: none;

}
#chatMessagesContainer{
  width: 100%;
  height: 90%;
  overflow-y: auto;
}
#chatOutput p{
  padding: 14px 0px;
  margin: 0 20px;
  border-bottom: 1px solid #e9e9e9;
  color: #555;
}
#chatFormElementsContainer{
  width: 100%;
  height: 10%;
}
#chatButton{
  background: #575ed8;
  color: #fff;
  font-size: 12px;
  border: 0;
  padding: 14px 0;
  float: right;
  width: 20%;
  heght: 100%;
  border-radius: 0 0 2px 2px;
}
</style>
</head>
<body>

<div id="userEnterDiv">
      <p>enter username</p>
      <p id="userNameErrorMsg"></p>
      <input type="text" id="userNameInput" />
      <button id="enterBtn">Enter</button>
</div>
<div id="mainDiv">
  <div id="usersDivContainer">
      <div id="displayUsers"></div>
  </div>
  <div id= "chatDivContainer">
      <div id = "chatMessagesContainer">
          <div id = "chatOutput"></div>
          <div id = "typingOutput"></div>
      </div>
      <div id="chatFormElementsContainer">
          <input id="messageTextArea" type="text" />
          <button id="chatButton">Send</button>
      </div>
  </div>
</div>

<script src="/ops.js"></script>


  </body>
</html>
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900