Last Updated: January 24, 2017
·
1.499K
· dangaytan

Simplest javascript widget

One of the things I really love of angularjs is their way of controllers. They seem to be like widgets with their own scope and their own behaviour.

Unfortunately, sometimes the project is so big that it's not really allowed to switch to a new framework like that, so I created this snippet in order to make it possible to load controllers in an already running gig.

function initializeControllers(){
  $('[js-controller]').each(function(index, el){
    var controllers = ($(el).attr('js-controller') || '')
                        .replace(/\s+/g, ' ')
                        .split(/\s/);
    if ($(el).data('jsControllersInitialized') === undefined){
      $(el).data('jsControllersInitialized', []);
    }
    for (i = 0; i < controllers.length; i++){
      if (controllers[i] === ''){ continue };
      if ($(el).data('jsControllersInitialized').indexOf(controllers[i]) >=0 ){ continue };
      eval("new " + controllers[i] + '(el)');
      $(el).data('jsControllersInitialized').push(controllers[i]);
    };
  });
};

Now, you can initialize the controllers every ajax request on elements that haven't already been initialised using $(document).on('ajax:complete', function(e){ initializeControllers() }); with jquery for example.

Here is an example of its usage:

html

<div js-controller='OneController SecondController'>
  <a js-one-trigger>First action</a>
  <a js-second-trigger>Second action</a>
</div>

coffeescript

class window.OneController
  constructor: (el)->
    @parent = $(el)
    @parent.on('click', '[js-one-trigger]', @doThis)
  doThis: =>
    console.log 'This'

class window.SecondController
  constructor: (el)->
    @parent = $(el)
    @parent.on('click', '[js-second-trigger]', @doThat)
  doThat: =>
    console.log 'That'

Cheers!