UNPKG

angular-gantt

Version:

Gantt chart component for AngularJS

249 lines (219 loc) 11.2 kB
// This file is adapted from Angular UI ngGrid project // MIT License // https://github.com/angular-ui/ng-grid/blob/v3.0.0-rc.20/src/js/core/factories/GridApi.js (function() { 'use strict'; angular.module('gantt') .factory('GanttApi', ['$q', '$rootScope', 'ganttUtils', function($q, $rootScope, utils) { /** * @ngdoc function * @name gantt.class:GanttApi * @description GanttApi provides the ability to register public methods events inside the gantt and allow * for other components to use the api via featureName.raise.methodName and featureName.on.eventName(function(args){}. * @param {object} gantt gantt that owns api */ var GanttApi = function GanttApi(gantt) { this.gantt = gantt; this.listeners = []; this.apiId = utils.newId(); }; /** * @ngdoc function * @name gantt.class:suppressEvents * @methodOf gantt.class:GanttApi * @description Used to execute a function while disabling the specified event listeners. * Disables the listenerFunctions, executes the callbackFn, and then enables * the listenerFunctions again * @param {object} listenerFuncs listenerFunc or array of listenerFuncs to suppress. These must be the same * functions that were used in the .on.eventName method * @param {object} callBackFn function to execute * @example * <pre> * var navigate = function (newRowCol, oldRowCol){ * //do something on navigate * } * * ganttApi.cellNav.on.navigate(scope,navigate); * * * //call the scrollTo event and suppress our navigate listener * //scrollTo will still raise the event for other listeners * ganttApi.suppressEvents(navigate, function(){ * ganttApi.cellNav.scrollTo(aRow, aCol); * }); * * </pre> */ GanttApi.prototype.suppressEvents = function(listenerFuncs, callBackFn) { var self = this; var listeners = angular.isArray(listenerFuncs) ? listenerFuncs : [listenerFuncs]; //find all registered listeners var foundListeners = []; listeners.forEach(function(l) { foundListeners = self.listeners.filter(function(lstnr) { return l === lstnr.handler; }); }); //deregister all the listeners foundListeners.forEach(function(l) { l.dereg(); }); callBackFn(); //reregister all the listeners foundListeners.forEach(function(l) { l.dereg = registerEventWithAngular(l.eventId, l.handler, self.gantt, l._this); }); }; /** * @ngdoc function * @name registerEvent * @methodOf gantt.class:GanttApi * @description Registers a new event for the given feature. The event will get a * .raise and .on prepended to it * <br> * .raise.eventName() - takes no arguments * <br/> * <br/> * .on.eventName(scope, callBackFn, _this) * <br/> * scope - a scope reference to add a deregister call to the scopes .$on('destroy') * <br/> * callBackFn - The function to call * <br/> * _this - optional this context variable for callbackFn. If omitted, gantt.api will be used for the context * <br/> * .on.eventName returns a dereg funtion that will remove the listener. It's not necessary to use it as the listener * will be removed when the scope is destroyed. * @param {string} featureName name of the feature that raises the event * @param {string} eventName name of the event */ GanttApi.prototype.registerEvent = function(featureName, eventName) { var self = this; if (!self[featureName]) { self[featureName] = {}; } var feature = self[featureName]; if (!feature.on) { feature.on = {}; feature.raise = {}; } var eventId = 'event:gantt:' + this.apiId + ':' + featureName + ':' + eventName; // Creating raise event method featureName.raise.eventName feature.raise[eventName] = function() { $rootScope.$emit.apply($rootScope, [eventId].concat(Array.prototype.slice.call(arguments))); }; // Creating on event method featureName.oneventName feature.on[eventName] = function(scope, handler, _this) { var deregAngularOn = registerEventWithAngular(eventId, handler, self.gantt, _this); //track our listener so we can turn off and on var listener = { handler: handler, dereg: deregAngularOn, eventId: eventId, scope: scope, _this: _this }; self.listeners.push(listener); var removeListener = function() { listener.dereg(); var index = self.listeners.indexOf(listener); self.listeners.splice(index, 1); }; //destroy tracking when scope is destroyed scope.$on('$destroy', function() { removeListener(); }); return removeListener; }; }; function registerEventWithAngular(eventId, handler, gantt, _this) { return $rootScope.$on(eventId, function() { var args = Array.prototype.slice.call(arguments); args.splice(0, 1); //remove evt argument handler.apply(_this ? _this : gantt.api, args); }); } /** * @ngdoc function * @name registerEventsFromObject * @methodOf gantt.class:GanttApi * @description Registers features and events from a simple objectMap. * eventObjectMap must be in this format (multiple features allowed) * <pre> * {featureName: * { * eventNameOne:function(args){}, * eventNameTwo:function(args){} * } * } * </pre> * @param {object} eventObjectMap map of feature/event names */ GanttApi.prototype.registerEventsFromObject = function(eventObjectMap) { var self = this; var features = []; angular.forEach(eventObjectMap, function(featProp, featPropName) { var feature = {name: featPropName, events: []}; angular.forEach(featProp, function(prop, propName) { feature.events.push(propName); }); features.push(feature); }); features.forEach(function(feature) { feature.events.forEach(function(event) { self.registerEvent(feature.name, event); }); }); }; /** * @ngdoc function * @name registerMethod * @methodOf gantt.class:GanttApi * @description Registers a new event for the given feature * @param {string} featureName name of the feature * @param {string} methodName name of the method * @param {object} callBackFn function to execute * @param {object} _this binds callBackFn 'this' to _this. Defaults to ganttApi.gantt */ GanttApi.prototype.registerMethod = function(featureName, methodName, callBackFn, _this) { if (!this[featureName]) { this[featureName] = {}; } var feature = this[featureName]; feature[methodName] = utils.createBoundedWrapper(_this || this.gantt, callBackFn); }; /** * @ngdoc function * @name registerMethodsFromObject * @methodOf gantt.class:GanttApi * @description Registers features and methods from a simple objectMap. * eventObjectMap must be in this format (multiple features allowed) * <br> * {featureName: * { * methodNameOne:function(args){}, * methodNameTwo:function(args){} * } * @param {object} eventObjectMap map of feature/event names * @param {object} _this binds this to _this for all functions. Defaults to ganttApi.gantt */ GanttApi.prototype.registerMethodsFromObject = function(methodMap, _this) { var self = this; var features = []; angular.forEach(methodMap, function(featProp, featPropName) { var feature = {name: featPropName, methods: []}; angular.forEach(featProp, function(prop, propName) { feature.methods.push({name: propName, fn: prop}); }); features.push(feature); }); features.forEach(function(feature) { feature.methods.forEach(function(method) { self.registerMethod(feature.name, method.name, method.fn, _this); }); }); }; return GanttApi; }]); })();