Fork me on GitHub
<!doctype html>
<html>

<head>
<title>Chat App Demo</title>
<meta name="description" content="Chat Client with RSS Feed reader client" />
<meta name="keywords" content="Chat Demo,ignite,RSS Feed" />
<meta name="author" content="Richard Miller-Smith,David Hammond" />
<script src='http://code.jquery.com/jquery-latest.js'></script>
<script src="/socket.io/socket.io.js"></script>
<style type="text/css">
  body { 
    font-family:"Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,
                Arial,sans-serif;
    font-size: 12px; 
  }
  #main { width:500px; }
  #title { margin:0; text-align:center; background-color:lightblue; }
  #clientsConnected { margin:0; text-align:center; background-color:lightblue; }
  #signInBanner { width:500px; background-color:#3B5998; } 
  #userNameLabel { color:white; }
  tr.msg { width:496px; }
  td.msg { width:496px; background-color:white; }
  span.msg { font-weight: bold; }
  #chatList { background-color:lightgrey;}
</style>

<script>
$(document).ready(function () {
  var controller = (function () {
    var userName = $('#userName'),
        signInMsg = $('#signInMsg'),
        signInButton = $('#signInButton'),
        clientsConnected = $('#clientsConnected'),
        chatInput = $('#chatInput'),
        chatList = $('#chatList'),
        chatMsg = $('#chatMsg');        

    var logIn = function () {
      var un = jQuery.trim(userName.val());
      if(un != '') {
        controller.setLoggingInState();
        send('signIn', un);
      }
    };

    userName.keypress(function (evt) {
      if(evt.keyCode == 13) {
        logIn();
        return false;
      }
    });

    chatInput.keypress(function(evt) {
      if(evt.keyCode == 10 || (evt.ctrlKey && evt.keyCode == 13)) {
        chatInput.val(chatInput.val() + '\n');
        return false;        
      } if(evt.keyCode == 13) {
        send('chat', chatInput.val().replace(/\n/g, '<br />'));
        chatInput.val('');
        return false;
      } else {
        return true;
      }
    });

    signInButton.click(logIn);

    return {
      setInitialState: function () {
        signInButton.text('connecting');
        signInButton.attr('disabled', 'disabled');
        signInMsg.text('');
        clientsConnected.text('');
        userName.val('');
        userName.attr('disabled', 'disabled');        
        chatInput.attr('disabled', 'disabled');
      },
      setLogInState: function () {
        signInButton.text('sign in');
        signInButton.removeAttr('disabled');                
        userName.removeAttr('disabled');
        userName.focus();
      },
      setBadNameState: function () {
        signInMsg.text('user name already in use');
        controller.setLogInState();
      },
      setLoggingInState: function () {
        signInButton.text('signing in');
        signInButton.attr('disabled', 'disabled');
        signInMsg.text('');
        userName.attr('disabled', 'disabled');
      },
      setLoggedInState: function () {
        signInButton.text('signed in');
        chatInput.removeAttr('disabled');
        chatInput.focus();
      },
      setClientsConnected: function (num) {
        clientsConnected.text('clients connected: '+num);
      },
      newChatMsg: function (msg) {
        var tr = chatMsg.find('tr');
        if (tr.length > 100) {
          $(tr[0]).remove();
        }
        chatMsg.append('<tr class="msg"><td class="msg"><span class="msg">'+msg.name+
                       ': </span>'+msg.text+'</td></tr>');
        chatList.scrollTop(1000000);
      }
    }
  }());
  controller.setInitialState();

  var send = (function () {
    var s = io.connect();

    s.on('connected', function () {
      controller.setLogInState();
    });
    s.on('badName', function () {
      controller.setBadNameState();
    });
    s.on('signedIn', function () {
      controller.setLoggedInState();
    });
    s.on('statusUpdate', function (count) {
      controller.setClientsConnected(count);
    });
    s.on('chat', function (msg) {
      controller.newChatMsg(msg);
    });
    s.on('disconnect', function () {
      controller.setInitialState();
    });

    return function (eventName, msg) {
      s.emit(eventName, msg);
    };
  }());
});
</script>
</head>

<body>
<div id="main">
  <h3 id="title"><a href="http://ignitejs.com">ignite.js</a> Chat App Demo</h3>
  <h5 id='clientsConnected'></h5>
  <div id='signInBanner'>
  <table><tbody>
    <tr>
      <td id='userNameLabel'>user name</td>
      <td><input id='userName' type='text' size='10' maxlength='10'></td>
      <td style='width:85px;'>
        <button id='signInButton' type='button' style='width:85px;'></button>
      </td>
      <td><span id='signInMsg'></span></td>
    </tr>
   </tbody></table>
 </div>

  <div id='chatList' style='width:500px;height:600px;overflow:auto;'>
    <table><tbody id='chatMsg'></tbody></table>
  </div>

  <div style='width:500px;'>
    <textarea id='chatInput' style='width:494px; height:50px;resize:none;'></textarea>
  </div>
  <div>
    <span>See the <a href="http://ignitejs.com/examples/apps/chat.html">source code</a></span>
  </div>
</div>
</body>

</html>