Archive for the 'programming' Category

Creating a MSN Spaces Type Layout with Prototype

Monday, August 21st, 2006

I’m really excited to share this bit of code with everyone, but, before I begin, let me start by saying I was planning to write a follow up to last weeks post on creating a web 2.0 form and adding IP to GEO location lookup etc, but I got distracted with Drag and Drop. I will continue that post next week.

The effect we want to create is a portal style windowed content system with drag and drop, much like MSN Spaces or now Live Spaces or the old My Yahoo! Click here to see the demo. By the end of this tutorial, you will have a good understanding on how to create this type of effect and port it into your own web application. It is not 100% complete. We will need a save layout method and a few other little things, but all in all, its not bad. Think of it like homework.

Okay, the problem. We want to display content in little windows, and give the user the ability to move the windows into any column they choose. We also want a way to provide the user the abiliy to chage the layout fron two colums to three or whatever the programmer defines. Since this isnt the 90’s, we are not going to do this from scratch. We’ll check out what libaries we could do this with, like YUI!, Dojo, or Script.aculo.us. Well, since I have focused all the other articles on Prototype, Script.aculo.us seems like the perfect choice.

Script.aculo.us provides a great drag and drop libary. We are actually going to use their sortables object, which extends the dragables object. We will basically create three lists and provide the user the ability drop onto any one of the lists.

Here we go…

We will create two objects: a layoutManager and a windowObject. The layoutManager will be responsible for creating the windows and displaying the layout or changing the layout. The windowObject will be responsible for actually rendering the window.

Lets start with the WindowObject and work backwards,


var windowObject = Class.create();

windowObject.prototype = {
initialize: function(id) {
this.id = id;
this.title = windows[id][0];
this.content = windows[id][1];
},

buildWindow: function() {
this.li = document.createElement('li');
var el = Builder.node('div',{className:'window'},[
Builder.node('span',{className:'handle'},this.title),
Builder.node('span',{className:'content'},this.content)
]);
this.li.appendChild(el);
return (this.li);
}
}

The window Object really only has one method, buildWindow. It creates a list item, a div, and two (2) spans. The actual window content is loaded in from the windows array deifined outside the object. The window is styled by the three (3) classes: window, handle, and content. As you can see, the content is loaded in here from a static variable. This should be changed to an ajax call and load in a file fragment rather then a string. Can we say homework assignment?

So this window array that defines the windows looks like this:

var windows = Array();
windows['blah'] = Array('Blah Window','Blah Content');
windows['foo'] = Array('Foo Window','Foo Content');
windows['bar'] = Array('Bar Window','Bar Content');

So we have created an associative array with three windows, and we use the ‘id’ as the key. Each element is an array and has two more elements: the windows title and the window content. This could be expanded to allow more information, such as window state, minimized, maximized, etc…

Moving along, lets break down the layoutManager Object.


layoutManager.prototype = {
initialize: function(type) {
this.type = type;
this.cols = Array();
},

// Defines the default set of windows to be displayed
addWindowSet: function(ws) {},

// Acutally writes out the layout and all the windows to the dest_id
drawLayout: function(dest_id) {},

// Used to change the layout, one paramater, a new layout type string.
changeLayout: function(type) {},

// These are helper functions, they are called from drawLayout()
makeSortable: function() {},
createColumn: function(colnum) {}

}

The constructor takes only one param, the layout type. The layout type is the type of layout we want to display, how many columns, and how big each column is (in percent). Lets take a look at that for a second. The layout type is a string that references a key in an array. I guess I could have just passed in the entire array, but I didn’t think about that until just now. Oh well… (more homework?)


var layoutTypes = Array();
layoutTypes['SymmetricTwoCol'] = Array(2,'50,50');
layoutTypes['RightHeavyTwoCol'] = Array(2,'30,70');
layoutTypes['LeftHeavyTwoCol'] = Array(2,'70,30');

var lm = new layoutManager("LeftHeavyTwoCol");

So the first method to call will be addWindowSet(ws); This is a string that defines the default set of windows to be displayed. The string will contain window id’s and be colon delimited and comma delimited. Colons delimit colums, and commas delimit windows. Here is our default window set.


var windowSet = "blah,foo:bar:blah";

Just a note here, and maybe an area for improvement. This above window set has three columns, and if we select a two column layout the third window is simply dropped.

The last thing we need to do is call the drawLayout(dest_id) method with the destination id.


lm.drawLayout('layout');

We are done. For all the little details, read through the source. If you have any questions, please comment below. If you like this article, Digg it or share it with a friend.

Download and Demo:
Click here to view the demo.
Click here to download the compete souce zip.

The Best Web 2.0 Sign-up Form: Episode One

Monday, August 14th, 2006

figure3-11.gifWell it’s Monday, so let’s do something different. Let’s build a simple form with 2 fields: email address, and password. We want to focus on client side validation, so we will add a second password field to compare against and a password strength field. Password strength is becoming more and more popular, so we’ll build one with a twist - let’s animate it.

Now I have labeled this post as episode one. It will a complete post, however, we will add on to it in the weeks to come to create a full sign-up form with lots of cow bell! One last thing before I start cutting code. This article should be straight forward, maybe 2/5 in difficulty, using JavaScript/Prototype, CSS2 and XHTML.

Okay here we go, first things first. If someone makes an error or mistake, we want to display a custom message. Now, rather then having a message at the top of the screen saying what field the error is on, we are going to have a box dynamically inserted. Well, moved in the DOM pointing right at the field with a custom error message.

So the markup will look like this:

We will call this warning box, warningfs for frame set and hide it right off the bat. At this point it really dosent matter were in the body you put it because we will move it where we need it later. There are a few more components to this warning frame set:

tic: an image pointing up.

msg: id where the message will appear, and disappear when you click on it and

shadow: another box offset to give a shadow effect.

Â? Â? Click here to view the CSS file.

I’m not going to get into the nuts and bolts behind the actual markup as it should be easy to follow. I do want to point out that I used a table rather then div’s -Â? some habits take a long time to break.Â? I felt it would be quicker to write andÂ? less weight on my CSS, but really thats just an exscuse.

What we are going to do is loop through all the input fields and add a focus and blur event to each one, we are also going to validate off the focus and blur in the background.

var aElements = Form.getElements(’form1′);
for(var i=0;i Â? Event.observe(aElements[i],’blur’,fncBlurInput.bind(aElements[i]),false);
Â? Event.observe(aElements[i],’focus’,fncFocusInput.bind(aElements[i]),false);
}

To make the fields light up we use color fx - Tom Jensen (http://neuemusic.com/). I started writing my own color changer, but itÂ? was twice as many lines. Tom Jensen’s is very eleigant. While I’m on the subject of external libaries, we will also use Moo fx, http://moofx.mad4milk.net/, We need it to animate our password strength field and color fx extends it. If you get a chance, check out some of the other stuff Valerio Proietti is up to. It’s all very nice!

So lets have a look at those two functions:

Â? Â? function fncFocusInput() {
Â? Â? Â? Â? Â? Â? Â? var id = this.id;
Â? Â? Â? Â? Â? Â? Â? var colorSwap =Â? new fx.Color(this.id, {fromColor: “#FFFFFF”, toColor: “#EFEFEF”});
Â? Â? Â? Â? Â? Â? Â? var borderSwap = new fx.Color(this.id, {fromColor: “#CCCCCC”, toColor: “#0066FF”, property: “borderColor”});
Â? Â? Â? Â? Â? Â? Â? colorSwap.toggle();
Â? Â? Â? Â? Â? Â? Â? borderSwap.toggle();

Â? Â? Â? Â? Â? Â? Â? $(id).parentNode.insertBefore($(’warningfs’),$(id).nextSibling);
Â? Â? }

Â? Â? function fncBlurInput() {
Â? Â? Â? Â? Â? Â? Â? var id = this.id;
Â? Â? Â? Â? Â? Â? Â? var colorSwap =Â? new fx.Color(this.id, {fromColor: “#EFEFEF”, toColor: “#FFFFFF”});
Â? Â? Â? Â? Â? Â? Â? var borderSwap = new fx.Color(this.id, {fromColor: “#0066FF”, toColor: “#CCCCCC”, property: “borderColor”});
Â? Â? Â? Â? Â? Â? Â? colorSwap.toggle();
Â? Â? Â? Â? Â? Â? Â? borderSwap.toggle();

Â? Â? Â? Â? Â? Â? Â? if (id == ‘email’ && $(id).value.length > 3) {
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? fncValidateEmail($(id));
Â? Â? Â? Â? Â? Â? Â? }

Â? Â? Â? Â? Â? Â? Â? if (id == ‘password2′) {
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? fncPasswordMatch($(id));
Â? Â? Â? Â? Â? Â? Â? }
Â? Â? }

So, walking through the focus function, we set the new focus field and move our warning frame set to the field where there might be a warning. We still keep it hidden. On the blur function we set the color back to the origional, and check to see which field we are working on. If it’s the email field, we run a validate function, and if it’s the second password field, we check to see if it matches the first field.

Here is the email validation function:

Â? Â? function fncValidateEmail(objEmail) {
Â? Â? Â? Â? Â? Â? var strEmail = objEmail.value;
Â? Â? Â? Â? Â? Â? var pattern = /^[a-z][_.a-z0-9-]+@[a-z0-9][a-z0-9-]+\.[a-z]+([.]?[a-z][a-z]+)*/;
Â? Â? Â? Â? Â? Â? var results = pattern.test(strEmail);
Â? Â? Â? Â? Â? Â? Â?
Â? Â? Â? Â? Â? Â? if (results == false) {
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? $(’warningfs’).style.top = getActualTop(objEmail) + 33;
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? $(’warningfs’).style.left = getActualLeft(objEmail);
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? $(’warningmsg’).innerHTML = “Please enter a valid email address.”;
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? $(’warningfs’).style.display = “block”;
Â? Â? Â? Â? Â? Â? } else {
Â? Â? Â? Â? Â? Â? Â? Â? Â? Â? $(’warningfs’).style.display = “none”;
Â? Â? Â? Â? Â? Â? }
Â? Â? Â? Â? Â? Â? return;
Â? Â? }

This is a simple regular expression. If there is an error, we display our warning frame set, else, we make sure it’s hidden. The PasswordMatch function is also quite similar. Check the source for that function.

Now the other big test we do is check the password strength. I’ve kept it out of the focus, blur loop and added the listener to the bottom of the init function ‘onkeyup’. Our password strength is going to be based on a series of tests: is it more then 5 characters, does it have at least one number, does it have at least one uppper case letter, and does it have one special character. Feel free to play with this and make it better.

To create the actual effect, we have two DIV’s sitting on top of each other using z-index, and we use fx.width to animate the top div to show the password getting stronger or weaker. It’s a nice effect and really not too difficult to recreate.

We are done, for now. I really hope you have enjoyed this tutorial, and if you have any questions, please let me know. Also, check back shortly to see how to add IP/GEO lookup checking and Postal/Zip to City checking.

Download and Demo:
Â? Â? Â? Click here to view the demo.
Â? Â? Â? Click here to download the compete souce zip.

References:
Â? fx color - Tom Jensen (http://neuemusic.com/)
Â? moo fx - Valerio Proietti (http://moofx.mad4milk.net/)

AJAX Hello World with Prototype

Wednesday, August 9th, 2006

This article should be a great resource for anyone starting to learn AJAX programming, and we are going to make it even easier with Prototype. I will assume you know the basics in XHTML, CSS, JavaScript, and PHPÂ? even though we won’t actually use PHP. Please visit http://www.w3schools.com/ if you’re already lost at this point.

Let’s really get down to the basics. AJAX is used to deliver data from the server without refreshing the page. Thats it, thats all. Data can be in the form of a page fragment, text, or data that we process into a data array like in our previous example (creating a option list).

We will use Prototype to actually make the AJAX call because it checks to see which browser is being used and does alot of low level processing for us.
The data we want to pull from the server will be a text string “Hello World.” So lets start.

Lets create a file hello_world.html that looks like this:

Â? Â? Â? Hello World

Now lets create main HTML file and make all this work!

Listing 2.1

We are done. Well, almost. Let me walk you though what we actually did here.
LineÂ? 3:Â? We call the Prototype Framework. This should be the first JavaScript file we call because it contains all the objects required to make everything work.
LineÂ? 20: We have a span with an id ‘display_area.’ This is where we want to insert the text from the server.
Lines 7-15: Our main function that does the work.Â? We call it init, but it could be called anything.
LineÂ? 9: We create a new Ajax.Request Object.
LineÂ? 10: We tell it what file to get.
Lines 11-14: The options we pass to the object, they include the method, GET. We could also tell the server we wanted to POST and onComplete.
LineÂ? 13: What we want to do when the the object has completed its operation. We pass in a function to display the response to the display_area id using innerHTML
LineÂ? 6: We need to ‘Fire’ the event and make everything work. We observe onload on the window object and call the init function when it happens.

Thats it, We’re are done. For more info on Prototype and all the other properties, methods, and options check here.