This is a chat using Node.js, socket.io and MongoDB for storage.
I'd appreciate any feedback on what can be improved. I understand that this allows for non-unique usernames to be used, and it's currently a JavaScript prompt, however this is simply a demonstration for entering a username to test the functionality.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="chat">
<div class="chat-messages"></div>
<textarea placeholder="Type your message"></textarea>
</div>
<script src="node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js"></script>
<script>
(function() {
var socket = io.connect('http://127.0.0.1:8080'),
name = prompt('Enter your name');
// Listen for output from server
socket.on('output', function(data) {
var messages = document.querySelector('.chat .chat-messages');
if(data.length) {
// Loop results
for(var x = 0; x < data.length; x = x + 1) {
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.innerText = data[x].name + ': ' + data[x].message;
// Prepend
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
// Listen for keydown
document.querySelector('.chat textarea').addEventListener('keydown', function(event) {
var self = this;
// Is enter down (without shift being held)?
if(event.which === 13 && event.shiftKey === false) {
if(name) {
// Send message
socket.emit('input', {
name: name,
message: self.value
});
self.value = '';
}
event.preventDefault();
}
});
})();
</script>
</body>
</html>
server.js
var mongo = require('mongodb').MongoClient,
client = require('socket.io').listen(8080).sockets;
client.on('connection', function(socket) {
// Connect to MongoDB
mongo.connect('mongodb://127.0.0.1/chat', function(err, db) {
if(err) throw err;
var col = db.collection('messages');
// Emit all messages
col.find().limit(100).sort({_id: 1}).toArray(function(err, res) {
if(err) throw err;
socket.emit('output', res);
});
// Wait for input
socket.on('input', function(data) {
col.insert({name: data.name, message: data.message}, function(err, docs) {
// Emit latest message to all clients
client.emit('output', [data]);
});
});
});
});
main.css (not as important here)
body,
textarea {
font: 13px "Trebuchet MS", sans-serif;
}
.chat {
max-width:300px;
}
.chat-messages,
.chat textarea {
border:1px solid #bbb;
}
.chat-messages {
width:100%;
height:300px;
overflow-y:scroll;
padding:10px;
}
.chat-message {
margin-bottom:10px;
}
.chat textarea {
border-top:0;
margin:0;
max-width:100%;
width:100%;
padding:10px;
}
.chat textarea:focus {
outline:none;
}