// you’re reading...

Featured

Simple Website Instant Messenger – Client-side Functionality

This is part two of the Simple Website Instant Messenger (SWIM for short, I love it when acronyms just work themselves out) and will cover adding some client-side functionality to our system. For part 1, click here.

Client-side functionality essentially translates itself to “using JavaScript to do some funcy (eh? get it? Funcy? Functional?) things”. It will allow us to add a level of interaction that users are familiar with and that they come to expect from applications. We want them to have the ability to minimize or maximize the windows, as well as close them. We also want to do all of this without page refreshes. Since actions like this are on a per-session basis, we don’t need to have any server-side code to handle it. We can let the browsers do all the work for us.

For this section we’ll be making some heavy use of jQuery and some rather complex DOM manipulation. I’ve also opted to use the long-hand version of everything instead of shorthand. This is so that you guys will be able to read the code and such. I’ve opted to use the production version of jQuery, but if you’re just getting started, you may as well download the development version. The bonus of this is that if you’re just learning you can easily pop in to the jQuery code and see how things are done. As well, if you are using an advanced IDE (such as Dreamweaver) you’ll get full code hinting. You can do this by heading to this website and downloading the appropriate version. I also recommend that you bookmark the documentation for jQuery (http://docs.jquery.com) as you’ll end up using it a lot.

Setup jQuery in whatever folder you’ve stored the HTML/CSS file from the previous tutorial (setup is actually just copy/paste). You’ll then need to link the script in your HTML by adding the following line of code to your HTML file in the head section of the code

<script src="jquery.min.js" type="text/javascript"></script>

Note the src attribute contains the name of the jquery file that I am using. You may have to edit it so that the name of the file matches the name of the file you downloaded.

Directly below that you can add this line as well

<script src="im.js" type="text/javascript"></script>

That line of code will link to our not-yet-created javascript file which will hold all the client-side functionality for our IM script. Once that’s done you can pop open your editor and get started with the actual jQuery code. However, before we continue with the tutorial note that this is NOT a jQuery primer. This tutorial is expecting you to have some knowledge of jQuery and javascript syntax. If you do not, please read this jQuery primer tutorial first before continuing.

The first thing we are going to do is ensure that our “information” window has a toggle-state. Instead of using jQuery’s built in toggle() method, I’ve decided to go with a simple boolean check.

$(document).ready(function){
var windowOpen = false;
$('.info').click(function(){
			if(windowOpen){
				$('.more').fadeOut('fast');
				$(this).children('span').children('img').attr('src','/icon/bullet_arrow_up.png');
				windowOpen = false;
			}
			else{
				$('.more').fadeIn('fast');
				$(this).children('span').children('img').attr('src','/icon/bullet_arrow_down.png');
				windowOpen = true;
			}
	});
});

Basically, this will apply the “onclick” event to our main window launching button. When clicked it will check if the window is already open and depending on the value of windowOpen, it will close/open it accordingly.

This next section of code will handle opening the chat windows. Since we want to make sure that only windows that AREN’T opened can be opened (redundant? yes, but completely necessary). This will ensure that if a window is already open, it won’t open it again.

	$('.contacts span').live('click',function(){
		var id = $(this).attr('id'); 
		var name = $(this).attr('name'); 
		var found = false; 
		for(i in openWindows){
			if(openWindows[i] == id+name){
				found = true;
			}
		}
 
		if(!found){
			$('.im-bar').prepend('<span class="task" id="'+id+'"><div class="convo"><img src="/icon/cancel.png" id="close-win" alt="Cancel"><span class="system">You have entered a conversation with '+name+'</span><textarea name="message" id="message"></textarea></div><div class="win" name="'+name+'">'+name+'</div>');
			$('#'+id).children('.convo').css('display','inline');
			openWindows[openWindows.length] = id+name;
			$('#'+id).children('.win').css('padding-top','50px');
			convoOpen = true;
			var offset = (openWindows.length*50)+(openWindows.length*15);
			$('#'+id).children('.convo').css('right',offset+'px');
			$('#'+id).children().children('textarea').focus();
		}
 
		$('.more').fadeOut('fast');
		$('.info').children('span').children('img').attr('src','/icon/bullet_arrow_up.png');
		windowOpen = false;
	});

The code itself remains fairly straightforward albeit long. First it does some variable assignment and then checks the openWindows array to see if it can find this particular window. If it can’t, it simply continues with the code. First it creates the new window and places it at the front of the open-window list. Then it just adds it to the openWindows array and does a bit more manipulation to create a text-box and align it properly with the current tab. It also opens the window and focuses on the text area. Finally it fades out the main information window and resets the image and boolean var.

Something to note here: Since we want openWindows and convoOpen to be accessible to ALL our functions, we can place it next to the “openWindow” declaration at the top of the script. It would look like this:

var openWindows = new Array(); 
var convoOpen = false;

This next bit will just pop open the window if you click on the tab, and minimize it again if you click again.

$('.task .win').live('click',function(){
		if(convoOpen){
			$(this).prev().css('display','none'); 
			$(this).css('padding-top','5px'); 
			convoOpen = false;
		}
		else{
			$(this).prev('.convo').css('display','block'); 
			$(this).css('padding-top','50px');
			convoOpen = true;
		}		   
	});

We’re nearing the end of our code. This block of code will handle the “Close” button on a conversation window. If it is clicked, the window is removed from the tab bar and the openWindows array and the remaining positions are re-calculated.

	$('.task .convo #close-win').live('click',function(){
		var id = $(this).parent().parent().attr('id');
		var name = $(this).parent().next().attr('name');
		for(i in openWindows){
			if(openWindows[i] == id+name){
				openWindows.splice(i,1);
				break;
			}
		}
		$(this).parent().parent().remove(); 
		convoOpen = false;
		var i = openWindows.length;
		$('.im-bar').children().children('.convo').each(function(){
			var offset = (i*50)+(i*15);
			$(this).css('right',(offset)+'px');
			i--;
		});	
	});

This last block of code will take any text in our textarea and submit it to the server when you press enter. The AJAX portion of this tutorial will be following, so in the mean-time everything else is showed here. The message is sent to the server, and then it is also automatically placed into the conversation window. We also strip out all tags from the code to ensure that nothing breaks our layout or is able to get through.

$('.task .convo #message').live('keyup',function(e){
		if(e.which == 13){
			data = $(this).val();
			data = data.replace(/<\/?[^>]+>/gi, '');
			// Send message
			$(this).val('');
			$(this).prev().addClass('text');
			if($(this).prev().hasClass('system')){
				$(this).prev().removeClass('system');
				$(this).prev().text('');
			}
			if(data != '' && data != '\n'){
				$(this).prev().append('<p><b>'+yourName+':</b> '+data+'</p>');
				$(this).prev().attr({ scrollTop: $(this).prev().attr("scrollHeight") });
			}
		}
	});

That is the basics of our Client-Side functionality to our Simple Website Instant Messenger system. The next installment will cover adding the AJAX function and modifying this last section sightly to reflect it.

Discussion

3 comments for “Simple Website Instant Messenger – Client-side Functionality”

  1. Very nice! can’t wait to see the next part.

    Cheers.

    Posted by Rayshinn | November 10, 2009, 3:05 pm
  2. Hey, I know its been a while since you posted this, but I was wondering if you were going to post an update to this?

    Thanks
    -Nova

    Posted by novastar | March 1, 2010, 4:37 pm

Post a comment