angular.module("ui.bootstrap", ["ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.datepicker","ui.bootstrap.dialog","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.position","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
angular.module('ui.bootstrap.transition', [])
/**
* $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
* @param {DOMElement} element The DOMElement that will be animated.
* @param {string|object|function} trigger The thing that will cause the transition to start:
* - As a string, it represents the css class to be added to the element.
* - As an object, it represents a hash of style attributes to be applied to the element.
* - As a function, it represents a function to be called that will cause the transition to occur.
* @return {Promise} A promise that is resolved when the transition finishes.
*/
.factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
var $transition = function(element, trigger, options) {
options = options || {};
var deferred = $q.defer();
var endEventName = $transition[options.animation ? "animationEndEventName" : "transitionEndEventName"];
var transitionEndHandler = function(event) {
$rootScope.$apply(function() {
element.unbind(endEventName, transitionEndHandler);
deferred.resolve(element);
});
};
if (endEventName) {
element.bind(endEventName, transitionEndHandler);
}
// Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
$timeout(function() {
if ( angular.isString(trigger) ) {
element.addClass(trigger);
} else if ( angular.isFunction(trigger) ) {
trigger(element);
} else if ( angular.isObject(trigger) ) {
element.css(trigger);
}
//If browser does not support transitions, instantly resolve
if ( !endEventName ) {
deferred.resolve(element);
}
});
// Add our custom cancel function to the promise that is returned
// We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
// i.e. it will therefore never raise a transitionEnd event for that transition
deferred.promise.cancel = function() {
if ( endEventName ) {
element.unbind(endEventName, transitionEndHandler);
}
deferred.reject('Transition cancelled');
};
return deferred.promise;
};
// Work out the name of the transitionEnd event
var transElement = document.createElement('trans');
var transitionEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition': 'transitionend',
'OTransition': 'oTransitionEnd',
'transition': 'transitionend'
};
var animationEndEventNames = {
'WebkitTransition': 'webkitAnimationEnd',
'MozTransition': 'animationend',
'OTransition': 'oAnimationEnd',
'transition': 'animationend'
};
function findEndEventName(endEventNames) {
for (var name in endEventNames){
if (transElement.style[name] !== undefined) {
return endEventNames[name];
}
}
}
$transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
$transition.animationEndEventName = findEndEventName(animationEndEventNames);
return $transition;
}]);
angular.module('ui.bootstrap.collapse',['ui.bootstrap.transition'])
// The collapsible directive indicates a block of html that will expand and collapse
.directive('collapse', ['$transition', function($transition) {
// CSS transitions don't work with height: auto, so we have to manually change the height to a
// specific value and then once the animation completes, we can reset the height to auto.
// Unfortunately if you do this while the CSS transitions are specified (i.e. in the CSS class
// "collapse") then you trigger a change to height 0 in between.
// The fix is to remove the "collapse" CSS class while changing the height back to auto - phew!
var fixUpHeight = function(scope, element, height) {
// We remove the collapse CSS class to prevent a transition when we change to height: auto
element.removeClass('collapse');
element.css({ height: height });
// It appears that reading offsetWidth makes the browser realise that we have changed the
// height already :-/
var x = element[0].offsetWidth;
element.addClass('collapse');
};
return {
link: function(scope, element, attrs) {
var isCollapsed;
var initialAnimSkip = true;
scope.$watch(function (){ return element[0].scrollHeight; }, function (value) {
//The listener is called when scollHeight changes
//It actually does on 2 scenarios:
// 1. Parent is set to display none
// 2. angular bindings inside are resolved
//When we have a change of scrollHeight we are setting again the correct height if the group is opened
if (element[0].scrollHeight !== 0) {
if (!isCollapsed) {
if (initialAnimSkip) {
fixUpHeight(scope, element, element[0].scrollHeight + 'px');
} else {
fixUpHeight(scope, element, 'auto');
}
}
}
});
scope.$watch(attrs.collapse, function(value) {
if (value) {
collapse();
} else {
expand();
}
});
var currentTransition;
var doTransition = function(change) {
if ( currentTransition ) {
currentTransition.cancel();
}
currentTransition = $transition(element,change);
currentTransition.then(
function() { currentTransition = undefined; },
function() { currentTransition = undefined; }
);
return currentTransition;
};
var expand = function() {
if (initialAnimSkip) {
initialAnimSkip = false;
if ( !isCollapsed ) {
fixUpHeight(scope, element, 'auto');
}
} else {
doTransition({ height : element[0].scrollHeight + 'px' })
.then(function() {
// This check ensures that we don't accidentally update the height if the user has closed
// the group while the animation was still running
if ( !isCollapsed ) {
fixUpHeight(scope, element, 'auto');
}
});
}
isCollapsed = false;
};
var collapse = function() {
isCollapsed = true;
if (initialAnimSkip) {
initialAnimSkip = false;
fixUpHeight(scope, element, 0);
} else {
fixUpHeight(scope, element, element[0].scrollHeight + 'px');
doTransition({'height':'0'});
}
};
}
};
}]);
angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
.constant('accordionConfig', {
closeOthers: true
})
.controller('AccordionController', ['$scope', '$attrs', 'accordionConfig', function ($scope, $attrs, accordionConfig) {
// This array keeps track of the accordion groups
this.groups = [];
// Ensure that all the groups in this accordion are closed, unless close-others explicitly says not to
this.closeOthers = function(openGroup) {
var closeOthers = angular.isDefined($attrs.closeOthers) ? $scope.$eval($attrs.closeOthers) : accordionConfig.closeOthers;
if ( closeOthers ) {
angular.forEach(this.groups, function (group) {
if ( group !== openGroup ) {
group.isOpen = false;
}
});
}
};
// This is called from the accordion-group directive to add itself to the accordion
this.addGroup = function(groupScope) {
var that = this;
this.groups.push(groupScope);
groupScope.$on('$destroy', function (event) {
that.removeGroup(groupScope);
});
};
// This is called from the accordion-group directive when to remove itself
this.removeGroup = function(group) {
var index = this.groups.indexOf(group);
if ( index !== -1 ) {
this.groups.splice(this.groups.indexOf(group), 1);
}
};
}])
// The accordion directive simply sets up the directive controller
// and adds an accordion CSS class to itself element.
.directive('accordion', function () {
return {
restrict:'EA',
controller:'AccordionController',
transclude: true,
replace: false,
templateUrl: 'template/accordion/accordion.html'
};
})
// The accordion-group directive indicates a block of html that will expand and collapse in an accordion
.directive('accordionGroup', ['$parse', '$transition', '$timeout', function($parse, $transition, $timeout) {
return {
require:'^accordion', // We need this directive to be inside an accordion
restrict:'EA',
transclude:true, // It transcludes the contents of the directive into the template
replace: true, // The element containing the directive will be replaced with the template
templateUrl:'template/accordion/accordion-group.html',
scope:{ heading:'@' }, // Create an isolated scope and interpolate the heading attribute onto this scope
controller: ['$scope', function($scope) {
this.setHeading = function(element) {
this.heading = element;
};
}],
link: function(scope, element, attrs, accordionCtrl) {
var getIsOpen, setIsOpen;
accordionCtrl.addGroup(scope);
scope.isOpen = false;
if ( attrs.isOpen ) {
getIsOpen = $parse(attrs.isOpen);
setIsOpen = getIsOpen.assign;
scope.$watch(
function watchIsOpen() { return getIsOpen(scope.$parent); },
function updateOpen(value) { scope.isOpen = value; }
);
scope.isOpen = getIsOpen ? getIsOpen(scope.$parent) : false;
}
scope.$watch('isOpen', function(value) {
if ( value ) {
accordionCtrl.closeOthers(scope);
}
if ( setIsOpen ) {
setIsOpen(scope.$parent, value);
}
});
}
};
}])
// Use accordion-heading below an accordion-group to provide a heading containing HTML
//
// Heading containing HTML -
//
.directive('accordionHeading', function() {
return {
restrict: 'EA',
transclude: true, // Grab the contents to be used as the heading
template: '', // In effect remove this element!
replace: true,
require: '^accordionGroup',
compile: function(element, attr, transclude) {
return function link(scope, element, attr, accordionGroupCtrl) {
// Pass the heading to the accordion-group controller
// so that it can be transcluded into the right place in the template
// [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
accordionGroupCtrl.setHeading(transclude(scope, function() {}));
};
}
};
})
// Use in the accordion-group template to indicate where you want the heading to be transcluded
// You must provide the property on the accordion-group controller that will hold the transcluded element
//
Interval, in milliseconds:
Enter a negative number to stop the interval.
function CarouselDemoCtrl($scope) {
$scope.myInterval = 5000;
var slides = $scope.slides = [];
$scope.addSlide = function() {
var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150);
slides.push({
image: 'http://placekitten.com/' + newWidth + '/200',
text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' '
['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4]
});
};
for (var i=0; i<4; i++) $scope.addSlide();
}
.carousel-indicators {
top: auto;
bottom: 15px;
}
*/
.directive('slide', ['$parse', function($parse) {
return {
require: '^carousel',
restrict: 'EA',
transclude: true,
replace: true,
templateUrl: 'template/carousel/slide.html',
scope: {
},
link: function (scope, element, attrs, carouselCtrl) {
//Set up optional 'active' = binding
if (attrs.active) {
var getActive = $parse(attrs.active);
var setActive = getActive.assign;
var lastValue = scope.active = getActive(scope.$parent);
scope.$watch(function parentActiveWatch() {
var parentActive = getActive(scope.$parent);
if (parentActive !== scope.active) {
// we are out of sync and need to copy
if (parentActive !== lastValue) {
// parent changed and it has precedence
lastValue = scope.active = parentActive;
} else {
// if the parent can be assigned then do so
setActive(scope.$parent, parentActive = lastValue = scope.active);
}
}
return parentActive;
});
}
carouselCtrl.addSlide(scope, element);
//when the scope is destroyed then remove the slide from the current slides array
scope.$on('$destroy', function() {
carouselCtrl.removeSlide(scope);
});
scope.$watch('active', function(active) {
if (active) {
carouselCtrl.select(scope);
}
});
}
};
}]);
angular.module('ui.bootstrap.datepicker', [])
.constant('datepickerConfig', {
dayFormat: 'dd',
monthFormat: 'MMMM',
yearFormat: 'yyyy',
dayHeaderFormat: 'EEE',
dayTitleFormat: 'MMMM yyyy',
monthTitleFormat: 'yyyy',
showWeeks: true,
startingDay: 0,
yearRange: 20
})
.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', function (dateFilter, $parse, datepickerConfig) {
return {
restrict: 'EA',
replace: true,
scope: {
model: '=ngModel',
dateDisabled: '&'
},
templateUrl: 'template/datepicker/datepicker.html',
link: function(scope, element, attrs) {
scope.mode = 'day'; // Initial mode
// Configuration parameters
var selected = new Date(), showWeeks, minDate, maxDate, format = {};
format.day = angular.isDefined(attrs.dayFormat) ? scope.$eval(attrs.dayFormat) : datepickerConfig.dayFormat;
format.month = angular.isDefined(attrs.monthFormat) ? scope.$eval(attrs.monthFormat) : datepickerConfig.monthFormat;
format.year = angular.isDefined(attrs.yearFormat) ? scope.$eval(attrs.yearFormat) : datepickerConfig.yearFormat;
format.dayHeader = angular.isDefined(attrs.dayHeaderFormat) ? scope.$eval(attrs.dayHeaderFormat) : datepickerConfig.dayHeaderFormat;
format.dayTitle = angular.isDefined(attrs.dayTitleFormat) ? scope.$eval(attrs.dayTitleFormat) : datepickerConfig.dayTitleFormat;
format.monthTitle = angular.isDefined(attrs.monthTitleFormat) ? scope.$eval(attrs.monthTitleFormat) : datepickerConfig.monthTitleFormat;
var startingDay = angular.isDefined(attrs.startingDay) ? scope.$eval(attrs.startingDay) : datepickerConfig.startingDay;
var yearRange = angular.isDefined(attrs.yearRange) ? scope.$eval(attrs.yearRange) : datepickerConfig.yearRange;
if (attrs.showWeeks) {
scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
showWeeks = !! value;
updateShowWeekNumbers();
});
} else {
showWeeks = datepickerConfig.showWeeks;
updateShowWeekNumbers();
}
if (attrs.min) {
scope.$parent.$watch($parse(attrs.min), function(value) {
minDate = new Date(value);
refill();
});
}
if (attrs.max) {
scope.$parent.$watch($parse(attrs.max), function(value) {
maxDate = new Date(value);
refill();
});
}
function updateCalendar (rows, labels, title) {
scope.rows = rows;
scope.labels = labels;
scope.title = title;
}
// Define whether the week number are visible
function updateShowWeekNumbers() {
scope.showWeekNumbers = ( scope.mode === 'day' && showWeeks );
}
function compare( date1, date2 ) {
if ( scope.mode === 'year') {
return date2.getFullYear() - date1.getFullYear();
} else if ( scope.mode === 'month' ) {
return new Date( date2.getFullYear(), date2.getMonth() ) - new Date( date1.getFullYear(), date1.getMonth() );
} else if ( scope.mode === 'day' ) {
return (new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) - new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) );
}
}
function isDisabled(date) {
return ((minDate && compare(date, minDate) > 0) || (maxDate && compare(date, maxDate) < 0) || (scope.dateDisabled && scope.dateDisabled({ date: date, mode: scope.mode })));
}
// Split array into smaller arrays
var split = function(a, size) {
var arrays = [];
while (a.length > 0) {
arrays.push(a.splice(0, size));
}
return arrays;
};
var getDaysInMonth = function( year, month ) {
return new Date(year, month + 1, 0).getDate();
};
var fill = {
day: function() {
var days = [], labels = [], lastDate = null;
function addDays( dt, n, isCurrentMonth ) {
for (var i =0; i < n; i ++) {
days.push( {date: new Date(dt), isCurrent: isCurrentMonth, isSelected: isSelected(dt), label: dateFilter(dt, format.day), disabled: isDisabled(dt) } );
dt.setDate( dt.getDate() + 1 );
}
lastDate = dt;
}
var d = new Date(selected);
d.setDate(1);
var difference = startingDay - d.getDay();
var numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference;
if ( numDisplayedFromPreviousMonth > 0 ) {
d.setDate( - numDisplayedFromPreviousMonth + 1 );
addDays(d, numDisplayedFromPreviousMonth, false);
}
addDays(lastDate || d, getDaysInMonth(selected.getFullYear(), selected.getMonth()), true);
addDays(lastDate, (7 - days.length % 7) % 7, false);
// Day labels
for (i = 0; i < 7; i++) {
labels.push( dateFilter(days[i].date, format.dayHeader) );
}
updateCalendar( split( days, 7 ), labels, dateFilter(selected, format.dayTitle) );
},
month: function() {
var months = [], i = 0, year = selected.getFullYear();
while ( i < 12 ) {
var dt = new Date(year, i++, 1);
months.push( {date: dt, isCurrent: true, isSelected: isSelected(dt), label: dateFilter(dt, format.month), disabled: isDisabled(dt)} );
}
updateCalendar( split( months, 3 ), [], dateFilter(selected, format.monthTitle) );
},
year: function() {
var years = [], year = parseInt((selected.getFullYear() - 1) / yearRange, 10) * yearRange + 1;
for ( var i = 0; i < yearRange; i++ ) {
var dt = new Date(year + i, 0, 1);
years.push( {date: dt, isCurrent: true, isSelected: isSelected(dt), label: dateFilter(dt, format.year), disabled: isDisabled(dt)} );
}
var title = years[0].label + ' - ' + years[years.length - 1].label;
updateCalendar( split( years, 5 ), [], title );
}
};
var refill = function() {
fill[scope.mode]();
};
var isSelected = function( dt ) {
if ( scope.model && scope.model.getFullYear() === dt.getFullYear() ) {
if ( scope.mode === 'year' ) {
return true;
}
if ( scope.model.getMonth() === dt.getMonth() ) {
return ( scope.mode === 'month' || (scope.mode === 'day' && scope.model.getDate() === dt.getDate()) );
}
}
return false;
};
scope.$watch('model', function ( dt, olddt ) {
if ( angular.isDate(dt) ) {
selected = angular.copy(dt);
}
if ( ! angular.equals(dt, olddt) ) {
refill();
}
});
scope.$watch('mode', function() {
updateShowWeekNumbers();
refill();
});
scope.select = function( dt ) {
selected = new Date(dt);
if ( scope.mode === 'year' ) {
scope.mode = 'month';
selected.setFullYear( dt.getFullYear() );
} else if ( scope.mode === 'month' ) {
scope.mode = 'day';
selected.setMonth( dt.getMonth() );
} else if ( scope.mode === 'day' ) {
scope.model = new Date(selected);
}
};
scope.move = function(step) {
if (scope.mode === 'day') {
selected.setMonth( selected.getMonth() + step );
} else if (scope.mode === 'month') {
selected.setFullYear( selected.getFullYear() + step );
} else if (scope.mode === 'year') {
selected.setFullYear( selected.getFullYear() + step * yearRange );
}
refill();
};
scope.toggleMode = function() {
scope.mode = ( scope.mode === 'day' ) ? 'month' : ( scope.mode === 'month' ) ? 'year' : 'day';
};
scope.getWeekNumber = function(row) {
if ( scope.mode !== 'day' || ! scope.showWeekNumbers || row.length !== 7 ) {
return;
}
var index = ( startingDay > 4 ) ? 11 - startingDay : 4 - startingDay; // Thursday
var d = new Date( row[ index ].date );
d.setHours(0, 0, 0);
return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 86400000) + 1) / 7); // 86400000 = 1000*60*60*24;
};
}
};
}]);
// The `$dialogProvider` can be used to configure global defaults for your
// `$dialog` service.
var dialogModule = angular.module('ui.bootstrap.dialog', ['ui.bootstrap.transition']);
dialogModule.controller('MessageBoxController', ['$scope', 'dialog', 'model', function($scope, dialog, model){
$scope.title = model.title;
$scope.message = model.message;
$scope.buttons = model.buttons;
$scope.close = function(res){
dialog.close(res);
};
}]);
dialogModule.provider("$dialog", function(){
// The default options for all dialogs.
var defaults = {
backdrop: true,
dialogClass: 'modal',
backdropClass: 'modal-backdrop',
transitionClass: 'fade',
triggerClass: 'in',
resolve:{},
backdropFade: false,
dialogFade:false,
keyboard: true, // close with esc key
backdropClick: true // only in conjunction with backdrop=true
/* other options: template, templateUrl, controller */
};
var globalOptions = {};
var activeBackdrops = {value : 0};
// The `options({})` allows global configuration of all dialogs in the application.
//
// var app = angular.module('App', ['ui.bootstrap.dialog'], function($dialogProvider){
// // don't close dialog when backdrop is clicked by default
// $dialogProvider.options({backdropClick: false});
// });
this.options = function(value){
globalOptions = value;
};
// Returns the actual `$dialog` service that is injected in controllers
this.$get = ["$http", "$document", "$compile", "$rootScope", "$controller", "$templateCache", "$q", "$transition", "$injector",
function ($http, $document, $compile, $rootScope, $controller, $templateCache, $q, $transition, $injector) {
var body = $document.find('body');
function createElement(clazz) {
var el = angular.element("
");
el.addClass(clazz);
return el;
}
// The `Dialog` class represents a modal dialog. The dialog class can be invoked by providing an options object
// containing at lest template or templateUrl and controller:
//
// var d = new Dialog({templateUrl: 'foo.html', controller: 'BarController'});
//
// Dialogs can also be created using templateUrl and controller as distinct arguments:
//
// var d = new Dialog('path/to/dialog.html', MyDialogController);
function Dialog(opts) {
var self = this, options = this.options = angular.extend({}, defaults, globalOptions, opts);
this._open = false;
this.backdropEl = createElement(options.backdropClass);
if(options.backdropFade){
this.backdropEl.addClass(options.transitionClass);
this.backdropEl.removeClass(options.triggerClass);
}
this.modalEl = createElement(options.dialogClass);
if(options.dialogFade){
this.modalEl.addClass(options.transitionClass);
this.modalEl.removeClass(options.triggerClass);
}
this.handledEscapeKey = function(e) {
if (e.which === 27) {
self.close();
e.preventDefault();
self.$scope.$apply();
}
};
this.handleBackDropClick = function(e) {
self.close();
e.preventDefault();
self.$scope.$apply();
};
this.handleLocationChange = function() {
self.close();
};
}
// The `isOpen()` method returns wether the dialog is currently visible.
Dialog.prototype.isOpen = function(){
return this._open;
};
// The `open(templateUrl, controller)` method opens the dialog.
// Use the `templateUrl` and `controller` arguments if specifying them at dialog creation time is not desired.
Dialog.prototype.open = function(templateUrl, controller){
var self = this, options = this.options;
if(templateUrl){
options.templateUrl = templateUrl;
}
if(controller){
options.controller = controller;
}
if(!(options.template || options.templateUrl)) {
throw new Error('Dialog.open expected template or templateUrl, neither found. Use options or open method to specify them.');
}
this._loadResolves().then(function(locals) {
var $scope = locals.$scope = self.$scope = locals.$scope ? locals.$scope : $rootScope.$new();
self.modalEl.html(locals.$template);
if (self.options.controller) {
var ctrl = $controller(self.options.controller, locals);
self.modalEl.children().data('ngControllerController', ctrl);
}
$compile(self.modalEl)($scope);
self._addElementsToDom();
// trigger tranisitions
setTimeout(function(){
if(self.options.dialogFade){ self.modalEl.addClass(self.options.triggerClass); }
if(self.options.backdropFade){ self.backdropEl.addClass(self.options.triggerClass); }
});
self._bindEvents();
});
this.deferred = $q.defer();
return this.deferred.promise;
};
// closes the dialog and resolves the promise returned by the `open` method with the specified result.
Dialog.prototype.close = function(result){
var self = this;
var fadingElements = this._getFadingElements();
if(fadingElements.length > 0){
for (var i = fadingElements.length - 1; i >= 0; i--) {
$transition(fadingElements[i], removeTriggerClass).then(onCloseComplete);
}
return;
}
this._onCloseComplete(result);
function removeTriggerClass(el){
el.removeClass(self.options.triggerClass);
}
function onCloseComplete(){
if(self._open){
self._onCloseComplete(result);
}
}
};
Dialog.prototype._getFadingElements = function(){
var elements = [];
if(this.options.dialogFade){
elements.push(this.modalEl);
}
if(this.options.backdropFade){
elements.push(this.backdropEl);
}
return elements;
};
Dialog.prototype._bindEvents = function() {
if(this.options.keyboard){ body.bind('keydown', this.handledEscapeKey); }
if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.bind('click', this.handleBackDropClick); }
};
Dialog.prototype._unbindEvents = function() {
if(this.options.keyboard){ body.unbind('keydown', this.handledEscapeKey); }
if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.unbind('click', this.handleBackDropClick); }
};
Dialog.prototype._onCloseComplete = function(result) {
this._removeElementsFromDom();
this._unbindEvents();
this.deferred.resolve(result);
};
Dialog.prototype._addElementsToDom = function(){
body.append(this.modalEl);
if(this.options.backdrop) {
if (activeBackdrops.value === 0) {
body.append(this.backdropEl);
}
activeBackdrops.value++;
}
this._open = true;
};
Dialog.prototype._removeElementsFromDom = function(){
this.modalEl.remove();
if(this.options.backdrop) {
activeBackdrops.value--;
if (activeBackdrops.value === 0) {
this.backdropEl.remove();
}
}
this._open = false;
};
// Loads all `options.resolve` members to be used as locals for the controller associated with the dialog.
Dialog.prototype._loadResolves = function(){
var values = [], keys = [], templatePromise, self = this;
if (this.options.template) {
templatePromise = $q.when(this.options.template);
} else if (this.options.templateUrl) {
templatePromise = $http.get(this.options.templateUrl, {cache:$templateCache})
.then(function(response) { return response.data; });
}
angular.forEach(this.options.resolve || [], function(value, key) {
keys.push(key);
values.push(angular.isString(value) ? $injector.get(value) : $injector.invoke(value));
});
keys.push('$template');
values.push(templatePromise);
return $q.all(values).then(function(values) {
var locals = {};
angular.forEach(values, function(value, index) {
locals[keys[index]] = value;
});
locals.dialog = self;
return locals;
});
};
// The actual `$dialog` service that is injected in controllers.
return {
// Creates a new `Dialog` with the specified options.
dialog: function(opts){
return new Dialog(opts);
},
// creates a new `Dialog` tied to the default message box template and controller.
//
// Arguments `title` and `message` are rendered in the modal header and body sections respectively.
// The `buttons` array holds an object with the following members for each button to include in the
// modal footer section:
//
// * `result`: the result to pass to the `close` method of the dialog when the button is clicked
// * `label`: the label of the button
// * `cssClass`: additional css class(es) to apply to the button for styling
messageBox: function(title, message, buttons){
return new Dialog({templateUrl: 'template/dialog/message.html', controller: 'MessageBoxController', resolve:
{model: function() {
return {
title: title,
message: message,
buttons: buttons
};
}
}});
}
};
}];
});
/*
* dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
* @restrict class or attribute
* @example: