An approach to use jQuery Plugins with AngularJS


Lets face it, we can not completely get rid of jQuery and its plugins ecosystem, even though Angular has a built-in subset of jQuery under the name jQLite. At one point or another, we often need some sort of jQuery plugins in our application and we can/should not port entire plugin into Angular world in order to use it but we can avoid the plugin initialization code to be scattered across.

How?

Simply by writing a directive for it.

I would like to give you a small demo of Toolbar.js which is a jquery plugin I found recently on geekli.st. This is how we create a tooltip style toolbar in jQuery:

<!-- Click this to see a toolbar -->
<div id="format-toolbar" class="settings-button">
    <img src="http://paulkinzett.github.com/toolbar/img/icon-cog-small.png">
</div>

<!-- Our tooltip style toolbar -->
<div id="format-toolbar-options">
	<a href="#"><i class="icon-align-left"></i></a>
	<a href="#"><i class="icon-align-center"></i></a>
	<a href="#"><i class="icon-align-right"></i></a>
</div>
<!-- Typical jQuery plugin invocation -->
$('#format-toolbar').toolbar({
	content: '#format-toolbar-options', 
	position: 'left'
});

Enter the dragon a.k.a Angular

We’ll keep our markup intact by just adding a custom attribute named `toolbar-tip` – which will be an angular directive we’ll going to write soon. So our markup will change to:

<div id="format-toolbar1" class="settings-button" toolbar-tip="{content: '#format-toolbar-options', position: 'top'}">
	<img src="http://paulkinzett.github.com/toolbar/img/icon-cog-small.png">
</div>

One thing to notice here is that I’ve moved all the options of a toolbar into an HTML so that we can use the same directiv anywhere else with different options/settings.

Finally,

<script>
var App = angular.module('Toolbar', []);

App.directive('toolbarTip', function() {
	return {
		// Restrict it to be an attribute in this case
		restrict: 'A',
		// responsible for registering DOM listeners as well as updating the DOM
		link: function(scope, element, attrs) {
		    $(element).toolbar(scope.$eval(attrs.toolbarTip));
		}
	};
});
</script>

Woohoo! Is not that awesome?? Everything is simple, maintainable and testable!!!

Demo

http://jsfiddle.net/codef0rmer/TH87t/

About these ads

24 thoughts on “An approach to use jQuery Plugins with AngularJS

  1. This is exactly what I’m looking for! Coz I have a navbar that I want to initialize with Twitter Bootstrap’s jquery affix plugin and I have no idea where to enter the initialization code. Initially I thought I’d have to mess with angular config run function.

    This is great stuff.

  2. Pingback: Migration guide for jQuery Developers | codef0rmer

  3. I’ve been using an identical approach myself. I prefer to add the braces for the options in the directive though -> scope.$eval(“{” + attrs.toolbarTip + “}”). The HTML looks a bit tidier that way.

    Also, if you’re already referencing jQuery in your solution, make sure you’re loading it before AngularJS. This way Angular will pick up that jQuery is present. So now instead of “$(element).toolbar(scope.$eval(attrs.toolbarTip));” you can write “element.toolbar(scope.$eval(attrs.toolbarTip));” as element will already be a jQuery object.

    Also, your JSFiddle is currently broken. Here is a working one:

    http://jsfiddle.net/gavinfoley/TH87t/57/

  4. This is an interesting example. I did not previously realize that the camel case directive name (in this case toolbarTip, is mapped to the dashed attribute toolbar-tip in the HTML. Took me a while to figure out that was happening. Kind of makes sense but not very obvious.

  5. App.directive(‘toolbarTip’

    and

    <div toolbar-tip…

    Should not it be the exactly same string?

    I am a newbie on angular, i need to understand everything.

    Thanks

    • No because thats how angular works! As per HTML spec, the attribute should be hyphenated but javascript does not support hyphenated variable/function name and hence angular team has decided to use hyphens while declaring and camelcase while defining a directive.

  6. Pingback: Using a jQuery Plugin (flipclock) in an angular.js application | Technology & Programming

  7. Pingback: Correct way to integrate Jquery plugins in Angular.js | Technology & Programming

  8. Pingback: Création de la directive "scrollable" | Angular-js.fr

  9. Pingback: future of Jquery | DiscVentionsTech

  10. How would you handle the toolbar item´s click events? Seems that the plugin replace/move the html whenever its called so you cannot use ngcllicks on em.

    • @insane, It’s very rare that you need angular event handlers in jQuery plugins. In this particular example, the toolbar’s click event is handled by the jQuery plugin itself – angular directive just creating a wrapper around it to help us use it declaratively in angular.

  11. Hi,
    I have some problem with angularJs + Jquery Steps Plugin.
    The problem is after implementing Jquery steps as directive , ng-model seems to be not working. Can any one tell me what I am missing? Do I need to do some extra stuff to make data binding work again??

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s