jQuery UI Options via data- attributes

jQuery UI Options via data- attributes

Note, all code here is untested and for illustrative purposes.


Recently I stumbled upon a small problem. I spent some time and came up with a workaround, but I'm fairly certain that there must be a better way. Basically, I want to do this in my $(document).ready()

  1. $('.accordion').each(function() {
  2.     var settings={collapsible:true,active:false};
  3.     if($(this).data('settings')) {
  4.         $.extend(true, settings, $.parseJSON($(this).data('settings')));
  5.     }
  6.     $(this).accordion(settings);
  7. });


With this HTML


  1. <div class='accordion' data-settings='{"collapsible":false}'>....</div>


This works great, except when I want to pass through functions, like beforeActivate


  1. <div class='accordion' data-settings='{"collapsible":false,"beforeActivate":function() {}}'>....</div>


This doesn't work. So, to get around it, I do this...

  1. <div ...data-settings='{..."beforeActivate":"function beforeActivate() { console.log(self.attr(\"id\")); }"}'>....</div>

  2. if(settings.beforeActivate) {
  3.     var self=$(this);
  4.     eval(settings.beforeActivate);
  5.     settings.beforeActivate=function () { beforeActivate(); }
  6. }


I have a few issues with this though:


I don't want to use eval, even if it is eval'ing a string I've made.

All the function names are the same. They are probably all local scope, and I haven't had issues yet, but it also means naming them the same every time rather than just using a closure.

It isn't easily maintainable. Every different thing (.draggable, .accordion, .button, .dialog, etc...) will need several different functions pre-made like this. That's not nice, and not fun.

Escaping quickly gets out of control.

I'm sure I read somewhere that there is a way to get jQuery to automatically parse data-... attributes and use them as options, but I don't know where I read it, if I dreamt it, or if it was an April fool's.


Has anyone else had this issue, and if so how did you get around it? If you haven't had this issue, how would you get around it? I really don't want to use the above method, and I also don't want to have to manually initialise each one -- that would suck even more.


Thanks in advance.