How to set custom rules in jQuery Validation plugin for fields that have a period "." in their names

We all love and use jQuery Validation plugin. For basic forms it does a great job and works flawlessly 80% of the time. But we all work on different kinds of projects and validation requirements change project to project.

jQuery Validation is a very flexible plugin and provides a way to easily define your own validation rules. You can read more about jQuery Validation plugin and custom validation rules here. It is quite straight forward.

Anyway, I was working on a project that requires the use of custom rules and I had no control over the generated HTML code and used CSS selectors. So I had to work with CSS classes that had period "." symbol in their names. My first attempt failed.

Here is the code that failed. Pay attention to the selector name with the (.) in it's name.

rules: { 
    user.email: { 
        required: true, 
        email: true 
    } 
} 

It is common in Java programming world that your form fields have periods (.) in their names and this is an example of that. So to solve the problem all you have to do is to make the object key a string like this:

rules: { 
    "user.email": { 
        required: true, 
        email: true 
    } 
} 

This will solve your problem and let you get on with your project. Happy coding...

5 easy tips on how to improve code performance with huge data sets in jQuery

Sitting on jQuery's support mailing list I noticed that developers use jQuery with huge data sets and their code becomes very slow. Examples would be generating very long tables with a lot of rows using AJAX to get JSON data. Or iterating through a long (very long) list of data, etc.

So I compiled a list of 5 easy tips on how to improve your code performance while working with huge data sets in jQuery.

  1. Use JavaScript native for() loop instead of jQuery's $.each() helper function.

    Native browser functions are always faster then any other helper functions that were built to add an abstraction layer. In case you are looping through an object that you have received as JSON, I highly recommend you rewrite your JSON to contain an array rather than an object.

  2. Do NOT append an element to the DOM in your loop.

    This one is probably one of the most important tips that will significantly improve your code performance. It is so important that I will repeat myself. Do not append a new element to the DOM in your loop statement. Instead store it in a variable as text and append it to the DOM after your loop finishes like this:

    // DO NOT DO THIS 
    for (var i=0; i<=rows.length; i++)  
    { 
        $('#myTable').append('<tr><td>'+rows[i]+'</td></tr>'); 
    } 
    
    // INSTEAD DO THIS 
    var tmp = ''; 
    for (var i=0; i<=rows.length; i++)  
    { 
        tmp += '<tr><td>'+rows[i]+'</td></tr>'; 
    } 
    $('#myTable').append(tmp);

  3. If you have a lot of elements to be inserted into the DOM, surround them with a parent element for better performance.

    When you have a lot of elements to insert into the DOM tree it takes time to add them all. Somehow adding one element with 1000 children is faster than adding 1000 children separately. You can search this site for performance tests that prove it.
    So, to improve our previous example's performance let's cover <tr>'s with <tbody> tag like this:

    var tmp = '<tbody>';
    for (var i=0; i<=rows.length; i++)
    {
        tmp += '<tr><td>'+rows[i]+'</td></tr>';
    }
    tmp += '</tbody>';
    $('#myTable').append(tmp);

  4. Don't use string concatenation, instead use array's join() method for a very long strings.

    var tmp = [];
    tmp[0] = '<tbody>';
    for (var i=1; i<=rows.length; i++)
    {
        tmp[i] = '<tr><td>'+rows[i-1]+'</td></tr>';
    }
    tmp[tmp.length] = '</tbody>';
    $('#myTable').append(tmp.join(''));

  5. And the last but not least use setTimeout() function for your long list looping and concatenation functions.

    This will make sure that page does not freeze while it loops through the long list of data and lets users to work with your page meanwhile.

    It was well mentioned in comments that setTimeout() function should be used to split your code processing into little chunks so your browser does not freeze up like this:

    function myFunk(data){ 
         
        // do processing 
         
        if(!has_finished) 
            setTimeout("myFunk()", 100); 
    }

How to check jQuery version?

This post will show you how to check currently loaded jQuery version on the page. This maybe useful in your jQuery plugins, in cases when your code utilizes jQuery version specific methods. Also, when you are writing code that runs in an environment where jQuery is already embedded. For example in open source CMS's like Drupal, Magento Ecommerce, etc.

jQuery keeps track of the current version of the script being used in jQuery.fn.jquery property. Both major version version 1.x and version 2.x have this property.

 // Returns string: "1.10.2"
jQuery.fn.jquery;

// Since jQuery == $, we can use shorthand syntax
$.fn.jquery;

You can look into the jQuery source code and find out that jQuery.fn is a reference to jQuery.prototype.

jQuery.fn = jQuery.prototype = {
 // The current version of jQuery being used
 jquery: version,
...

This means we can use alternative method to get current jQuery version like so:

// Alternative method, also returns string
jQuery().jquery;

// or shorthand method
$().jquery

Caveats & notes

I would like to remind you that jQuery must be loaded before you call the code above. Otherwise, it will throw an error: ReferenceError: jQuery is not defined or TypeError: $(...) is null. To avoid it, you can check for existance of jQuery first.

if (window.jQuery) {  
  jQuery().jquery;
}

If jQuery is not loaded, we can load it dynamically from an alternative location.

if (!window.jQuery) {  
  var jq = document.createElement('script');
  jq.type = 'text/javascript';
  jq.src = '/path-to-your/jquery.min.js';
  document.getElementsByTagName('head')[0].appendChild(jq);
}

Also, learn how to check loaded jQuery UI version.

How to disable all jQuery animations at once

Yesterday I came across jQuery.fx.off setting in jQuery documentation. It disables all jQuery animations effective immediately when you set it's value to true.

Consider this code:

jQuery.fx.off = true;

$("input").click(function(){
  $("div").toggle("slow");
});

Your div will be showed/hidden immediately without animation. One of the reasons (as documentation mentions) to disable animations would be "slow" environments.

How to get full html string including the selected element itself with jQuery's $.html()

Sometimes you need to get the selected element's html as well when using .html() function. To make it more clear what I mean, consider you have this HTML markup:

<div id="top">
  <div id="inner">
    Some content
  </div>
  More content
</div>

And you need to get not only <div id="inner">Some con... but <div id="top"><div id="inner">Some con...

Here is the code to get jQuery selector's HTML including its own:

var html = $('<div>').append($('#top').clone()).remove().html();

Here we are:

  1. Cloning selected div
  2. Creating a new div DOM object and appending created clone of the div
  3. Then getting the contents of wrapped div (which would give us all HTML)
  4. Finally removing the created DOM object, so it does not clutter our DOM tree.

This is a little trick you can use to select self HTML with jQuery's .html() function. But if you can you should surround your markup with some dummy div and avoid this workaround all together. This would be much faster since jQuery would not need to do all the DOM manipulations.