22 3 / 2012

JavaScript Processors

Often times we use jQuery plugins and other scripts to enhance the user experience. These plugins are usually initialized when the page loads and they process html and add some fancy new behavior. But when we start adding content via ajax, things start to get messy.

Some of the plugins can be developed to use live event handlers and that they can handle the problem elegantly (with more or less performance impact), but most of them cannot.

General idea is to have these blocks of code declared once and re-applied whenever needed. To do so, we need all of them to share same interface. Lets call these blocks processors and created a module for each of them. Here are few written in CoffeeScript:

@TimeagoProcessor =
  process: ->
    $('time.ago').timeago()


@SimpleTooltipsProcessor =
  process: ->
    $('[data-tooltip]').qtip
      position:
        at: 'bottom center'
        my: 'top left'

Next, we need to store these in a collection, so that we can run them all once the page loads, and after every ajax call. For that purpose, lets create new module called App.

@App =
  processorData: []

  registerProcessor: (processor, options) ->
    @processorData.push { processor: processor, options: options }

  bindEventHandlers: ->
    $('body').ajaxComplete => @runProcessors(ajax: true)

  runProcessors: (options) ->
    for data in @processorData
      if !options || options.ajax && data.options.ajax
        data.processor.process()

  init: ->
    @runProcessors()
    @bindEventHandlers()

The App enables us to register new processors through registerProcessor method. We can also specify other custom options for each processor. Currently, only ajax option is implemented to denote whether processor should run after each ajax call, but other options can be added easily.

Finally, lets hook it up:

jQuery ($) ->
  App.registerProcessor TimeagoProcessor,        ajax: true
  App.registerProcessor SimpleTooltipsProcessor, ajax: false
  App.init()

That’s it! We no longer have to worry about initializing various plugins and other blocks of code after every ajax call.