erichynds

Hi, I'm Eric Hynds, a front-end website developer living outside of Boston, Massachusetts. I'm passionate about developing functional, standard-compliant, and user-friendly websites.

Using $.widget.bridge Outside of the Widget Factory

Within jQuery UI’s widget factory exists a little method called $.widget.bridge, which acts as a middle man between the object created with $.widget and the jQuery API. Because bridge is a public function you do not need jQuery UI or any other part of the widget factory to use it. This is awesome and i’mma show you how.

What the widget factory calls "bridge" is an important pattern that affords us modularity and loose couping. Both Alex Sexton and Justin Meyer do an excellent job explaining it, and I highly recommend you become familiar with this design pattern if you’re not already.

$.widget.bridge does a few things:

  • Connects a regular JavaScript object to the jQuery API.
  • Automatically creates instances of said object and stores it within the element(s) $.data cache.
  • Allows option changes after initialization.
  • Allows calls to public methods.
  • Prevents calls to private methods.
  • Prevents method calls on uninitialized objects.
  • Protects against multiple initializations.

jQuery UI widgets are created using $.widget("foo.bar", {}); syntax to define an object from which instances will be created. Given a DOM structure with five .foo‘s, $('.foo').bar(); will create five instances of your "bar" object. $.widget.bridge works inside the factory by taking your base "foo" object and giving it a public API, so that you can create instances by writing $('.foo').bar(), and call methods by writing $('.foo').bar('baz').

However, the object passed into $.widget.bridge can be your own, not one that was created with $.widget(). But first, bridge has to make a few assumptions about your code for all this to work correctly:

  1. Your object must have both an option and an _init method. Initialiation logic goes in _init, and logic to change an option after initilization goes in option.
  2. Your option method returns the current instance. If you attempt to re-initialize an instance on an element, option is called first, and immediately chained to that is _init.
  3. Your constructor accepts two arguments: options, an object of configuration options, and element, the DOM element this instance was created on.

That said, let’s create an object:

Now hook it up to the bridge:

All this functionality and $.widget.bridge is less than 50 lines of code. Here’s a link to the source so you can study how it works.

Also, view source on this page by jQuery UI core member Scott Gonzales. His code on that page walks through the $.widget.bridge concept and illustrates how to use it.

Related posts:

  1. Tips for Developing jQuery UI 1.8 Widgets
  2. jQuery UI MultiSelect Widget
  3. A jQuery UI Growl/Ubuntu-like Notification Widget

Tags: , ,

  • http://profiles.google.com/rocketinbottle Rocket-in-Bottle Team

    Hi, it’s very helpful. I am developing a widget using the typical way described in jQuery UI API Developer Guide (http://jqueryui.com/docs/Developer_Guide), however, when I try to obfuscate the widget with Google Closure compiler using ADVANCED_OPTIMIZATIONS, I simply do not know how to expose those public function for the compiler to work. Do you think I should use the method described above, that is using a prototype(which can be exported easily) then use widget.bridge to turn it into a widget? Thanks!

  • http://www.surfulater.com/ nevf

    Hi Eric,
    Thanks for this great article on $.widget.bridge. I’ve been trying to find better ways of writing jQuery plugins that can support public & private methods and variables and this looks great.

    Having said that (there’s always a but isn’t there) I’d live to see the ability to call public methods in an OOP fashion. ex. $(“#elem”).foo.publicFn() or $(“#elem”).foo().publicFn() instead of passing method names as string parameters. Any idea if this is possible?

    Also in your example could you please change:
    publicFn: function(){
    return “public method”;
    },
    to:
    publicFn: function(){
    return this;
    },

    so the public methods are called for all elements in a collection. ex. $(“.aclass”).foo(‘publicFn’, params).

    I’d almost come to the conclusion that $.widget.bridge couldn’t be used for collections of elements, both from reading your article and others and nearly gave up on it because of this. It wasn’t until I dug around a bit and made the change above did I see the light.

    Thanks again,
    Neville http://www.surfulater .com

  • Serge Krul

    Hi, did you ever find a solution for your first request? I also don’t like the string names.. Thanks.

  • Eyal Peleg

    and what about cleenup? is there any destroy method that needs/can to be implemented ?

  • Eyal Peleg

    Please correct me If I am missing anything but in all the places where it says “instance” it is actually the jquery element that my object instance is bridged to. It looks like the actual object instance is the value returned from  what you refer to as instance.data(“foo”) (and this is why it has a .element attribute from the _init constructor…).