Unobtrusive JS


Unobtrusive car repair

One of the principles of Unobtrusive JS is the “separation of functionality (the “behavior layer”) from a Web page’s structure/content and presentation”.

A small example:

Wrong:
<a href="#" onclick="SomeObj.someAction(2)">Do some action on Obj 2</a>
better:
<a href="#" class="someaction" data-id="2">Do some action on Obj 2</a>

And in our JS file:

$(function(){
  $(document).on('click', '.someaction', function(){
    SomeObj.someAction($(this).data('id'))
  })
}(jQuery));

Notice that with this, you don’t even need to expose the someAction method from SomeObj, you can do these bindings in the object declaration.

An example with charts (and morris.js)

A pretty common mistake (I think) occurs while adding some charts to a page ( genarally a dashboard). I commited this mistake too.

A bad example with Rails, will be something like:

dashboard.html.erb

<script type="text/javascript">
Morris.Donut({
  element: "my-chart-placeholder",
  data: <%= raw ModelController.chart_data.to_json %>
})
</script>
<div id="my-chart-placeholder"></div>

As you can see, I’m doing the JS right into the page, so, I can concatenate it with a Ruby method call, and get the data without use a Restful call.

Pretty tricky, but, you can do it better.

The better way

Use data attributes!

dashboard.html.erb

<div id="my-chart-placeholder" data-chart="<%= ModelController.chart_data.to_json %>">
</div>

dashboard.js

$(function(){
  var id = "my-chart-placeholder"
  var chart = $("#"+id)
  // verify if the placeholder exists
  if(chart.lenght > 0) {
    Morris.Donut({
      element: id,
      data: chart.data('chart')
    })
  }
}(jQuery))

Much better, huh? We now have our presentation and behavior more separated.

Related Posts

Fast and easy Go binaries delivery

Watchub

Fixing alerts