October 10, 2012
I have written a lot of JavaScript code like this
$(".product_pictures .actions .delete").on "click", ->
do_something_useful
The problem with above code is that class names in the html markup was meant for web design. By using css class for functional work, I have made both the design team and the front end development team perpetually terrified of making any change.
If designer wants to change markup from
<div class="first actions">
xxx
<div></div>
</div>
to
<div class="first actions-items">
xxx
<div></div>
</div>
they are not too sure what JavaScript code might break. So they work around it.
Same goes for JavaScript developers. They do not want to unintentionally remove a class element otherwise the web design might get messed up.
There has to be a better way which clearly separates the design elements from the functional elements.
Nick Quaranto of 37Signals presented Code spelunking in the All New Basecamp in video.
In his presentation he mentioned data-behavior
.
data-behavior
usage can be best understood by an example.
# no data-behavior
$(".product_pictures .actions .delete").on("click", function(){});
# code with data-behavior
$('[data-behavior~=delete-product-picture]').on('click', function(){});
# Another style with the same effect
$(document).on('click',"[data-behavior~=delete-product-picture]", function(){ });
The html markup will change from
<%= link_to '#', class: 'delete', "data-action-id" => picture.id do %>
to
<%= link_to '#', class: 'delete', "data-action-id" => picture.id, 'data-behavior' => 'delete-product-picture' do %>
Above code would produce html looking something like this
<a
class="delete"
data-action-id=""
data-behavior="delete-product-picture"
href="#"
>
<button>Delete</button>
</a>
Now in the above case the designer can change the css class as desired and it will have no impact on JavaScript functionality.
Based on this data-behavior approach I changed some part of a project I was working on to use data-behavior.
data-behavior
is a very simple and effective tool to combat the problem of
having clear separation between designer elements and JavaScription functional
work.
Over the period of time we have used this technique in many projects
successfully. However sometimes I need to spend a while to find the right way to
add data-behavior
. I'm adding some code snippet so that I can find them here
when I need them.
%div{ class: "", "data-behavior" => "search-container" }
.div{ data: { behavior: 'search-container' }, style: "" }
= button_tag '×', :class => "", "data-behavior" => "search-container"
= link_to 'Edit', "#",
data:{ behavior: 'display-in-modal', url: '' },
class: ""
= f.check_box :include_annual_workplan,
'data-behavior' => 'input-include-workplan'
= f.text_area :content, placeholder: "",
class: '',
data: { behavior: "comment-content" }
= f.text_field :name, class: '',
'data-behavior' => 'input-client-name'
= form_for '', data: { remote: true, behavior: 'add-comment-form' } do |f|
If this blog was helpful, check out our full blog archive.