Click here to Skip to main content
15,896,201 members
Articles / Web Development / HTML

A jQuery plugin for an Adaptive 960 Grid System

Rate me:
Please Sign up or sign in to vote.
4.50/5 (4 votes)
3 Oct 2011GPL38 min read 33.8K   318   17  
Article discussing the development of a jQuery plugin to be used with adaptive 960 Grid System
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>The Code Project</title>
<style>
BODY, P, TD { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt }
H2,H3,H4,H5 { color: #ff9900; font-weight: bold; }
H2 { font-size: 13pt; }
H3 { font-size: 12pt; }
H4 { font-size: 10pt; color: black; }
PRE { BACKGROUND-COLOR: #FBEDBB; FONT-FAMILY: "Courier New", Courier, mono; WHITE-SPACE: pre; }
CODE { COLOR: #990000; FONT-FAMILY: "Courier New", Courier, mono; }
</style>
<link rel="stylesheet" type="text/css" href="http://www.codeproject.com/App_Themes/NetCommunity/CodeProject.css">
</head>
<body bgcolor="#FFFFFF" color=#000000>
<!-------------------------------     STEP 1      --------------------------->
<!--  Fill in the details (CodeProject will reformat this section for you) -->

<pre>
Title:       A jQuery plugin for an Adaptive 960 Grid System 
Author:      dniswhite
Email:       denniswhite98@yahoo.com
Language:    HTML, CSS, javascript, jQuery
Platform:    Web
Technology:  HTML, CSS, jQuery, javascript
Level:       Intermediate
Description: Article discussing the development of a jQuery plugin to be used with adaptive 960 Grid System
Section      HTML / css
SubSection   Ajax
License:     GPL, MIT
</pre>

<!-------------------------------     STEP 2      --------------------------->
<!--  Include download and sample image information.                       --> 

<ul class=download>
<li><a href="Article_demo.zip">Download demo project - XXX Kb </a></li>
<li><a href="Article_src.zip">Download source - XXX Kb</a></li>
</ul>

<h2>Introduction</h2>

<p>I have long been a fan of the work at <a href="http://960.gs">960.gs</a>, in my opinion, its 
simplistic approach in the layout and design of a web page will most likely interest others.</p>

<p>My interests in jQuery over the last couple of years have been equally as great (probably more). 
Mostly because I like the idea of how it simplifies javascript development into 
a reusable library so that I don't have to clutter my own development. So recently when I came 
across some javascript code at <a href="http://adapt.960.gs">http://adapt.960.gs</a> to make web 
pages adaptive to the changing sizes of web browser. Naturally I started looking into an even 
simpler approach.</p>

<p>Of course, I wanted something that could be done in the form of a <a href="http://jquery.com/">jQuery</a> 
plugin and that would ease my daily development.</p>

<p>So in this article I will go over the details of developing a jQuery plugin, while at the same 
time creating something that we all can use in our daily development.</p>

<h2>Background</h2>

<p>Ok so for all you jQuery developers out there (both old and new) you probably know how you want 
a plugin to work right?</p>

<p>Personally, I am always amazed with those plugins where you, as the developer, using them writes 
like one line of code and then all this really cool stuff just happens. You know the kind of stuff 
that would have normally taken you several dozen or even worse several hundred of lines of code 
to write (not to mention the hours).</p>

<p>Don't get me wrong, I love the complex problems, but once they have been solved by me or someone 
else, then my interest level diminishes. There are only so many ways to improve the design of a 
wheel in my opinion.</p>

<p>I want something like the following to fit neatly into a script block on a web page:</p>
<pre lang="jscript">
	// variable to hold instance of my plugin
	var plugin;

	$(function() {
		plugin = new $.jQueryAdaptive960(window);
		
		// other code to be run on page load
	 });
</pre>

<h2>Basics of a jQuery Plugin</h2>
<p>Lets go over the quick basics of a jQuery plugin by showing a simple framework for the layout 
of one.</p>

<pre lang="jscript">
	;(function($) {
		$.jQueryAdaptive960 = function(element, options) {
			var defaultOptions = {
			}
			
            // save the element
            var pluginElement = el;

			var jQuery960 = this;
			
			var init = function() {
				if(options) {
					jQuery960.settings = $.extend(defaultOptions, options);
				}
				else {
					jQuery960.settings = defaultOptions;
				}
				
				// other init stuff for you plugin goes here
			}
			
			// your own plugin development stuff goes here
			
			// always keep this at the end
			init();
		}
	}) (jQuery); 
</pre>

<p>Looks simple right? Let me go over things with a bit more detail.</p>

<p>The first and last line of the plugin are how we make this control become a part of jQuery as 
well insuring that we still have access to jQuery itself. We have this awesome framework so we 
want to make sure that in our plugin development we can still use it.</p>

<p>The entry into our plugin starts with the <code>$.jQueryAdaptive960 = function(element, options)</code>
 where the plugin object is created as well as the receiving objects it will work with.</p>
 
<p>The first parameter to our jQuery plugin, <code>element</code>, and in about 99% of the 
cases where you develop a jQuery plugin, you find the control or page element. In the case of this 
plugin we will be passing the <code>window</code> for reasons to be explained later.</p>

<p>The second parameter is simply any options that the page developer and user of the plugin may 
want to pass in. Very important that you understand the options passed into the plugin are optional 
because sometimes the developer will just want the thing to work. We will see later in the 
<code>init</code> function how we handle this scenario.</p>

<p>Now let's move onto to the meatier side of the plugin.</p>

<h3>Plugin Settings</h3>
Remember that I said it is important to understand that some developers will never want to pass 
any options into your plugin. Taking this into consideration you will want to make sure that your 
plugin has a default set of options of which to operate with. We handle this by creating an object 
to contain our <code>defaultOptions</code> that we will be using. 

<p>I don't want to get into the details of object oriented programming with javascript but the 
following will be how we expose our public properties to the outside world:</p>

<pre lang="jscript">
    // save the element
    var pluginElement = el;

	var jQuery960 = this;
</pre>

<p>For all of you object oriented purists out there (yeah you know who you are) please don't flame an 
argument about how javascript is not an object oriented language.</p>

<p>Whatever is assigned to <code>jQuery960</code> will now become a publicly accessible property, 
or function to whoever uses the plugin.</p>

<p>Finally, we save the element passed to us in <code>pluginElement</code> that we can reference 
it in other areas of code.</p>

<h3>Plugin Initialization</h3>
<p>One more step, and then you get your official (well maybe not official) badge as a jQuery 
Plugin Magician. Since we have already included the jQuery framework this final step is simplified 
even further for us.</p>

<pre lang="jscript">
	var init = function() {
		if(options) {
			jQuery960.settings = $.extend(defaultOptions, options);
		}
		else {
			jQuery960.settings = defaultOptions;
		}
			
		// other init stuff for you plugin goes here
	}
		
	// your own plugin development stuff goes here
			
	// always keep this at the end
	init();
</pre>

<p>Remember I mentioned that sometimes a developer will want to just use your plugin without 
passing any parameters? Well in the initialization of the plugin we will handle this scenario 
by checking to see if something was passed in. In the event that we did receive something we 
are going to use the jQuery <a href="http://api.jquery.com/jQuery.extend/"><code>$.extend()</code></a> 
function call to update our default settings.</p>

<p>Finally, at the very end of the plugin, we will make a call to the <code>init()</code> function 
which will make sure that everything gets initialized. As a note of personal importance I like to 
have the <code>init()</code> be the last line in a plugin, it insures that everything has been 
loaded and is fully accessible to the rest of the plugin.</p>

<h2>Using the code</h2>

<p>So now that the basics of the plugin are taken care of lets put together a working example 
how to use it.</p>

<p>By now I am assuming you have had a chance to review <a href="http://adapt.960.gs">http://adapt.960.gs</a> 
 because the goal is to fashion that into a jQuery plugin. Remember the goal is to give the users 
 of our plugin something simple that takes care of everything for them. I am thinking that something 
 like the following will work:</p>
 
 <pre lang="jscript">
	// variable to hold instance of my plugin
	var plugin;

	$(function() {
		plugin = new $.jQueryAdaptive960(window);
		
		// other code to be run on page load
	 });
</pre>

<h3>Default Settings</h3>
<p>So in the direction of keeping things simple I thought it best to bundle all of the required CSS files with the 
plugin. At the same time I want to make sure to cater as much as possible to those looking to take things a step 
further.</p>

<p>The following should be enough to support both developers and their individual use:</p>

<pre lang="jscript">
    var defaultOptions = {
        ranges: ['0px    to 760px  = mobile.css',
        '760px  to 980px  = 720.css',
        '980px  to 1280px = 960.css',
        '1280px to 1600px = 1200.css',
        '1600px to 1920px = 1560.css',
        '1940px to 2540px = 1920.css',
        '2540px           = 2520.css'],
        path: 'jquery960/css/',
        onResize: function () { },
        onRotate: function () { }
    }
</pre>

<p>To make this plugin extensible I make both the <code>ranges</code> and the <code>path</code> for the CSS 
information an option that can be replaced by developers. Then I added two callback functions so that the 
developer can be notified when the browser is being resized as well as rotated.</p>

<p>If you have read through the code at <a href="http://adapt.960.gs">http://adapt.960.gs</a> you will notice 
they had a <code>dynamic</code> variable to turn on/off the dynamic abilities to update the page. At first I 
had that option configurable but then I thought if they don't want it be dynamic then they most likely wont 
have a need for the plugin.</p>

<h3>Plugin Initialization</h3>
<p>With the settings all in place now let's move on to the initialization of the plugin. Our initialization steps 
should be fairly simple. Most of what we are going to be handling in this step is the subscription to events to 
notify the plugin of when the browsers size has changed or it has been tilted.</p>

<pre lang="jscript">
    var init = function () {
        if (options) {
            jQuery960.settings = $.extend(defaultOptions, options);
        }
        else {
            jQuery960.settings = options;
        }

        if (pluginElement.addEventListener) {
            pluginElement.addEventListener('resize', reactiveDisplay, false);

            if (pluginElement.onorientationchange) {
                pluginElement.addEventListener('orientationchange', rotateDisplay, false);
            }

            setTimeout(checkDisplayOrientation, 1000);
        }
        else if (pluginElement.attachEvent) {
            // old ie support and there is no support for orientation
            pluginElement.attachEvent('onresize', reactiveDisplay);
        }
        else {
            // definitely no orientation support
            pluginElement.onresize = reactiveDisplay;
        }

        adaptDisplay();
    }
</pre>

<p>As said before basically everything being done is to subscribe events. This should give the plugin the 
ability to work across most (hopefully all) of the browsers in operation. The important part to take note 
on is the last line where a call to <code>adaptDisplay()</code> is made.</p>

<h3>Active Screen Adaptations</h3>
<p>I don't intend to go over every line of code in the function <code>adaptDisplay()</code>, the details 
of what is happening lie in the <code>while</code> loop as it iterates through 
<code>defaultOptions.ranges</code> searching for a range that fits with the browsers current 
dimensions.</p>

<pre lang="jscript">
    var adaptDisplay = function () {
        ....

        // get the width of the browser
        var width = pluginElement.innerWidth || pluginElement.document.documentElement.clientWidth || pluginElement.document.body.clientWidth || 0;

        // loop through each of the items inside of defaultOptions.ranges
        while (index--) {
            item = defaultOptions.ranges[index].split('=');

            range = item[0];
            cssFile = item[1] ? item[1].replace(/\s/g, '') : index;

            // check to see if a range has been specified
            is_range = range.match('to');

            // get the min and max values for the range
            val_1 = is_range ? parseInt(range.split('to')[0], 10) : parseInt(range, 10);
            val_2 = is_range ? parseInt(range.split('to')[1], 10) : undefined;

            // check to see if the width of the browser falls within the range of the current range setting
            if ((!val_2 && index === (rangeLen - 1) && width > val_1) || (width > val_1 && width <= val_2)) {
                url = defaultOptions.path + cssFile;
                break;
            }
            else {
                url = '';
            }
        }

        ....
    }
</pre>

<p>In the case of our default settings for the plugin a valid range containing a CSS file will 
always be found to match with the browsers current size. You will notice as you resize the browser 
this code gets exercised and if you view the source of the page (not the original source) you 
will see the link for the CSS file being changed.</p>

<p>The page adapting itself to the new size is the inner working of the browser in conjunction with CSS file 
that it was informed to render against.</p>

<h4>Viewing Page Source</h4>
<p>Important Note:</p>

<p>When viewing the page source make sure that you are viewing the active document. If you don't 
see a line in the header that looks similar to the following:</p>

<pre lang="html">
	</<link href="jquery960/css/###.css" rel="stylesheet" />>
</pre>

<p>Then you most likely are not viewing the pages active source.</p>

<h3>Notification Events</h3>
<p>The important thing to take note of in all of the notification handlers is how they handle notification 
back to the developer using the plugin. Remember the original idea was to allow a developer to use the plugin 
and only have to supply the <code>window</code> that it will be working with. This scenario is handled by 
giving the callback functions a default function handler.</p>

<pre lang="jscript">
    var defaultOptions = {
        ....
        onResize: function () { },
        onRotate: function () { }
    }
</pre>

<p>Should the developer want to extend their use of the plugin and be notified of these events they only have to 
change their call in how they use the plugin.</p>

<p>The following is an example of how to override the control and be notified of when the browser is resized or 
tilted:</p>

<pre lang="jscript">
    $(function () {
        var plugin = new $.jQueryAdaptive960(window, { onResize: function () { }, onRotate: function () { } })
    });
</pre>

<h2>Points of Interest</h2>
<p>Check out <a href="http://jquery.com/">http://jquery.com/</a> for more information on this amazing javascript framework.</p>
<p>For more information on the 960 Grid System checkout <a href="http://960.gs/">http://960.gs/</a></p>

<h2>History</h2>

</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
United States United States
I am software developer with over 20 years of professional experience. I have been employed as a software developer since the early 90′s back when Microsoft’s Windows 3.1x was gaining popularity and IBM’s OS/2 was the predominant leader in 32-bit PC based Operating Systems.

Prior to choosing this as my profession I had studied architecture and then later Electrical and Mechanical engineering in college. As a young kid growing up I always played with computers, my first computer was a TRS-80 that I would spend countless hours writing programs for, I never really thought of programming as a profession. The story goes that in my final year of college I took a C/C++ programming class and had so much fun working on the various projects that my professor told me something that changed everything.

“You know they pay people to do stuff like this for a living?” – Professor Bolman

Check out my blog here.

My current and ever evolving projects:

jqAlert javascript alerts done right for those using jQueryUI.
DooScrib Doodle and scribble pad written in javascript for use with HTML5 Canvas.

Comments and Discussions