AngularJS, jQuery Plugins and UI.Utils
In a previous post, I wrote about using a Bootstrap 3 Admin theme to update the "look and feel" of the client application produced by the AngularJS Full-Stack generator.
In this post, we'll do some more refactoring in order to get the themes jQuery plugins to play nicely with AngularJS.
JQuery plugins
After theming your AngularJS client you may have noticed that the jQuery plugins are not responding to events. We can address this issue by leveraging the UI.Utils AngularJS module.
The UI.Utils module
The UI.Uitls module (refered to by its developers as the "Swiss-Army-Knife of AngularJS tools") includes a JQuery Passthrough directive and an Event Binder directive.
Use Bower to install the UI.Utils module:
bower install --save angular-ui-utils
Bower will copy the modules files into your project's bower_components
folder, along with any dependencies.
Refactor index.html
Add the UI.Utils script to your project's index.html
:
Refactor app.js
Add the UI.Utils module to your dependencies:
angular.module(myApp', [
'ngRoute',
'ui.utils'
])
The jsTree jQuery plugin
The Admin theme I chose uses the jsTree jQuery plugin:
We can config jsTree in app.js
as follows:
angular.module(myApp', [
'ngRoute',
'ui.utils'
])
.value('uiJqConfig', {
jstree: {
types: {
default : {
icon : 'fa fa-folder icon-state-warning icon-lg'
},
file : {
icon : 'fa fa-file icon-state-warning icon-lg'
}
},
"plugins": ["types"]
}
})
Refactor main.html
We need to add the JQuery Passthrough directive: ui-jq
and the Event Binder directive: ui-event
to the jsTree container:
<div id="jstree-document-browser" ui-jq="jstree"
ui-event="{'select_node.jstree' : 'ctrl.selectNode($event)'}">
Refactor main.controller.js
Now, the select_node.jstree
event will be passed to the selectNode
function:
angular.module('webCaptureApp')
.controller('MainCtrl', ['$log', function($log) {
var self = this;
self.selectNode = function(event) {
var elementId = angular.element('#jstree-document-browser')
.jstree('get_selected')[0];
var elementText = angular.element('#' + elementId).text();
$log.info(JSON.stringify(elementText, null, 4));
}
}]);
We also need to update main.js
to use the controllerAs sytax:
angular.module('webCaptureApp')
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/main/main.html',
controller: 'MainCtrl as ctrl'
});
});