Creating jQuery Plugin: reuse your code, save your sanity

Spread the word
Tweet about this on TwitterShare on Google+Share on FacebookPin on PinterestShare on RedditShare on TumblrEmail this to someonePrint this page

jQuery has made all our lives easier, but if you’re not making your re-usable code into plugins then you’re not using it to its full potential. One reason so many new developers get spooked by JavaScript programming is that the treat it as a strictly procedural language. Yes, it was created that way, but a lot of very smart developers have worked long, tireless hours to make it more object-oriented (Backbone.js, Dojo, etc) and thus more maintainable. Most jQuery plugins are really just that, built to run specific commands, set attributes and create behaviors for selected objects in the DOM or user triggered events.

Though a late adopter of jQuery I was an early user. My first real job in web was refactoring and debugging WordPress sites that were built by not-so-web developers. Basically this meant they would install WordPress, install a theme and add 30 plugins to make it work. It was my job at the time to make those sites Seem less like the 100+ others using those same templates and/or plugins. I grew to despise WordPress and jQuery and I also found out that there were a mind blowing amount of shitty jQuery plugins out there. Especially for WordPress.

To create the simplest of plugins you really only need one two lines of code. $.fn.<plugin_name> = () -> and then your custom code that makes the next coolest JavaScript functionality to ever hit the world wide web.

Getting Started

Let’s have a quick gander at how we would do this:

See the Pen HpJqr by Keith Raymond (@Sparkmasterflex) on CodePen.

What’s going on here? Well let’s just focus on what’s in our <pre> tag. The real magic comes from the $.fn. This bit of code is actually extending your function to the jQuery functions object of the library. This will hopefully make things a bit clearer if you’re lost. I’m going to completely simplify the jQuery library to illustrate the point. First we have the jQuery object:

  jQuery = function() {
    // ...omitted code...
  }

Then later on the fn object is extended on the object:

  jQuery.fn = jQuery.protoype = {
    // methods on this 'fn' object
    // examples
    toArray: function() { ... }
    get: function(num) { ... }
  }

So what we’re doing with our change_text() is adding it to this fn object.

  jQuery.fn = jQuery.protoype = {
    // methods on this 'fn' object
    // examples
    toArray: function() { ... }
    get: function(num) { ... }
    
    // Essentially it's as if we were editing the jQuery code itself, but we don't actually have to...
    change_text: function(str) {
      // our code here
    }
  }

 

What’s the Point?

Valid question. One of the really nice things about doing this is that it compartmentalizes your code. From here on out this.text str can only ever effect changes on the selected DOM elements $('span.change') and any parameters that are passed to it; "Who". The only way that this can make a liar out of me is if you did something like this:

  $.fn.change_text = (str) ->
    $('.another-element').text str
    this.text str

  $ ->
    $('span.change').change_text "Who"

But I feel confident that you won’t do anything like that. It defeats the whole purpose of the plugin and it is most unwise. The theory of a plugin is that it can be extracted from Project A and dropped into Project B – Z. (but not Project F, you’ll want no part of that thing ;) ) Yet you cannot share this plugin everywhere if you have DOM specific code within your plugin. What we’ve done above requires that you now have an element in your HTML with the class of another-element and now there are a minimum of two files that the next person has to touch to get your plugin working.

Please note that there is no one way of doing anything, but there are best practices and this falls under that category. Another note: best practices are not in place so that you’ll never break them, just so that you have to backup your decision if you’re going against them.

A Worth While Plugin

Clearly what we’ve done so far is nothing exceptional and no one would ever really use it. What we need to do is play around with something that we’d actually want to use.

See the Pen AhreH by Keith Raymond (@Sparkmasterflex) on CodePen.

In the above CodePen we have 2 inputs, typing lowercase letters into the first one automatically changes them to uppercase. The second of the two does the opposite, typing in uppercase letters are automatically changed to lowercase. But wait, there’s something else with the second input isn’t there? When typing letters into the second input the input also changes color and then back to notify the user that this field has been updated by our script.

Switch over to the CoffeeScript tab and let’s look at our plugin code. First we declare our plugin as an extension of the jQuery library using $.fn.<name>, we set that equal to a function that we pass options to.

Using jQuery’s extend method we set some defaults that can be over-written by the options passed. We default our case (uppercase, lowercase or capitalize) to upper and highlight is null. Next we set this, the jQuery selected DOM element we are calling this plugin on, to listen for the keyup event or when the user has released a pressed key on their keyboard.

We use a switch statement to determine the value of new_val based on the case attribute in this.settings and what is typed into the input.

Next we test if the last typed character was a letter. If so set the value of our input to new_val and check for this.settings.highlight to not be null. If the highlight attribute has been set properly, we animate the input’s background color to our highlight and then back to the inherit color.

Once the document is ready ($ ->), our script runs the force_case() on both our inputs. For $('input.uppercase') we pass no arguments, so our plugin uses the default values. The $('input.lowercase') element on the other hand we pass case: 'lower' and highlight: 'rgb(255, 251, 204)'. (a pale yellow color) This sets our plugin to run toLowerCase() on @.val() rather than toUpperCase(). Also it gives the plugin a color in which to highlight our input field.

NOTE: the jQuery animate() method requires jquery-color to animate background-color. I have added this to the CodePen required libraries and you’ll need it as well if using this plugin

Conclusion

Now you can throw this plugin code into any web project you’d like and it will work seamlessly with one line of code:

  
  $('input.<class>').force_case()

This is a very simple plugin that will save you from writing 14 lines of CoffeeScript (or 34 lines of JavaScript) every time you want to use this functionality.

In my next post, I’ll create a more complex plugin that we’ll not only accept and use more configurations, but also utilize a JavaScript class object to further compartmentalizes our plugin from all other scripts that may be running in your project.

Spread the word
Tweet about this on TwitterShare on Google+Share on FacebookPin on PinterestShare on RedditShare on TumblrEmail this to someonePrint this page