Not in production environment, anyway!

Recently, I have been involved in implementing functionality that requires a modification to the structure of a SQL Server table. In fact, the nature of the change was a simple addition of a new column to the table in question.

Logic would dictate that that wouldn’t be too problematic. Right? Wrong!

The fact is, that when you use ‘*’ to reference all columns on a table, you’ll make it impossible to perform any reliable impact analysis on your code base. Columns will be used without being explicitly referenced.

If you add more columns to the table in future, who can guarantee that your existing views or stored procedures will actually need them? If you have code in them that performs a ‘Select *’ then they will, regardless. The obvious problem with this is the overhead of returning unwanted data from the database, and the potential degradation of performance inherent therein. However, there is another pitfall surrounding table joins, which I will now attempt to demonstrate:

Imagine you start out with two tables:

create table Test (Id int, code char(1))
create table Test2 (Id int, TestId int, name varchar(10))

And you would like a query that joins these two, so you create a view

create view vwJoinTests as
select t.code, t2.*
from test t
inner join test2 t2 on t.id = t2.testid

You can select from this, no problem

select code from vwJoinTests

A year later, another developer comes along and adds a new column to Test2:

alter table Test2 add code char(1)

Now, the column ‘Code’ exists on both tables.

Selecting from the view is still fine:

select code from vwJoinTests

And, because our original ‘select’ remains intact (it doesn’t break anything), this fault will not be picked up by testing.

But, if I want to reapply the view code, I get the following error:
Column names in each view or function must be unique. Column name ‘code’ in view or function ‘vwJoinTests’ is specified more than once.

Why would I want to reapply the view? Well:

  1. You may want to modify it
  2. You may want to rebuild a database
  3. You may want to install a brand new database on a client site

Technically, 2 and 3 are the same, but I thought I’d emphasise the potential for embarrasment when it comes to your clients.

It also emphasises the point that structural changes to the database, should be accompanied by a full database build test to ensure its integrity has been maintained.

,

Go nuts! Here is a free EBook on Defensive SQL Server Programming from Red Gate

Defensive Database Programming with SQL Server

Alex Kuznetsov

ISBN: 978-1-906434-44-1

This leads us to another interesting article:

The Curse and Blessings of Dynamic SQL

, ,

Synopsys

Use chaining as an alternative to variable caching and multiple selector calls.

Where chaining is used, appropriate line breaks and indentation should be used.

Do not over-chain. For long chains it acceptable to cache intermediate objects in a variable.

Description

Chaining is one of the signature features of jQuery. Used correctly, it can reduce the amount of code we have to write and the amount of data that is held in memory.

Chaining can be considered as an alternative to:

  • Caching jQuery objects in local variables
  • Performing multiple selections

Where chaining is used, appropriate line breaks and indentation should be used.

When to Use Chains

Chains should not compromise the readability of the code. For long chains, finding and defining a formatting and indentation strategy can be troublesome.

It can be better in these instances to cache your jQuery object in a separate variable.

When a JavaScript object is cached in jQuery, the reference to the object is actually stored. This occupies a minimal amount of memory, leaving negligible performance degradation.

The items show some indentation strategies, and a representation with a cached variable:

Chain Formatting Examples

Long Chains – Indentation Strategy 1

$("#MyTable").append(
    objButton.parents("tr").clone()
        .find(".RowTitle")
            .text("Row " + String(AddCount)).end()
        .find(".MySelect1")
            .attr("id", "SomeId" + String(AddCount))
                .change(function() { ChangeFundRow() }).end()
        .find(".MySelect2")
            .attr("id", "SomeOtherId" + String(AddCount)).end()
);

Long Chains – Indentation Strategy 2

$("#FundTable").append(
    objButton
        .parents("tr")
            .clone()
                .find(".RowTitle")
            .text("Row " + String(AddCount))
            .end()
                .find(".MySelect1")
                .attr("id", "SomeId" + String(AddCount))
                .change(function() {
                    ChangeFundRow();
                })
            .end()
                .find(".MySelect2")
                .attr("id", "SomeOtherId" + String(AddCount))
            .end()
);

To the untrained eye, either of the above may take some deciphering. In this case, a better strategy could be to cache your selections in a separate variable:

Long Chains – Caching Variable

var $clonedRow = objButton.parents("tr").clone();
$clonedRow.find(".RowTitle")
          .text("Row " + nAddCount); 

$clonedRow.find(".MySelect1")
    .attr("id", "FundManager" + nAddCount)
    .change( ChangeFundRow ); 

$clonedRow.find(".MySelect2")
          .attr("id", "FundName" + nAddCount); 

$clonedRow.appendTo("#FundTable");

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

Do not reinvent the wheel. Use plugins if they fit your functional requirement.

Ensure the plugins are fit-for-purpos, well regarded and well tested.

Description

Plugins are a way by which any developer can extend the jQuery library. They are often useful, frequently well tested and supported, and may well cut down on development time.

The following are some commonly used plugins:

Reviewing Plugins for Use

The review process for including a plugin should encompass some sort of investigation into the plugin itself. The following aspects should be examined:

  • The current level of use I.e. is it widely adopted? Those with a large number of users will be well tested and developed.
  • For which version of jQuery was it written? Is it still valid for your current version of jQuery?
  • The current level of support. E.g. does it have a website with examples, etc. An example of one with good support is BlockUI (http://malsup.com/jquery/block/#)
  • Quality of plugin comments – A quick scan of the code will see if it’s well documented. If its well documented, then it should be well written.
  • How well is it regarded?. A quick internet search across the jQuery community and its users should reveal this.
  • Availability of vsdoc js for intellisense. Not critical, but would be a factor in choosing two plugins that were identical to each other in every other aspect.

Writing Plugins

Whenever you find yourself developing some jQuery that could be considered generic, and could certainly adopted within other areas of the code base, then you should consider turning it into the jQuery plugin.

The ‘how’ of doing this is outside the scope of these standards. Refer to jQuery literature (department books and online) for how to do this. Experienced jQuery developers may also be able to assist.

As a starting point, any plugin should begin with the following closure code convention:

    function($){
        //plugin code
    }(jQuery);

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

Use #ID selector wherever possible. It is the fastest.

Ensure slower selectors are optimised for performance – Combine them with faster selectors where possible.

Custom selectors must be kept simple, as they may end up being run upon every element in the DOM.

Avoid needless selector combinations.

Description

Selectors are ranked by performance as follows:

  1. #Id
  2. Element
  3. .class, :pseudoclass and :custom

The Class and PseudoClass and Custom selectors are slower than ID and Element selectors. The deficiency of their performance can be mitigated by combining them with other selector types, so do this wherever possible.

Examples

    $(".oddRows");                   //Inefficient: scans DOM for all elements with oddrows class
    $("tr.oddRows");                 //More efficient: Searches only <tr>s with oddrows class
    $("#MyTable tr.oddRows");        //More efficient: searches descendents of #MyTable
    $("#MyTable>tbody>tr.oddRows");  //Best: searches immediate children

In these examples, we have combined CSS style selectors to obtain better performance in two ways:

  • Element.WithClass – I.e. search for element with the specified class name
  • #Id Descendents – I.e. search within descendents of the Id.
  • #Id>Children – I.e. search only immediate children

The optimisation of selector performance is essential for efficient jQuery. This must be a major consideration for developers and code-reviewers alike.

Custom Selectors

It is possible within jQuery to define custom selectors, as per the following example:

    $.extend($.expr[":"], {
        textboxEmpty: function(el) {
            return $(el).val() === "";  //must return boolean
        }
});
alert($(":text:textboxEmpty").length);

Custom selectors must be kept simple, as they may end up being run upon every element in the DOM.

Be aware that Custom and Pseudoclass selectors are, at best, as slow as class selectors (complex custom selectors may be even be slower!). Therefore you should attempt to optimise their performance by utilising some of the techniques described above.

For a tutorial on writing custom selectors, check out my blog post here.

Pitfalls and Traps

Assuming Children and Descendants

The example “#MyTable>tbody>tr.oddRows” helps us demonstrates the potential pitfalls of assuming specific children/descendants. Had we written this as “#MyTable>tr.oddRows” then our selector would have returned nothing!

Correct Use of Parent-Child

The selector $(“#MyTable .oddRows”) will return all elements in the DOM with the oddrows class assigned (there is a space between #MyTable and .oddRows)

However, the selector $(“#MyTable.oddRows”) will probably return nothing, as the code imples that we are looking for the table with the Id #MyTable that has the class oddrows assigned to it.

Given the naming convention in the example it seems unlikely that that the table will have the class assigned.

Needless Selector Combinations

The Id of an element should be unique. Therefore there is no need to combine it with other selectors. For example, the selector $(“#MyTable.TableClass”) is probably pointless as the query for #MyTable will already have returned at most one element.

In the same vein, the selector $(“div #MyTable”) is also pointless. Here we are going to select all divs in the DOM, and then scan that subsection for #MyTable.

Defining an Id at the start of a Parent-Child selector can, however improve selector performance greatly, and is strongly encouraged. See selector performance examples above.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

Adopt a restrained and consistent approach to implementing animation functionality.

Description

jQuery provides some basic functionality, the simplest of which is demonstrated by the following code:
    $("#MyDiv").hide("slow");

Here, the hiding of MyDiv is animated.

It is important that a consistent approach to the use of effects and anuimation is adopted across the web application.

There is a temptation when discovering this functionality to ‘go nuts’ and have divs whizzing in from all angles with buttons flashing and all hell breaking loose. In general you should try to show restraint when using animation.

If possible, feed animation use into UI standards.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

Avoid making changes to individual CSS styles using the jQuery API functions.

Use CSS Classes intead.

Description

Avoid using direct CSS style changes (using .css() ), and inbuilt style functions .length(), .width(), etc.

Instead, declare the styles in a class within a CSS StyleSheet file (not inline within an HTML file!), and use .addClass(), .removeClass() or .toggleClass() upon your selecteded object(s).

For example, avoid this type of declaration:

    $("#MyTR").css({
       "background-color":"gray"
    });

Use instead:

    $("#MyTR").addClass("HighlightRow");

    /*In CSS File:*/
    .HighlightRow
    {
       background-color:gray;
    }

This promotes correct separation of content and style.

Embedding style changes in JavaScript/jQuery has the following implications when it comes to rebranding or changing a site’s theme:

  • It is less likely that a consistent approach has been adopted with regard to styling making the task harder.
  • A bigger and more complex  impact analysis required to identify files that require changed.
  • More files require changed.
  • More files = more testing. As we will be changing JavaScript code, we will have to retest more than we otherwise would have.

A discussion on the merits of Behavioral Separation is outside the scope of this article. It may seem a little draconian to advise against using .css() and other style-change functions, but is essential when attempting to achieve this goal.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

1. Adopt a consistent approach when writing document ready events.

2. Use a document ready event in place of window onload.

3. No JavaScript or behavioural markup is to be included in HTML files.

4. Events must be late-bound within the $(document).ready()handler code itself.

5. Use the shorthand event syntax.

6. Anonymous function handlers must be limited to one line of code.

Document Ready Declaration

1. The handler for the document ready event must be an anonymous declared in the following form:

    $(document).ready(function(){
    	//all initialization
    });

This is clear, readable, and should be used ahead of other possible invocations of this functionality, which include:

    $(handler);
    $().ready(handler); //not recommended
    $(document).bind("ready", handler); //not fired if bound after document ready fires

(And, of course, ‘$’ is interchangeable with ‘jQuery’)

This standard stipulates the use of the given format, however the important aspect of this is the recommendation to adopt a consistent approach to writing document ready events.

2. A Document Ready handler must be specified in place of the window.onload event, except in the rare event where this is too soon: http://blog.arc90.com/2008/05/16/a-jquery-tip-dont-use-jquery/

Note: There is no limit on the number of document ready handlers that can be associated with a page. Event handlers are added to a stack that will be executed when the document is ready.

Binding and Behavioural Markup


3. No JavaScript or behavioural markup is to be included in HTML files. For example, the red-highlighted code should not be present in HTML any more:

    <input type="button" id="MyButton" onclick="OnClickMyButton()">

4. Events must be late-bound within the $(document).ready()handler code itself. For example:

    $(document).ready(function(){
        $("#MyButton").click(MyFunc);
    });

    function MyFunc(event){
    }

5. Use the shorthand event syntax:

    $("#MyButton").click(MyFunc); //use this
    $("#MyButton").bind("click", MyFunc); //instead of this

Event Handlers and Anonymous Functions
6. jQuery allows developers to specify anonymous functions for event handlers. For example:

    $("#MyButton").click(function(){//code});

However, to avoid On Ready Bloating (a side effect of late-binding where the document.ready() function handler becomes large, cumbersome, and unmaintainable), these anonymous function handlers must be limited to one line of code:

    $("#MyButton").click(function(){
        MyFunction();
    });

If we need to refer to the this object, we wrap it in a jQuery object, and pass it within our anonymous function (it is better practice to wrap in a jQuery object early on):

    $("#MyButton").click(function(){
        MyFunction($(this));
    });

jQuery will automatically pass the event object when calling our anonymous function. We can access it as follows:

    $("#MyButton").click(function(event){
        MyFunction($(this), event);
    });

Incidentally, the declaration for MyFunction for the above example would be:

    function MyFunction($this, event){
        //code
    }

As well as avoiding OnReady Bloating, this approach makes our code easier to debug and more readable.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsis

Manipulation of the Document Object Model (DOM) can be costly and inefficient, regardless of whether it is undertaken through jQuery or JavaScript.

The API provided by jQuery facilitates greater DOM manipulation, possibility outwith of the awareness of the developer.

Therefore, you should limit the amount of code that performs DOM Manipulation tasks.

Description

The challenge here is to recognise:

  1. When DOM Manipulation is being undertaken
  2. When it is being done in excess.

Both of these are open to interpretation as it is difficult to stipulate exactly what constitutes excessive DOM manipulation.

In general, very little DOM manipulation should really be undertaken. You should be hitting the DOM in this way only when is absolutely necessary.

Let us examine the following example:

    var $myList = $("#myList");   

    for (i=0; i<1000; i++){
        $myList.append("This is list item " + i);
    }

This code adds 1000 lines to an HTML list. This is done with 1000 successive calls to the .append() method, and hence, 1000 manipulations to the DOM.

The following code, modified from the example above demonstrates how this can be made more efficient:

    var $myList = $("#myList");
    var li = "";   

    for (i=0; i<1000; i++){
        li += "<li>This is list item " + i + "</li>";
    }  

    $myList.append(li);

In this example, the HTML is constructed in advance. The HTML is appended in one call, greatly reducing the amount of manipulation you undertake.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Synopsys

All variables that are use to store/cache jQuery objects should have a name prefixed with a ‘$’.

Consider using chains in place of jQuery object variables.

Description

There is often a requirement to store/cache a jQuery selection in a holding variable. Where this is the case, you should prefix the variable name with a ‘$’.

For example:

    var $MyTable = $("#MyTable");
    $MyTable.addClass("MyTable");
    $MyTable.append("<tr></tr>");

Also, in conjunction with $(this):

    var $this = $(this);

Storing in a holding variable helps reduce the number of calls into jQuery, and enhances performance. The dollar notation on all jQuery-related variables helps us easily distinguish jQuery variables from standard JavaScript variables at a glance (e.g. string, integer, etc).

Cached Variables vs Chains

The above example could have been written efficiently as a chain like so:

    $("#MyTable").addClass("MyTable").append("<tr></tr>");

This has the advantage in removing the need for a cached variable, and in this particular case makes sense.

When chains become long, complex and especially hard to read, you should split them up, storing intermediate selections in a holding variable: http://stackoverflow.com/questions/1286829/is-there-a-preferred-way-of-formatting-jquery-chains-to-make-them-more-readable

This does not result in much (if any) of a performance hit. Objects are held as references, not values, so their impact is minimal: http://stackoverflow.com/questions/1287106/can-it-be-disadvantageous-to-store-jquery-objects-in-a-variable

The Chaining Standards cover this in more detail.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Yes, maybe, and yet, a few days ago I code reviewed a bit of code like this:

     $("select[id='MySelect']").val(1);

Where, of course, an ID selector would have sufficed, and would have been faster, smaller and better:

     $("#MySelect").val(1);

jQuery isn’t a silver bullet against bad code. You can still write some quite horrific jQuery, and moreover, as JavaScript isn’t subject to precompilation you can ship syntactically incorrect jQuery.

If this were not enough, jQuery, and in particular the Sizzle Selector Engine does a lot ‘under the hood’ with regard to DOM manipulation and traversal. The consequence of this is that, although you code may look great, and be perfectly bug free, it may grind to a painful halt under real-world stupid-user scrutiny.

Standards can help guard against all of this. I’m not really wanting to get tried up in a discussion on the virtues of standards, but, in general, if you believe in them elsewhere, then they are equally valid here.

jQuery Coding Standards Menu

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining
, ,

Overview

The jQuery JavaScript library has established itself as the most dominant and widely-used JavaScript library available.

And yet, for me, there no sites that appear to pull together best practices for jQuery development in a way that Douglas Crockford has done with his JavaScript Code Conventions.

So, while researching the language for the rollout of a jQuery course, I found myself needing to develop a set of standards.

Some time on from this, lessons have been learned and I feel I have a good workable set of jQuery standards. I have decided to present these in a series of posts that fall under the following headers:

  1. jQuery Variables
  2. DOM Manipulation
  3. Events
  4. Page Style and Layout Changes
  5. Effects and Animation
  6. Selectors
  7. Plugins
  8. Chaining

Scope

The initial scope of these posts is intended to cover coding from the core jQuery library. only. It is not intended to cover the use of jQuery UI, or other high-profile plugins.

Such is the significance and widespread adoption of some of these add-ons, for example the  jQuery forms validator, or anything that malsup has written,  that a set of good practice guidelines for these may also be of benefit. But not here, not now at least.

Audience

These standards were developed following the rollout of jQuery within a corporate development community.

They were a result of capturing developer experiences, and evolved over a number of iterations to suit the ecosystem of a very specific development community.

I do believe, however, that they have a broad relevance and use, and will serve any jQuery developer well.

jQuery Version

These standards were developed against jQuery 1.4.2.

I Don’t Think jQuery Should / Needs To be constrained

I disagree, which is why I’ve written these standards. I’ve felt this warrants a separate article.

I think you/a standard/everything here is wrong

And you may be correct.

I’m happy to change, debate and listen to any opinions to this end, but I would encourage you to bear in mind the audience, and motivation for this. The standards were developed for use within a corporate programming environment, and although I’ve always tried to carry these into my everyday programming adventures, I realise they are not for everyone.

For me, standards are there to make you think about what you are doing. On occasions I think standards can be broken, but these scenarios will be exceptions, not rules. And if you are thinking about deviating from a standards, so you should be thinking about commenting. For a well disciplined programmer, good standards lead to better code and better comments.

You may also feel that I’ve missed something. Quite possibly – this was evolved over a number of months in response the practices adopted by a specific development community. I hope for these standards to evolve now they have been exposed to the outside world!

, ,