Javascript coding suggestions

crockford I am now working on some coding conventions for use at one of my clients. Having done some work on the HTML and CSS ones, I recently started with the javascript one. As I was working on it, I looked at the work done by others, like Douglas Crockford. Some of my co-workers suggested that we did this:

var nameSpace = (function () {
// declare all of your var's before using them..
var config, init,x,doStuff;
config = {
a : 'a'
};
init = function ( arg ) {
doStuff( arg );
};
x = '36';
doStuff = function ( arg ) {
// dostuff
};
return {
init:init
};
}());

While I initially agreed with this, as it seems nice and neat, I spotted a problem with it when it gets big. As you get a really big script and more people working on it, chances are that you will get someone to forget to declare a var in the beginning of the function, hence making it global.
Like this:

var nameSpace = (function () {
// declare all of your var's before using them..
var config, init,x,doStuff;// we forgot to add doMoreStuff
config = {
a : 'a'
};
init = function ( arg ) {
doStuff( arg );
};
x = '36';
doStuff = function ( arg ) {
// dostuff
doMoreStuff();
};// doMoreStuff is global
doMoreStuff = function () {
alert( config.b );
};
return {
init:init
};
}());

So I came up with a (not so revolutionary) way of avoiding this and I am curious what you think of it?
It goes like this:

var nameSpace = (function () {
// start with var to avoid global variables
var config = {
a : 'a',
b : 'b'
},
// continue with a comma to stay in the same var declaration.
init = function ( arg ) {
doStuff( arg );
},
x = '3',
doStuff = function ( arg ) {
// dostuff
};
// end with a semi colon.
return {
init:init
};
}());

I think that this has the advantage that when someone else continues with this code he can extend it easily, while not accidentally introducing globlal variables...

var nameSpace = (function () {
// start with var to avoid global variables
var config = {
a : 'a',
b : 'b'
},
// continue with a comma to stay in the same var declaration.
init = function ( arg ) {
doStuff( arg );
},
x = '3',
doStuff = function ( arg ) {
// doStuff
},// if you add a new var it's not global
doMoreStuff = function (){
// do more stuff
}
;
// end with a semi colon.
return {
init:init
};
}());

What do you think, is this a good way to structure your code or am I missing something?

JQuery coding style

Jun 01, 2010 2 Comments
Tagged: , and

jquery logoI was just documenting a whole bunch of scripts and I noticed that my coding style is not so consistent as I like to think. It seems like I am a real person too :). But this put a question in my head, what do most people do if you chain lots of things. All on one line, or each method on it's own line. Mind you, I compress my code when I go live, so size don't matter much, just readability.

So do you like:

	$( 'foo' )
.clone()
.appendTo('#bar')
.find('p')
.removeClass( 'one' )
.find('input, label')
.val('')
.removeClass( 'two' );

Or do you like this one better:

$( 'foo' ).clone().appendTo('#bar').find('p').removeClass( 'one' ).find('input, label').val('').removeClass( 'two' );

Me I do both, in general I go for the one a method way when it's a lot of code and all on one line when it's only three or four things I am chaining. So, although I go for a consistent style in coding, I seem to violate my own principles when I review a project that I (like this one) work on for months. I wonder if this is something that can be prevented by setting strict coding guidelines or that we should accept it, as long as the overal principles are being followed.

After all, this is a project I worked on with several people, over a period of 6 months. In that time, deviations in coding style can occur, but when you follow the overall guidelines it does no harm in my opinion. The thing is that you should not make you coding standards to strict, as people tend to feel that they are in the way of their work, instead of helping them. Me, I am quit relaxed about coding styles, I tend to agree upon a certain naming convention and some common pattern and that is that. Formatting I can do from textmate, so other people's preferences don't bother me as I take over some code or do a review.

So we agree on a naming convention, like all-small-caps or maybe camelCasing or even using_underscores, and we then select for instance the Revealing Module Patter and of we go...

I am curious about your opinion on this. How do you people approach this when you do a big project or product? Do you work with more extensive guidelines or none at all...

I would really like to hear different opinions, as I think that this sort of thing is getting more important by the day...

By the way, I wrote about CSS coding conventions a long time ago... It still holds in my opion

Pagination script for jquery

Apr 20, 2010 0 Comments
Tagged: , and

A small script I wrote to do pagination, sorting and zebra-striping of a list.

As you can see we start of with a ;, in case some sloppy programmer forgot to add it to the end of his function. Than as a first, we set our namespace as the first thing to do as we don't want to pollute the global namespace. The function is being set as a revealing module pattern.

;var pagination = function () {

We start with an object literal named config to contain the common variables, stuff we use more than once. These variables are private to this function only...

	var config = {
// default amount to be shown
defAm : 15,
// radio buttons for sorting
sort : $('#sort input[type="radio"]'),
sortFirst : $('#sort input[type="radio"]:first'),
// several common classes
hidden: 'hidden',
sorted : 'sorted',
active : 'active'
};

We than initiate the function, this is the only thing we make public at the end of this function.

	var init = function ( t ) {
// check the first radio, just in case ( to avoid problems )
config.sortFirst.attr('checked','checked');
// get the visible li's
var amountSort = $( t +' li:visible').length;
// go to the view function.
view(t,amountSort);
// go and initialize the sorting function...
sort(t);
// as a last thing we get and initiate the script to handle the history stuff.
$.getScript('js/jquery.ba-hashchange.min',back(t));
};

We first start with hiding the list items that need not be shown, the next pages so to speak... When we have done that, we go and build the paging stuff..

	var view = function ( t,amountSort ) {
// hide all of the li's other than the ones on the first page.
$(t+' li').removeClass('even');
$(t+' li:visible:even').addClass('even');
// substract 1 to get the correct amount to be shown...
$(t+' li:visible:gt('+(config.defAm-1)+')').addClass( config.hidden );
// go to paging.
paging(t,amountSort);
};

We build the paging stuff and make it work.

	var paging = function ( t,amountSort ) {
// first we clean up all of the old pagination
$('.pagination').remove();
// we than get the amount of pages
var nr = ((amountSort - ( amountSort % config.defAm ))/config.defAm)+1;
// build the paging ul before the sort radiobuttons
$('#sort').before('<ul class="pagination"></ul>');
// loop through the pages, with the cool guy loop
for ( var i = -1; ++i < nr;){
// append a li with an a to the ul.pagination for each page
// and fill it with the correct number
$('ul.pagination').append('<li><a href="#">'+(i+1)+'</li');
}
// make visible that there is an active page.
$('ul.pagination li:first-child a').addClass( config.active);
// if we click on a pagination link
$('ul.pagination a').click( function (e) {
// get the correct page to show
// note the ,10) this makes sure we can't slip into octal mode...
var link = parseInt( $(this).text(),10);
showHide( t, link);
// now we need to enable the back button...
// we do this by setting the location for the hash tag plugin.
window.location = window.location.toString().split('#')[0] + '#pagination' +link;
// we stop the default action of the (fake) pagination link...
return false;
});
};

This function is wat we use to do the showing and hiding. Note the nice and short :) jQuery selector at the bottom.

	var showHide = function (t,link) {
// remove the active class
$('ul.pagination li a').removeClass( config.active );
// make the clicked one active
$('ul.pagination li:nth-child('+(link)+') a').addClass( config.active );
// show all of the li's
$(t + ' li').removeClass( config.hidden );
// hide all of the li's not on the correct 'page'
// :) notice the nice and short jquery selector...
// it's like this: t = the overall container list.
// in there we find the li's without the class sorted = li:not(.sorted)
// either before the number being calculated = :lt('+(link-1)*(config.defAm)+'),
// note that the number comes from the object literal in config and is therefore easily altered.
// or after that = '+t + ' li:not(.sorted):gt('+link*(config.defAm-1)+')')
// and add a class to them...
// this class also comes from config as I use it more than once..
$(t+' li:not(.sorted):lt('+(link-1)*(config.defAm)+'), '+t+' li:not(.sorted):gt('+((link*config.defAm)-1)+')').addClass(config.hidden);
console.log('lt = '+(link-1)*(config.defAm)+' | gt = '+(link*(config.defAm)))
}

Here we do the sorting, by checking a radio button, gettings it's value and using that to show list items with that class and hiding others.

	var sort = function ( t ) {
// on change
config.sort.change( function () {
// remove all of the sorted and hidden classes, thus making all li's visible
$(t+' li').removeClass( config.sorted );
$(t+' li').removeClass( config.hidden );
// get the value of the radio that is checked.
var v = $(this).val();
// if we selected a filtering option
if( !(v == 'nofilter')){
// hide all of the not chosen li's
$(t+' li:not(.'+v+')').addClass( config.sorted );
}
// go to the view function
// the two arguments are the list and the amount of visible li's (before paging)
view( t,$( t +' li:visible').length );
});
};

This small function utilize the hashchange plugin to make the back buttons work when we page through the pages

	var back = function (t) {
$(window).bind( 'hashchange', function(e) {
var hash = location.hash || '#pagination1';
showHide( t, hash.split('pagination')[1]);
// alert('movement...');
});
};

Here we make the init function public.

	return {
init: init
};
}();

Inline JavaScript

Nov 25, 2009 0 Comments
Tagged: and

As we all know, or should know, the usage of inline JavaScript is not done. For various reasons, it blocks the rendering of your page, it is bad for maintenance and so on.

There is however, one notable exception to this rule. Sometimes it can be usefull to know if you have JavaScript enabled, so you can hide certain elements that depend on a user action. For instance, you have a login button that, when clicked, shows you a box for your username and password with a login button. You don't want to hide this with CSS, so you would do that with javascript. Which you have put at the bottom of your html, just as sir Souders ordained. So at document ready the script kicks in and hides the right element. As this is not noticable on a fast site, sometimes the user can see a Flash of Unstyled Content.

So to countermand that, you can set a class on the HTML element to let the CSS know that it has to hide the correct stuff.

<script type="text/javascript">
document.documentElement.className += ' js-on';
</script>

With this in place you can write CSS to rely on the JavaScript and not have a Flash of Unstyled Content. In my opinion this is the only correct usage of Inline JavaScript.

DL abuse

Oct 26, 2009 1 Comment
Tagged: , , , and

As I had quit a few laughs over my so called abuse of <dl> tags in forms, I decided that it was time I showed him what real abuse of dl's was.

So I present to you the ultimate dl abuse page and it's not even in a form

What I do, is instead of building a proper form with a fieldset and legend in it, I put it all in a definition list. Not quit semantically correct, but at least it is proper and valid html. So this is being written;

<dl>
<dt>Form name</dt>
<dd>
<label for="name">Name</label>
<input type="text" id="name" value="Bruce Lawson" />
</dd>
<dd>
<label for="email">Email</label>
<input type="email" id="email" value="bruce-invalid-email-lawson@foo.bar" />
</dd>
<dd>
<input type="submit" id="go" />
</dd>
</dl>

I then recognize my mistake and correct it with a small bit of JavaScript;

var abuse = function () {
var init = function () {
buildform();
transform();
destroy();
};
var buildform = function () {
$('body').append('<form action="index.html"><fieldset><legend></legend></fieldset></form>')
}
var transform = function () {
var leg = $('dt').html();
$('legend').html(leg)
$('dd').each( function() {
var con = $(this).html();
$('fieldset').append('<p>'+con+'</p>')
});
};
var destroy = function () {
$('dl').remove();
}
return {
init:init
};
}();
abuse.init();

Which gave me a proper form, that looks like this:

<form action="index.html">
<fieldset>
<legend>Form name</legend>
<p>
<label for="name">Name</label>
<input type="text" value="Bruce Lawson" id="name"/>
</p><p>
<label for="email">Email</label>
<input type="email" value="bruce-invalid-email-lawson@foo.bar" id="email"/>
</p><p>
<input type="submit" id="go"/>
</p>
</fieldset>
</form>

So my question of the day is this: Is this the ultimate dl abuse, or can you come up with a worse one?

Please not that this is NOT serious and should not be taken as such.

Update

As Molly rightfully noted, this is more JavaScript abuse than dl abuse. So if you have examples of the former, please let me know...

just in time initialization

just in time initialization

Or as we need a catchy name for this: JITI. This is 'cause we all know that we need a catchy name for something to catch up...

Part 1 - the HTML

what is JITI and what is it to you?

It stands for Just In Time Initialization and I first heard about it from PPK. He came in at one of my clients to review my javscript work there and he told me about some stuff he was working on. JITI is a way to utilize the DOM as you API, something to speed up the loading and rendering time of your page.

At anwb.nl/verkeer I have started using it, in order to speed up the page. We used to render the images of for instance the rain radar as we loaded the page (anwb.nl/verkeer ) and hide them with css. If you clicked on the appropriate checkbox we would set a css class on the body and show the image. This all seemed well and good, but a lot of people come to this page for just the traffic information and the traffic information alone. So why should we have them wait for the image they will never see...

JITI to the rescue.

so now instead of loading the image before hand, we only load the location of the image, like this.

<li>location/of/the/image.gif</li>

As we don't actually load the image, this results in no http request or data collected from the server, until we request the image to be shown by clicking the appropriate checkbox. We then let a small bit of javascript change that to:

<li>
<img scr="location/of/the/image.gif" alt="alttext" />
</li>
The point

So why am I so excited about this? It simply means that we wont let the user wait for data he has not requested. He will not wait longer for a couple of features he may never use, only for what he wants to use. And by doing it by utilizing the dom as our api we don't burden the server with this, just the client and he asked for it...

We do a similar thing with the weather information, instead of rendering the html structure we need to show the weather stuff, we only render the data at page load.

so the user gets from the server this:

<li>
<span>136,63,63,105</span>
<div class="weerB" title="licht bewolkt">
licht bewolkt|18.0|zo|2|0.0
</div>
</li>

Breaks added for clarity, the real thing is one big line of code, better yet the whole html code is nearly devoid of white space or breaks.

after checking the box to see the weather we change that into:

<li 
style="top: 136px; width: 63px; height: 63px; left: 105px; position: absolute;">
<div class="weerB" title="licht bewolkt">
<dl>
<dt>licht bewolkt</dt>
<dt/>
<dt>tekst</dt>
<dd>18.0</dd>
<dt>temp</dt>
<dd>zo</dd>
<dt>windrichting</dt>
<dd>2</dd>
<dt>windrichting</dt>
<dd>0.0</dd>
</dl>
</div>
</li>

Sure, we could do all this with a couple of ajax calls, but with this solution we save the server a lot of calls ( this is a page that gets a couple of million visitors a month) and it's faster after the page has been downloaded. Yes the user still has to download a couple of bytes that may not be needed, but only minimal. If the extra data is a lot more, than a ajax call to fetch that data is viable in my opinion but you have to decide what to use on a case by case basis.

I am wondering if I need a part 2 for the javascript, but I would like to hear your opinion on this

bing on bling

Jun 04, 2009 0 Comments
Tagged: , , , and

bing.com is the new search engine of microsoft. It could be great with the amount of smart people at Microsoft and the amount of money thrown at it. The search results are what you expect from any decent engine (a search for wnas puts me on top). But what got me baffled is the markup of the page, which comes in at a hefty 26,708 bytes. And that for a page which has one input field and some links... Me as a front end developer, I'm baffled by that size and kinda insulted. I have to wait longer because they used front page or what ever, no way, not in 2009 I don't.

The real fun comes when you do a certain magic trick called view source. Most of the size of the HTML is being formed by inline css and javascript. There even is a table in there, along with inline script handlers...

1999 called and it want's it's markup back, guys.

The numbers

Still I get back to the size of the page, a whopping 26,708 bytes with all the bells and whistles. If you strip the javascript alone, you're still left with just 13,462 bytes.

Thats 13,246 bytes of inline javascript for you.

So no javascript solves the size and the waiting time? Not quite, we have inline css too. So if we get rid of that, we are left with 5,524 bytes.

So the css alone is 7,722 bytes.

It seems that were getting there, no. No way, the html is very much too much and can be optimised to I think half of it's current size.

That size being 5,524 bytes for HTML alone.

If they got the correct markup and got their CSS and JavaScript from external sources, the user would only had to download that once. And would get a better experience, because faster is better.

Conclusion

I think that the front end of this page was build by a .net developer, who thinks everybody got a broad band connection. Maybe that is the case, but I know that my patience is less now than it was when I had a 14k4 modem. If I have to wait, even for a few seconds, it's not my fault and the chance that I navigate away from that page would be greater now than it was back in the 14k4 days.

So Microsoft, please clean up your act and hire a decent front end developer. Maybe you could look at this awesome presentation from Nicole Sullivan at yahoo. It shows you how much speed matters.

Textmate plugins

In my work I use textmate, the mac only editor from macromates. It comes with the abilities for macro's and plugins, some of them are in my opinion very usefull for a web developer.

CSS

For CSS I absolutely love this one Format CSS single-line. With this you can format your CSS in the way you prefer, simply by pressing ctrl-q.

You choose either 1 or 2, where the latter is the single-line option you should go with when you publish stuff.

JavaScript

Another one is for writing javascript, the one thing that makes it usefull to me is that it runs jslint on my js as I save. That sort of thing keeps me sharp and makes me put ; in all of the right places. It warns you, nice and unobtrusively, of any warning or errors as you save. And you can call it before that to get a nice window, where you can click right through to the line where the error is.

validate

It also compresses your JavaScript files in two ways, minifying or obfuscating it. You can get it here: Javascript tools.

@media 2009 and other conferences

This year I will be attending some conferences, here is my list of the ones I will be going to.

@media 2009

In a few months I will be attending my 6th (sixth) @media conference. This time I booked a room in the hotel which is the closest to the venue, the Premier Inn London County Hall. No more wandering around london in the rain, as I did after a few pints at the first @media ajax november 2008. No more standing in cramped underground trains as I did at my last company sponsered visit in spring 2008.@media 2009

I am looking forward to seeing all of the speakers, especially the ones I haven't seen like Simon Collison and Jason Santa Maria. I'm curious on the one track arrangement, as I always had a love hate relation with the two track thing. Two of my favorite speakers would always be on the same time in a different room. I am not sure that I like the whole no-lunch thing, but I understand that the guys from vivabit had to do something to keep is affordable in these times.

Still the cost of a conference to me is not the ticket alone, I have to fly over and get a hotel for a couple of nights. So the cost of the ticket is only 40% of the whole, less so if you reckon that I won't be billing clients for three days. But the real value is off-course in the speakers and speaking to lots of fellow web developers from all over europe and to that I am really looking forward to.

Fronteers

The other conference I am going to attend is Fronteers 2009. Not that I have much of a choice as I have been drafted by PPK to help organizing the whole thing. One of the advantages is that I already know which speakers we have lined up. All I can say at this point is that you really, really have to attend this one..

fronteers

Full frontal

The third one I may attend is Full frontal as the speakers line up sure looks impressive for a day which costs only 100 pounds. I am not sure about this as it comes awfully close after fronteers and I may have some work to do sometime. On the other hand this could be my replacement for my yearly javascript conference fix that @media Ajax provided...

So if you are attending any of these, have fun and I will see you there.

jQuery UI slider

The past few weeks I had a lot of fun playing with jQuery UI for a client. They wanted to replace some elements in an application, sliders and such, with a more accessible solution. For that I turned to jQuery UI, as I had previously introduced jQuery as the standard javascript library for them.

As I started to play with the code I couldn't helped but be impressed by the great work that has been done by the UI team on this project. But as I looked at it more closely I found some things that could be improved.

So here are some of my grieves with it and a possible way to solve them. I am going to concentrate on the slider ( docs / demo ), as it was with that widget that I started to notice some things missing.

The way you use it is in a true jquery fashion nice and unobtrusive, once you have included the correct javascript files (for that see the documentation), you just do:

$("#slider").slider();

And shazaam, #slider has turned into a slider, nice... But, what happens to the input that people provide...

This solution is nothing without javascript, so in my book it is a nono. I can not imagine that I could use this widget on my sony erikkson k800 phone. So accessible it is not, at least not in the way the demo shows us. And as most people will just copy and paste from demo's, most sliders will not be accessible.

So what you say, a slider can never be accessible, rubbish I say. Stick with me and I will show you a very simple way to make this accessible. And in a few day I will put up some example sliders to accompany the code as suggested by Danny Lagrouw.

Improvement

First we will look at what a slider does, it provides a user the possibility to enter data. Whoa, a whole new concept... eh no.

Lets start with an simple < input type="text" /> that gives people a good opportunity to enter a value, no? But what about stepping you say, that we can solve with a few < input type="radio" />. All we have to do is write javascript that sends the value of the slider to the input and when the form is submitted, the server can sort it out.

If a user has no javascript a viable alternative is provided. So not only advantages on the user level, but did you notice that we just solved the data to server problem, in a way that requires us to write zero I admit it is boring but if you want your fancy interface to do something, it has to interface with the back-end as well.

So we start with the html, as that is the base for accessible solutions, we set up a free form slider. As we do this, we make sure that we create a fully functional option for everybody. That is, the purpose of the slider is to set a value.

<div class="slider free" id="slider">
<label for="text">
label
</label>
<input type="text" id="text" />
</div>

As you see a nice and clean solution where data can be entered and processed. What we miss is the fancy slider, which we will create with javascript like this:

// add a slider container div
// add a slider handle to slider container
// place a span to recieve the value
// and add a class to the container
// find and set the input to readonly
jQuery('.slider')
.append('<div class="slideContainer"> // br
<div class="ui-slider-handle""> // br
</div> // br
</div> // br
<span class="value"></span>') //br
.addClass('sliding') // br
.find('input').attr("readonly","readonly");
// linebreaks (br) added for readability

There you have it, an accessible solution for a slider, simple as that.

But wait, what if I have 5 steps that I want people to choose from. That I cannot do, so your solution sucks and I still am stuck with a pure javascript solution says the sceptic (I know who you are...). Oke, the second one is a slider with steps for you.

First let us see what that is, it is simply a option you choose from a limited number of options isn't it. The html solution for this is really easy, radio buttons. So of we go with html

<div class="slider steps" id="slider2">
<fieldset class="radios">
<legend>legend</legend>
<input type="radio" name="radio" value="0" id="v0" />
<label for="v0">zero</label>
<input type="radio" name="radio" value="1" id="v1" />
<label for="v1">one</label>
<input type="radio" name="radio" value="2" id="v2" />
<label for="v2">two</label>
<input type="radio" name="radio" value="3" id="v3" />
<label for="v3">three</label>
<input type="radio" name="radio" value="4" id="v4" />
<label for="v4">four</label>
</fieldset>
</div>

Just like that we have a viable and accessible solution in plain old semantic html, now for the javascript.

var sliderSteps = {
radiobuttons : ((jQuery(this) //br
.find('input[type="radio"]') //br
.length)-1) //br
.toFixed(0),
init : function(targ){
sliderSteps.createSlider(targ);
sliderSteps.set(targ)
},
set : function(targ){
var w = (100/((sliderSteps.radiobuttons*1)+1));
jQuery(targ) //br
.find('label, .ui-slider-handle') //br
.width(w+'%');
},
createSlider : function(targ){
jQuery(targ).slider({
// zoveel stappen als er radio button zijn...
steps : sliderSteps.radiobuttons,
change:function(e,ui){
var x = jQuery(this).slider('value');
var a = (x/100*((jQuery(this). //br
find('input[type="radio"]').//br
length)-1)).toFixed(0);
// set the value somewhere...
jQuery(this).find('.value').text(a);
// check the radiobutton.
var t = jQuery(this). //br
find('input[@type="radio"]')[a];
jQuery(t).attr('checked','true');
}}
);
}
}
sliderSteps.init('#slider2.steps');
// linebreaks (br) added for readability

So there you have it, a nice clean and accessible slider solution for the folks at jquery ui to include in their demos. And for everybody else to look at and maybe even use. So have fun with it and let me know if you like it.

If you see any faults in the code please let me know, but as I am on holiday now, don't except me to rush...

Here is all the demo code zip file wn.slider.zip for you to play with.

Technorati Tags:, , ,