Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RactiveJS and jQuery plugins

I have a form with multiple fields, some of them being for plain text and some of them require plugins for advanced select and upload capability.

There are 2 problems with this:

  • ractive needs to parse the template and render it before I can attach the plugins so there is some small delay
  • the second one is that such plugins change the markup around mentioned fields and that cannot work with ractive's generated DOM tree because that markup is out of sync.

What is the right approach to solving this problem? I would really like to use ractive for binding all form values and controlling behaviour of it all but at this point it seems nearly impossible.

like image 968
user2887067 Avatar asked Apr 15 '14 12:04

user2887067


1 Answers

A good way to integrate jQuery plugins with Ractive is to use decorators. A decorator is a function that gets called when an element enters the DOM; it returns an object with a teardown() method that is called when it's removed from the DOM.

So if you were using the jQuery File Upload plugin, your decorator might look like this:

var fileupload = function (node) {
  $(node).fileupload();

  return {
    teardown: function () {
      $(node).fileupload('destroy');
    }
  };
};

Once you've created the decorator, you need to register it. The easiest way is to make it globally available...

Ractive.decorators.fileupload = fileupload;

...but you can also pass in per-instance or per-component decorators:

// instance will have the fileupload decorator
ractive = new Ractive({
  // ...usual options...
  decorators: { fileupload: fileupload }
});

// all instances of Widget will have the decorator
Widget = Ractive.extend({
  decorators: { fileupload: fileupload }
});

Then, you can use it in your template like so:

<input decorator="fileupload" type="file" data-url="whatever">

It so happens that with this plugin you can specify options with data- attributes. But if you needed to specify options via the decorator itself, you could do so:

<input decorator="fileupload:{{url}},{multiple:true}" type="file">

In this example, the decorator function would receive two additional arguments - a URL, and an options object:

Ractive.decorators.fileupload = function (node, url, options) {
  // setup code...

  return {
    update: function (url, options) {
      // if the options change (i.e. `url` updates),
      // this function is called
    },
    teardown: function () {
      // teardown code...
    }
  };
};
like image 137
Rich Harris Avatar answered Oct 23 '22 01:10

Rich Harris