Wednesday, October 5, 2011

Speed up jquery

1.Alway use :
  
$.parent.find('child').show();
    

Wednesday, September 21, 2011

Adding Syntax Highlighting to Blogger

(Note: This article is somewhat dated because SyntaxHighlighter 2.0 was released in February 2009.  However, this article is still valid for those who prefer the older 1.5.x version or who don't want to upgrade)

As we all know, any self-respecting blogger needs some kind of syntax-highlighting plug-in before posting source code on a blog. I've been amiss in this regard, but decided it was high time to correct this particular deficiency.

From doing a little web searching, it looks like the favorite choice is a Java script tool called syntaxhighlighter. As of this writing, syntaxhighlighter hasn't been updated since version 1.5.1 was release in August 2007. It's been surprisingly robust all this time, except that it appears to have some trouble with scrollbars in the more recent Firefox versions, and Safari can be pegged at 100% CPU utilization. Also, the documentation is a little sparse.

That said, here are the steps I followed to make syntax highlighting work with Blogger (the host for this blog) using the syntaxhighlighter suite of javascript and css code.

In the blogger back end (reachable by logging into your blog and clicking "New Post" or "Customize", or other methods), click the"Layout" tab, then the "Edit HTML" sub-tab. Within the textbox within the "Edit Template" section, do the following:

1. Go to http://syntaxhighlighter.googlecode.com/svn/trunk/Styles/SyntaxHighlighter.css, then perform a "select all" and "copy". The css information is now in the clipboard.

2. Paste the css information at the end of the css section of your blogger html template (i.e., after <b:skin><!--[CDATA[/* and before ]]--></b:skin>).

3. [Updated March 25, 2009 to include closing script tags] Before the </head> tag, paste the following:

  1. <!-- Add-in CSS for syntax highlighting -->  
  2. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js' type='text/javascript'></script>  
  3. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js' type='text/javascript'></script>  
  4. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCSharp.js' type='text/javascript'></script>  
  5. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCss.js' type='text/javascript'></script>  
  6. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushDelphi.js' type='text/javascript'></script>  
  7. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJava.js' type='text/javascript'></script>  
  8. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJScript.js' type='text/javascript'></script>  
  9. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPhp.js' type='text/javascript'></script>  
  10. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushPython.js' type='text/javascript'></script>  
  11. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushRuby.js' type='text/javascript'></script>  
  12. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushSql.js' type='text/javascript'></script>  
  13. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushVb.js' type='text/javascript'></script>  
  14. <script src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushXml.js' type='text/javascript'></script>  
Feel free to remove lines for languages you'll never use (for example, Delphi) -- it will save some loading time.

4. [Updated to add final /script] Before the </body> tag, insert the following:
  1. <!-- Add-in Script for syntax highlighting -->  
  2. <script language='javascript'>  
  3. dp.SyntaxHighlighter.BloggerMode();  
  4. dp.SyntaxHighlighter.HighlightAll('code');  
  5. </script>  

5. Use the "Preview" button to make sure your website is correct, then click "Save Template".

6. When composing a blog entry that contains source code, click the "Edit Html" tab and put your source code (with html-escaped characters) between these tags:
  1. <pre name="code" class="cpp">  
  2. ...Your html-escaped code goes here...  
  3. </pre>  

Substitute "cpp" with whatever language you're using (full list). (Choices: cpp, c, c++, c#, c-sharp, csharp, css, delphi, pascal, java, js, jscript, javascript, php, py, python, rb, ruby, rails, ror, sql, vb, vb.net, xml, html, xhtml, xslt)

For performing the HTML escaping, you can get a good list of tools by searching for 'html esaper' or a similar term. Here's the one I used while writing this post.

Let me know how it works!

Jquery plugin IBM

Introduction
In a previous article in this series, Working with jQuery, Part 2: Intermediate JQuery: The UI project, I discussed using plug-ins in your own jQuery code to increase the effectiveness of your Web applications. However, these plug-ins don't write themselves. They are written and tested by developers like you and me, donating their free time to the jQuery community to make it better. And we do this all for free, living only for the love of our own code. This article focuses on how you can give something back to this great community, by writing your own plug-in and checking it into the plug-in pages hosted by jQuery. This lets everyone use the plug-in you create, bettering the entire jQuery development community. Consider this my charity work for the year.
While writing the plug-in for this article, I found that the plug-in creation, and the framework for creating it, is extremely straightforward and easy. The hard work is actually thinking of something that hasn't already been done by someone else, and writing the "grunt work" JavaScript code that actually does things. Because of the straightforward plug-in structure, which is easy for beginners and flexible for advanced coders, the number of plug-ins has grown rapidly.
Of course, in doing the research for this article, I also found that every author has their own style for writing a plug-in and that jQuery allows several different styles for writing them. I will concentrate on the easiest one here, and the one recommended by jQuery itself, but will point out any differences or options as they pop up.
Describing your plug-in
Step 1 in creating a plug-in is, of course, thinking of a good idea. Chances are, like most good ideas, someone else has already beaten you to it. For the plug-in I'll be developing here, it's not a novel concept, but at the time of this article I couldn't find it anywhere in the jQuery plug-in community. I know I would personally get a lot of use out of it.
My plug-in is a NumberFormatter plug-in. Number formatting is likely familiar to anyone who's worked with server-side code like Java™ or PHP and internationalization. It's common knowledge that not everyone in the world formats their numbers in the same way. For example, not everyone uses miles for distance. A number that we would write in the U.S. as "1,250,500.75" (I just grabbed this number from my tax form), would be written differently in different countries: "1.250.500,75" in Germany, "1 250 500,75" in France, "1'250'500.75" in Switzerland, and "125,0500.75" in Japan. The number is exactly the same, but it's just written using a different format when presented to users of the Web application.
So, the question emerges, when you're writing an international application, how would you present these numbers to people in different countries? The solution, of course, is to use server-side formatting, which is pretty common. Java has a robust formatting library to make formatting numbers easy. When the page is set up on the server with numbers, the server can take care of formatting these numbers. However, many times you might not be on the server, so you need a way to format numbers on the client, without ever talking to the server.
Here's a typical use case for what I'm describing. You have an input field in your Web application that asks a person for their salary. In the U.S., the user can type in varied forms of input - "$65000", "65,000", "65000", "65,000.00". All these numbers are exactly the same, but you want to control how these numbers look on the screen, in order to create a better user experience. You could call the server after the number is entered, but this could get annoying if you have a lot of number fields with different formats. Plus, if you can take care of this problem on the client, and offer instantaneous feedback to the user, why wouldn't you do that?
So, I've established the gap in JavaScript/jQuery functionality I am trying to fill. My plug-in is going to offer number formatting on the client, giving others a way to offer internationalization for their Web applications without having to talk to the server. As an added bonus, my plug-in will also do the opposite function; the plug-in will allow developers to parse numbers, getting a number out of a formatted text string. This can be used for mathematical operations on the client. Additionally, I will mimic the functionality in the Java DecimalFormatter class, to maintain a commonality between the client code and the standard server-side method of doing number formatting.
Step 1 result: I've established a need for a plug-in, and have defined the specs that I will use in filling the need.
Plug-in rules
The jQuery team has established a number of general rules that they want plug-in authors to follow to create a common and expected environment for the plug-in users. Because I consider the jQuery team to be much smarter than me, who am I to disagree with any of the rules, right? For that reason, I'll outline the rules here, and will also strive to follow them in every step of my own plug-in.
  • Name your file "jquery.<your plug-in name>.js"
    Well, this makes sense, because you want someone to look at the file and know right away that it's a jQuery plug-in, and which plug-in it is. Check. I will call my plug-in "jquery.numberformatter.js."
  • All new methods are attached to the jQuery.fn object, all new functions to the jQuery object
    This may be confusing at this stage, and I will discuss this more in the next section because this is the most important rule for actual coding. Check. I will only attach methods/functions to those two objects.
  • "this" is a reference to the jQuery object
    This is to facilitate plug-in writing by letting all plug-in authors know what object they will receive from jQuery when they reference "this." Check. I will use "this" only as a reference to the jQuery object.
  • All methods/functions defined in the plug-in must have a ";" (semicolon) at the end or code minimizers will break.
    Because it is a best practice to minimize JavaScript files, breaking the minimizer would be bad, and chances are your plug-in would get dumped quickly Check. All of the methods/functions will have a ";" at the end.
  • All methods must return the jQuery object, unless otherwise noted
    The daisy-chaining of jQuery methods is quite popular, and if you write a plug-in that breaks this chain, it literally "breaks the chain" Check. My format() method will return the jQuery object, and even though the parse() method will not return the jQuery object, I have documented it in many places that this function breaks the chain. (After all, it would be difficult/impossible to return a Number object and not break the chain.)
  • You should always use this.each() to iterate over the matched elements, as this is a reliable and efficient way to loop through objects
    For performance and stability reasons, they recommend all methods use this means to loop through matched elements. Check. My methods will only loop through matched elements in this manner.
  • Always use "jQuery" instead of "$" in your plug-in code
    This is important because it allows users who have a conflict with "$" (those who may be using another JavaScript library) the ability to change their pseudonym for jQuery in one place using the "var JQ = jQuery.noConflict();" function. However, as I have looked through many plug-ins, I have found that this rule is broken quite often, which is unfortunate. If the developer ever needs to change the jQuery pseudonym, it likely means that the broken plug-ins will get dumped. Check. In my plug-in, I will only use the jQuery and not its "$" pseudonym.
So, those are the only rules/recommendations that are placed on your plug-in code. The truth of the matter is, they are de facto enforced, because if you start breaking the rules of the plug-ins, your plug-in won't get used very often, and it will get bad reviews from your peers. What will result is a plug-in that gets rarely used, and one you probably wasted your time on. Therefore, it's important to follow the rules. This not only helps your peers out, and makes their coding consistent, it also gives your plug-in a greater chance of success.
Step 2 result: I will follow all the rules of creating a jQuery plug-in
Writing the plug-in
Now it's time to start writing the code! The first step in starting your plug-in is to decide how you want to structure your plug-in. There are two choices to start off with: do you want it to be a method or a function? "What's the difference?" you might ask.
A method, as I said above, needs to be attached to the jQuery.fn object, and a function needs to be attached to the jQuery object. Oh, that clears everything up, right? Well, probably not if you're relatively new to jQuery. Instead, think of it this way. A method gives your code the ability to loop through all the selected elements that are passed into the plug-in. As a result, your plug-in can accept any type of HTML element, and it's up to your plug-in to define how to work with each element. Thus, your plug-in method can accept any jQuery selector, anything from "p" to "#mySpecificPageElement". This would be desirable if you want to have some flexibility in your plug-in, allowing users to pass in any type of page element. The burden is on you, the plug-in developer, to deal with everything properly. Contrast that with a function, which doesn't take any selected elements as arguments. It's simply a function that will be applied to the entire page. The burden shifts to the plug-in developer, who has to define which page elements they want the plug-in to interact with, and ignore the others. Let's take a look at the difference in some code.

Listing 1. jQuery plug-in method/function
		   
// This is a method because you can pass any type of selector to the method and it 
// will take some action on the results of the selector.  In this case, it will
// doSomething() on the page element with an ID of myExample
$("#myExample").doSomething();
   
// This is also a method, even though you are passing the entire page body to
// the method, because you are still passing a selector
$("body").doSomethingElse();

// This is a function, because you are NOT passing any selector to the function
// The plug-in developer must determine what page elements they want to take action on.
// This is usually accomplished by the plug-in developer requiring the page elements
// to contain a certain class name.

<div class="anotherThing">

// This hypothetical plug-in developer would document that his plug-in only works
// on elements with the class "anotherThing"
$.anotherThing();

So, judging from these descriptions, it looks like your plug-in should use a method, because you want to allow its users to tell you what page elements they want formatted. Listing 2 shows how your plug-in code looks now.

Listing 2. Your method definition
		   
jQuery.fn.format = function();

// You would call your plug-in like this (at this point)
$("#myText").format();

Of course, your function can't simply be a one-size-fits-all plug-in, because you're dealing with internationalization and you can't automatically figure out what country you want the text formatted for or the format you want. So, you must modify your plug-in slightly to accept some options. You will need two options in your formatting method: the format the number should use (for example, #,### vs. #,###.00) and the locale (the locale being a simple 2-letter country code to determine which international number formatting to use).
You also want to make your plug-in as easy to use as possible, because you want to increase your plug-in's chances of success. This means you should also go ahead and define some default options so the user doesn't have to pass in the options if they don't want to. Because I'm writing this from the U.S., and that also happens to be the most common number formatting in the world, I'll default to the "us" locale, and I'll default to the "#,###.00" format, for no other reason other that it can be used for currency with this default.

Listing 3. Allowing options in your plug-in
		   
jQuery.fn.format = function(options) {

    // the jQuery.extend function takes an unlimited number of arguments, and each
    // successive argument can overwrite the values of the previous ones.
    // This setup is beneficial for defining default values, because you define
    // them first, and then use the options passed into the method as the
    // second argument.  This allows the user to override any default values with their
    // own in an easy-to-use setup.
    var options = jQuery.extend( {

      format: "#,###.00",
      locale: "us"

}, options);

The final step to creating your plug-in framework is to work properly with the selected elements that were passed into the method. If you'll recall from the examples above, the selected elements could be 1 page element, or it could be many page elements. You have to deal with them all equally well. Also, recall from the jQuery plug-in commandments, the "this" object is a reference to the jQuery object. So, you have a reference to the jQuery-selected elements that were passed into the method, and now you just need to iterate through them. Also, looking back at the Commandments, each plug-in method should return the jQuery object. You know, of course, the jQuery object is "this", so you can simply return this in your method and be all good. Let's take a look at how you can accomplish both in a code snippet, iterating through each selected element and return the jQuery object.

Listing 4. Working with the jQuery object
		    
jQuery.fn.format = function(options) {

    var options = jQuery.extend( {

      format: "#,###.00",
      locale: "us"

    }, options);

// this code snippet will loop through the selected elements and return the jQuery object 
// when complete
return this.each(function(){
  // inside each iteration, you can reference the current element by using the standard
  // jQuery(this) notation
  // the rest of the plug-in code goes here
  });

Because the actual plug-in code itself isn't the point of this article, I won't spend any time on it, but you can see it all in the plug-in code attached to this article (see Download). I'd also like to show you an example of how you'd set up your plug-in architecture if you decided to write a function, as opposed to a method.

Listing 5. Example plug-in using a function
		   
jQuery.exampleFunction = function(options) {

   var options = jQuery.extend( {

     // your defaults

    }, options);
    
    jQuery(".exampleSelector").each(function(){
    
    });

});

Fine tuning the plug-in
Most beginner plug-in articles you find around the Web will stop there, letting you take the basic plug-in format and run with it. However, this basic framework is just that, basic. There are other important things that you must consider when writing your own plug-in, things that will give your plug-in the polish it needs to be more than a beginner plug-in. With these two added steps, you can turn your beginner plug-in into an intermediate-level plug-in.
Fine tune #1 - Make internal methods private
In any object-oriented programming language, you will find it handy to create external functions that can run repetitious code. In the NumberFormatter plug-in that I've created, there is an example of this code — the code that decides which locale got passed into the function and which characters to use as the decimal points and the group separator. This code is needed in the both the format() method and the parse() method, and any beginning programmer can tell you this belongs in its own method. However, one problem arises from this decision because you are working with a jQuery plug-in: if you simply make it its own function, defined in JavaScript, then the method can be called by anyone who uses the script, for any purpose. This isn't what the function is intended for, and I would like to prevent outsiders from calling it, because it is intended only for my internal work. So, let's see how you can make this function a private one.
The solution for this private method problem is something called a Closure, and it essentially closes the entire plug-in code from outside calls, except those you attach to the jQuery object (which is public). Using this design, you can put any code you want within your plug-in and not worry about it being called by outside scripts. By attaching your plug-in methods to the jQuery object, you are essentially making them public methods, with all the rest of the functions/classes becoming private. Listing 6 gives you a look at the code required to do this.

Listing 6. Make a function private
		   
// this code creates the Closure structure
(function(jQuery) {

   // this function is "private"
   function formatCodes(locale) {
      // plug-in specific code here
   };  // don't forget the semi-colon

   // this method is "public" because it's attached to the jQuery object
    jQuery.fn.format = function(options) {

     var options = jQuery.extend( {

          format: "#,###.00",
          locale: "us"

     },options);

     return this.each(function(){
         var text = new String(jQuery(this).text());
         if (jQuery(this).is(":input"))
             text = new String(jQuery(this).val());

         // you can call the private function like any other function
         var formatData = formatCodes(options.locale.toLowerCase());

         // plug-in-specific code  here
      });
     }; // don't forget the semi-colon to close the method

// this code ends the Closure structure
})(jQuery);

Fine tune #2 - Make your plug-in's defaults overridable
The last step to fine-tuning this plug-in is to give it the ability to have its defaults overridden. After all, if a developer in Germany downloaded this plug-in, and knew that all of his Web application's users would want to see the German locale, you should give him the ability to change the default locale in one line of code, rather than requiring him to write it in every method call. This is particularly handy in your plug-in because it is highly unlikely that a Web application will present numbers in different international formats to its users. Chances are, if you're on a Web page, all the numbers are going to be formatted using the same locale.
This step will require you to modify your code somewhat, so what you've seen so far has been updated to reflect this latest polishing step.

Listing 7. Overridable defaults
		   

jQuery.fn.format = function(options) {
// Change how you load your options in to take advantage of your overridable defaults
// You change how your extend() function works, because the defaults
// are globally defined, rather than within the method.  If you didn't use the
// {} as the first argument, you'd copy the options passed in over the defaults, which is
// undesirable.  This {} creates a new temporary object to store the options
// You can simply call the defaults as an object within your plug-in
var options = jQuery.extend({},jQuery.fn.format.defaults, options);

   return this.each(function(){
   
   // rest of the plug-in code here

// define the defaults here as an object in the plug-in
 jQuery.fn.format.defaults = {
      format: "#,###.00",
      locale: "us"
      }; // don't forget the semi-colon

That is the last step to creating your plug-in! What you should have now at this point is a polished plug-in that's ready for the final steps of testing. Listing 8 shows the completed plug-in that you've put together in this article so you can see how all the pieces fit together. Also, included is the parse() function, which I haven't talked about up until this point, but which is included in the plug-in. (I've excluded the grunt work of the plug-in, the parts that deal with formatting, because they are outside the scope of the article. They are included in the examples, and are of course in the plug-in itself).

Listing 8. The NumberFormatter plug-in
		   
(function(jQuery) {

    function FormatData(valid, dec, group, neg) {
       this.valid = valid;
       this.dec = dec;
       this.group = group;
       this.neg = neg;
    };

    function formatCodes(locale) {
      // format logic goes here
      return new FormatData(valid, dec, group, neg);
    };

 jQuery.fn.parse = function(options) {

    var options = jQuery.extend({},jQuery.fn.parse.defaults, options);

    var formatData = formatCodes(options.locale.toLowerCase());

    var valid = formatData.valid;
    var dec = formatData.dec;
    var group = formatData.group;
    var neg = formatData.neg;

    var array = [];
    this.each(function(){

       var text = new String(jQuery(this).text());
       if (jQuery(this).is(":input"))
           text = new String(jQuery(this).val());


       // now we need to convert it into a number
       var number = new Number(text.replace(group,'').replace(dec,".").replace(neg,"-"));
       array.push(number);
     });

     return array;
 };

 jQuery.fn.format = function(options) {

    var options = jQuery.extend({},jQuery.fn.format.defaults, options);  

    var formatData = formatCodes(options.locale.toLowerCase());

    var valid = formatData.valid;
    var dec = formatData.dec;
    var group = formatData.group;
    var neg = formatData.neg;

    return this.each(function(){
       var text = new String(jQuery(this).text());
       if (jQuery(this).is(":input"))
           text = new String(jQuery(this).val());

       // formatting logic goes here

       if (jQuery(this).is(":input"))
           jQuery(this).val(returnString);
       else
           jQuery(this).text(returnString);
    });
 };
 
 jQuery.fn.parse.defaults = {
    locale: "us"
 };

 jQuery.fn.format.defaults = {
    format: "#,###.00",
    locale: "us"
 };
 
 })(jQuery);

Testing the plug-in
The final step in creating my plug-in is to test it—thoroughly. Nothing angers a plug-in user more than seeing a bug in your plug-in. Rather than fix it, they will quickly dump your plug-in and move on. Getting a few of these types of users as well as some bad reviews can quickly sink your plug-in. Besides, it's a good reciprocal behavior—you want the plug-ins you use in your code to be well tested, so you should return the favor in your own plug-in code.
I created a quick test structure to test my plug-in (no need for a unit testing library), which creates dozens of spans with various numbers and the correct format right after the number. The JavaScript test calls format on the numbers and then compares the formatted number with the desired result, showing them as red if it fails. With this quick test, I can set up dozens of different test cases, testing every possible format, which I've done. I've attached my test page to the examples download so you can see one possible solution to testing your plug-in, utilizing jQuery to do the testing for you.
Looking at the finished plug-in
Let's take a look at the new NumberFormatter in action. I've created a simple Web application that you can look at to see how the NumberFormatter plug-in can fit in your applications.

Figure 1. NumberFormatter in action
A screen shot shows a series of labels with numeric fields, each displaying numbers correctly formatted in various styles.
The Web application is simple and straightforward enough. When the user leaves the textfield, after typing in their salary, house, and child information, the NumberFormatter plug-in will format their answers appropriately. The plug-in allows the Web app to consistently format numbers to the user. Also, note that this Web application is formatted for a user in Germany, as the decimal and group characters are different than it would be for a user in the U.S. (this lets me show how to change defaults).

Listing 9. NumberFormatter in action
		   
$(document).ready(function() {

   // use the AlphaNumeric plug-in to limit the input
   $(".decimal").decimal();
   $(".numeric").numeric();

   // you want to change the defaults to use the German locale
   // this will change the default for every method call on the
   // entire page, so you won't have to pass in the "locale"
   // argument to any function
   $.fn.format.defaults.locale = "de";
   $.fn.parse.defaults.locale = "de";

   // when the salary field loses focus, format it properly
   $("#salary").blur(function(){
      $(this).format({format:"#,###.00"});
   });

   // when the house field loses focus, format it properly
   $("#houseWorth").blur(function(){
      $(this).format({format:"#,###"});
   });
   
   // when the kids field loses focus, format it properly
   $("#kids").blur(function(){
      $(this).format({format:"#"});
   });
   
   // calculate the tax
   $("#calculate").click(function(){
      // parse all the numbers from the fields
      var salary = $("#salary").parse();
      var house = $("#houseWorth").parse();
      var kids = $("#kids").parse();
      // make some imaginary tax formula
      var tax = Math.max(0,(0.22*salary) + (0.03*house) - (4000*kids));
      // place the result in the tax field, and then format the resulting number
      // you need one intermediate step though, and that's the "formatNumber" function
      // because all numbers in JavaScript use a US locale when made into a String
      // you need to convert this Number into a German locale String before
      // calling format on it.
      // So, the steps are:
      //   1) the tax is a Number that looks like 9200.54 (US locale)
      //   2) formatNumber converts this to a String of 9200,54 (German locale)
      //   3) put this String in the #tax field
      //   4) Call format() on this field
      $("#tax").text($.formatNumber(tax)).format({format:"#,###"});
   });

});

Some remaining things to point out about the NumberFormatter plug-in before I close things up. First of all, this is the first 1.0.0 release of the plug-in, so I'm hoping to expand it in the future to include more formatting features that are included in the Java DecimalFormatter. This includes support for currency, scientific notation, and percentages. It will also include separate formatting rules for positive and negative numbers, beyond the simple "-" for a negative (for example, using (5,000) for negative numbers, which is done in accounting). Finally, a good formatter will allow any character in the format, it just ignores any that aren't part of the reserved characters. These are all features I hope to add in the near term to make this a robust plug-in.
Getting the locale of a user
One last question that's not specific to jQuery plug-ins, but one that might arise from using this plug-in—how do you get the user's locale? This is a good question, because there's currently no way to get this information using JavaScript. You'll need to create a JavaScript Bridge to do it. What's a JavaScript Bridge? I just mean you can set up a simple design pattern to get values into the JavaScript code from the server-side code. Listing 10 shows you could use Java; how you could do this on a JSP page.

Listing 10. Getting a user's locale
		   
<%

    // the request object is built into JSPs
    // unfortunately, it's not any easier
    // tested on FF, IE, Safari, Chrome
    String locale = "us"; // or your default locale
    String accLang = request.getHeader("Accept-Language");
    if (accLang.length() > 5)
    {
       accLang = accLang.substring(0,5);
       locale = accLang.substring(accLang.indexOf("-")+1);
    }

%>

$(document).ready(function() {

   // take advantage of the ability to override defaults by using the JavaScript
   // Bridge here.  Then your page can use the format() and parse() functions
   // elsewhere in the page without modifying them for a user's locale.
   $.fn.format.defaults.locale = "<%=locale%>";
   $.fn.parse.defaults.locale = "<%=locale%>";
   
   });

Wednesday, August 17, 2011

jQuery Plugin Design Patterns: Part I

jQuery plugins come in all shapes and sizes. They perform very simple or very complex tasks depending on their intended use. When it comes time for you to design your own plugin, its really important to understand what patterns other developers use and what will best suits your needs.
As a side note, I have built a number of plugins for my own projects and client work that will never be released. The jQuery community needs to stop thinking of plugins only as releasable, open-source projects, and start thinking of them instead as a reusable pieces of code that can help optimize and DRY up a complex website. Take this little plugin as an example:
$.fn.notice = function(){
    return this.slideDown(500).delay(4000).slideUp(500);
}
It simply abstracts the animation for displaying a notice (using jQuery 1.4). Would I ever release this on an open source site? Of course not! But it is still a fully functioning jQuery plugin that can be used over and over throughout a website.

Design Pattern Series Overview

  • Basics & Structure (this article)
  • Options & Updating
  • Callbacks & Custom Events
  • Misc. General Practices

Basics

Filename

Every jQuery plugin sits in its own JS file, and is normally named using the following pattern:
jquery.pluginname.js
jquery.pluginname.min.js
Released plugins often also have a version number:
jquery.pluginname-1.3.js
jquery.pluginname-1.3.min.js
If you end up building a lot of plugins for your website, consider also including a namespace to keep all your files together (And of course you would combine and minify them for production, right?):
jquery.mysite.pluginname.js
jquery.mysite.pluginname.js

Basic File Layout

After any comments you choose to put at the top of your file, the very next thing you should have is a self executing anonymous function that will actually wrap your entire plugin. Say what!? Don’t worry, you have seen it before, and it looks like this:
(function($){
 
   ... code here ...
 
})(jQuery);
This gives your plugin a private scope to work in, and also allows your plugin to be used with $.noConflict mode without creating a problem. By passing jQuery into the function, the $ will equal jQuery inside the function even if $ means something different outside your plugin.

Structure

There are three basic structures you will see when you look at released plugins:

Contained Function

In this structure, (almost) all the code to run your plugin is contained within the function used to call your plugin. This is the most common format:
(function($){
 
   $.fn.myPlugin = function(){
      return this.each(function(){
         // do something
      });
   }
 
})(jQuery);
You should use this this structure when you are writing a simple plugin that acts once upon the jQuery result set on each execution. For complex plugins that need to maintain an adjustable state, you should consider the “Class and Function” structure.

Class and Function

In this structure, a class is used and an instance is created for each DOM element in the result set. You may see these objects attached in some way to the DOM elements they modify:
(function($){
   var MyClass = function(el){
       var $el = $(el);
 
       // Attach the instance of this object
       // to the jQuery wrapped DOM node
       $el.data('MyClass', this);
   }
 
   $.fn.myPlugin = function(){
      return this.each(function(){
         (new MyClass(this));
      });
   }
 
})(jQuery);
You should use this structure if you need to be able to access the object later that is associated with a DOM element. It is far easier to attach a single object vs several key/value pairs using the data() method. In this approach, you can access the object by calling $('selector').data('MyClass'). This functions more like a widget and is a plugin that maintains state and can adjust its state on the fly (Learn how in the next article.).
Note: Widget Factory: The next release of jQuery UI is going to see the addition of a Widget Factory that will be designed to specially assist in developing widget-like plugins.

Extend

In my opinion, this is the least idiomatic way to create a jQuery plugin. It uses the jQuery.fn.extend method instead of jQuery.fn.pluginName:
(function($){
 
   $.fn.extend({
     myPlugin: function(){
      return this.each(function(){
         // do something
     },
     myOtherPlugin: function(){
      return this.each(function(){
         // do something
     }
   });
 
})(jQuery);
You will find this structure helpful if you need to add a large number of plugin methods to jQuery. I would contend, however, that if your plugin needs to add that many methods, there may be a better way to structure its implementation.
I feel the extend method is used more by programmers transitioning from other JS libraries. I personally find the simple $.fn.pluginName = structure to be easier to read, and more in line with what you will normally see in jQuery plugins.

Up Next

In the next part of this series, we will look at passing options and providing methods for updating settings and functionality after a plugin has been called.

Jquery Plugin

For some jQuery plugins it would be useful if we could expose one or more functions, so that we can interact with it from Javascript outside the plugin.  If we follow the standard mechanism of plugin authoring, we can only interact with the it at the moment of initialisation.  This post will look at two mechanisms that can be used to expose and access plugin functions.
This post will be based around the following mediaPlayer fictional plugin:
  1. (function($) {  
  2.   $.fn.mediaPlayer = function(options){  
  3.   .........  
  4.   }  
  5. })(jQuery);  
This mediaPlayer plugin would work by being attached to a selected DIV element in the DOM, like this:
  1. $('.myDiv').mediaPlayer(options);  
Now suppose we now want to interact with our mediaPlayer from outside. For example, we may want to trigger the media player to play a certain file. It would be useful if we could have a play() function on our plugin so we can trigger this action. So, how can we do this?

Class and Function Mechanism

With the standard mechanism of building a jQuery plugin we always ensure that the plugin function returns this (the current context of the plugin). The reason for returning the current context is that it allows the plugin call to be chained onto another plugin call. For example:
  1. $('.myDiv')  
  2.    .mediaPlayer(options)  
  3.    .otherPlugin();  
There is another approach to building jQuery plugins, called the class and function approach (see this excellent article of jQuery design patterns). Instead of returning the current context, the jQuery plugin creates and then returns a new instance of a JavaScript class. So, our mediaPlayer plugin could be created in the following way:
  1. (function($) {  
  2.   //the class  
  3.   var player = function(options){  
  4.     return createApi();      
  5.   
  6.     function createApi(){  
  7.       return {  
  8.         play : play  
  9.       }  
  10.     }  
  11.   
  12.     function play(url) {  
  13.       //our play code  
  14.     }  
  15.   }  
  16.   //the function  
  17.   $.fn.mediaPlayer = function(options){  
  18.     //create an instance of the class and return from the plugin  
  19.     return new player(options);  
  20.   }  
  21. })(jQuery);  
If the Javascript that creates the plugin stores a reference to returned instance it can continue accessing it’s public API. For example:
  1. var myMediaPlayer = $('.myDiv').mediaPlayer(options);  
  2. myMediaPlayer.play(url1);  
  3. myMediaPlayer.play(url2);  
However, there is a bit of a problem with this approach. Because it returns the instance of the class rather than the current context, it breaks the chaining of plugins in jQuery. We can no longer do this…
  1. $('.myDiv')  
  2.    .mediaPlayer(options)  
  3.    .otherPlugin();  
…we would have to do this instead:
  1. $('.myDiv')  
  2.    .mediaPlayer(options);  
  3. $('.myDiv')  
  4.    .otherPlugin();  

Execution Through apply() Mechanism

An alternative, and my preferred approach, is to execute the ‘public’ functions in the main plugin function by use of the apply() command. For this approach to work the plugin function has to be effectively overloaded, so that it can be used in two ways. It needs to retain it’s constructive form which in out case takes one argument of options, but it also needs to be able to accept an alternative call that takes a string argument (function name) and any additional arguments that this function requires.
The example below shows how we might use this mechanism to build our mediaPlayer plugin.
  1. (function($) {  
  2.     //define the commands that can be used  
  3.     var commands = {  
  4.         play: play,  
  5.         stop: stop  
  6.     };  
  7.   
  8.     $.fn.mediaPlayer = function() {  
  9.         if (typeof arguments[0] === 'string') {  
  10.             //execute string comand on mediaPlayer  
  11.             var property = arguments[1];  
  12.             //remove the command name from the arguments  
  13.             var args = Array.prototype.slice.call(arguments);  
  14.             args.splice(0, 1);  
  15.   
  16.             commands[arguments[0]].apply(this, args);  
  17.         }  
  18.         else {  
  19.             //create mediaPlayer  
  20.             createMediaPlayer.apply(this, arguments);  
  21.         }  
  22.         return this;  
  23.     };  
  24.   
  25.     function createMediaPlayer(options){  
  26.        //mediaPlayer initialisation code  
  27.     }  
  28.   
  29.     //Exposed functions  
  30.     function play(url) {  
  31.       //code to play media  
  32.     }  
  33.   
  34.     function stop() {  
  35.       //code to stop media  
  36.     }  
  37. })(jQuery);  
When the plugin function is called the first argument is examined to see what type it is. If this is NOT a string it is a call to initialise a mediaPlayer and so the createMediaPlayer() method is executed by using the apply() command. It uses apply as it 1) ensures that the context is correct (this is passed as the context); and 2) allows us to pass the argument(s) without caring about how many there are.
If the first argument is a string, then this must be the name of the function that is required to be executed. A new arguments array is prepared by stripping off the first argument (see this blog post about splice), as the called method won’t need this. Then the named function is executed by calling apply() and passing the current context and our new list of arguments. You might notice that when this named function is executed it has to retrieved from the commands object by using the bracket notation. This is required for the apply() function to be able to execute functions dynamically from string values.
This is how we would initialise this plugin and call the play() function:
  1. $('.myDiv')  
  2.    .mediaPlayer(options);  
  3.   
  4. $('.myDiv')  
  5.    .mediaPlayer('play', url1);  
As the context is always returned from the plugin function we can still chain calls to our selected DIV:
  1. $('.myDiv')  
  2.    .mediaPlayer(options)  
  3.    .otherPlugin();  
  4.   
  5. //chain calls to our play method...  
  6. $('.myDiv')  
  7.    .mediaPlayer('play', url1)  
  8.    .mediaPlayer('play', url2);  

Conclusion

In this post I’ve looked at two mechanisms that can be used to expose functions on jQuery plugins. The first of these is the Class and Function Mechanism that exposes ‘public’ functions by returning an instance of a class from the plugin initialisation function. Although this does allow functions to be exposed, it does break jQuery chaining and so is not ideal.
The Execution Through apply() Mechanism still allows jQuery chaining as the current context is still returned from the plugin initialisation function. This mechanism allows access to functions by effectively overloading the initialisation function to allow the name of the function that is to be executed to be passed in. This function can then be executed by using the JavaScript apply() command.

Tuesday, May 31, 2011

Jquery mistake you 're probaly making

  1. Selector Perfomance :
  2. Event binding :
  3. What is different between live method and delegate method?

    $('li',ul).live('click',function(){});

    $(ul).delegate('li','click',function(){});

    Initialization performance!

    .live() will execute the selector at init,.delegate() will not

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews