3 //== Translate Substitute Module =============================================//
6 * For those not using Angular-Translate (pascalprecht.translate), this will sub
7 * in for it so we don't have to include Angular-Translate if we don't want to.
10 var translateSubMod = angular.module('translate.sub',[]);
14 * Sets up a $translateProvider service to use in your module's config
15 * function. $translate.Provider syntax is the same as Angular-Translate,
16 * use $translate.Provider.translations(lang,obj) to change the defaults
17 * for modal button, header and message text.
19 translateSubMod.provider('$translate',[function(){
20 var _translations = []; // object of key/value translation pairs
21 var _current = 'en-US'; // default language
25 * Set the internal object of translation key/value pairs.
27 this.translations = function(lang,obj){
28 if(angular.isDefined(lang) && angular.isDefined(obj)){
29 _translations[lang] = angular.copy(obj);
32 }; // end translations
34 this.$get = [function(){
38 * Retrieve the translation for the given key, if key not found
39 * return an empty string.
40 * Example: $translate.instant('DIALOGS_OK');
42 instant : function(what){
43 if(angular.isDefined(what) && angular.isDefined(_translations[_current][what]))
44 return _translations[_current][what];
51 }]); // end $translate
55 * For use in an Angular template.
56 * Example: {{"DIALOGS_CLOSE" | translate}}
58 translateSubMod.filter('translate',['$translate',function($translate){
59 return function(what){
60 return $translate.instant(what);
62 }]); // end translate / translate.sub
63 //== Controllers =============================================================//
65 var ctrlrs; // will be dialogs.controllers module
67 // determine if Angular-Translate is available, if not use the substitute
69 angular.module('pascalprecht.translate'); // throws error if module not loaded
70 // console.log('Dialogs (Angular-Translate): OK');
72 // dialogs.controllers: module declaration
73 ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate']);
75 // console.log('Dialogs: (Angular-Translate): ' + err.message);
76 // console.log('Dialogs: Attempting to use translate.sub module.');
78 // dialogs.controllers: module declaration
79 ctrlrs = angular.module('dialogs.controllers',['ui.bootstrap.modal','translate.sub']);
82 // angular.module('dialogs.controllers',['ui.bootstrap.modal','pascalprecht.translate'])
85 * Error Dialog Controller
87 ctrlrs.controller('errorDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
88 //-- Variables -----//
90 $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_ERROR');
91 $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_ERROR_MSG');
92 $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-warning' : 'glyphicon glyphicon-warning-sign';
96 $scope.close = function(){
97 $modalInstance.close();
100 }]); // end ErrorDialogCtrl
103 * Wait Dialog Controller
105 ctrlrs.controller('waitDialogCtrl',['$scope','$modalInstance','$translate','$timeout','data',function($scope,$modalInstance,$translate,$timeout,data){
106 //-- Variables -----//
108 $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_PLEASE_WAIT_ELIPS');
109 $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_PLEASE_WAIT_MSG');
110 $scope.progress = (angular.isDefined(data.progress)) ? data.progress : 100;
111 $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-clock-o' : 'glyphicon glyphicon-time';
113 //-- Listeners -----//
115 // Note: used $timeout instead of $scope.$apply() because I was getting a $$nextSibling error
118 $scope.$on('dialogs.wait.complete',function(){
119 $timeout(function(){ $modalInstance.close(); $scope.$destroy(); });
120 }); // end on(dialogs.wait.complete)
122 // update the dialog's message
123 $scope.$on('dialogs.wait.message',function(evt,args){
124 $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
125 }); // end on(dialogs.wait.message)
127 // update the dialog's progress (bar) and/or message
128 $scope.$on('dialogs.wait.progress',function(evt,args){
129 $scope.msg = (angular.isDefined(args.msg)) ? args.msg : $scope.msg;
130 $scope.progress = (angular.isDefined(args.progress)) ? args.progress : $scope.progress;
131 }); // end on(dialogs.wait.progress)
135 $scope.getProgress = function(){
136 return {'width': $scope.progress + '%'};
137 }; // end getProgress
139 }]); // end WaitDialogCtrl
142 * Notify Dialog Controller
144 ctrlrs.controller('notifyDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
145 //-- Variables -----//
147 $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_NOTIFICATION');
148 $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_NOTIFICATION_MSG');
149 $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-info' : 'glyphicon glyphicon-info-sign';
153 $scope.close = function(){
154 $modalInstance.close();
157 }]); // end WaitDialogCtrl
160 * Confirm Dialog Controller
162 ctrlrs.controller('confirmDialogCtrl',['$scope','$modalInstance','$translate','data',function($scope,$modalInstance,$translate,data){
163 //-- Variables -----//
165 $scope.header = (angular.isDefined(data.header)) ? data.header : $translate.instant('DIALOGS_CONFIRMATION');
166 $scope.msg = (angular.isDefined(data.msg)) ? data.msg : $translate.instant('DIALOGS_CONFIRMATION_MSG');
167 $scope.icon = (angular.isDefined(data.fa) && angular.equals(data.fa,true)) ? 'fa fa-check' : 'glyphicon glyphicon-check';
171 $scope.no = function(){
172 $modalInstance.dismiss('no');
175 $scope.yes = function(){
176 $modalInstance.close('yes');
178 }]); // end ConfirmDialogCtrl / dialogs.controllers
179 //== Services ================================================================//
181 angular.module('dialogs.services',['ui.bootstrap.modal','dialogs.controllers'])
183 .provider('dialogs',[function(){
184 var _b = true; // backdrop
185 var _k = true; // keyboard
186 var _w = 'dialogs-default'; // windowClass
187 var _copy = true; // controls use of angular.copy
188 var _wTmpl = null; // window template
189 var _wSize = 'lg'; // large modal window default
191 var _fa = false; // fontawesome flag
193 var _setOpts = function(opts){
196 _opts.kb = (angular.isDefined(opts.keyboard)) ? opts.keyboard : _k; // values: true,false
197 _opts.bd = (angular.isDefined(opts.backdrop)) ? opts.backdrop : _b; // values: 'static',true,false
198 _opts.ws = (angular.isDefined(opts.size) && (angular.equals(opts.size,'sm') || angular.equals(opts.size,'lg') || angular.equals(opts.size,'md'))) ? opts.size : _wSize; // values: 'sm', 'lg', 'md'
199 _opts.wc = (angular.isDefined(opts.windowClass)) ? opts.windowClass : _w; // additional CSS class(es) to be added to a modal window
207 * Sets the use of the modal backdrop. Either to have one or not and
208 * whether or not it responds to mouse clicks ('static' sets the
209 * backdrop to true and does not respond to mouse clicks).
211 * @param val mixed (true, false, 'static')
213 this.useBackdrop = function(val){ // possible values : true, false, 'static'
214 if(angular.isDefined(val))
216 }; // end useStaticBackdrop
221 * Sets the use of the ESC (escape) key to close modal windows.
225 this.useEscClose = function(val){ // possible values : true, false
226 if(angular.isDefined(val))
227 _k = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
228 }; // end useESCClose
233 * Sets the additional CSS window class of the modal window template.
237 this.useClass = function(val){
238 if(angular.isDefined(val))
245 * Determines the use of angular.copy when sending data to the modal controller.
249 this.useCopy = function(val){
250 if(angular.isDefined(val))
251 _copy = (!angular.equals(val,0) && !angular.equals(val,'false') && !angular.equals(val,'no') && !angular.equals(val,null) && !angular.equals(val,false)) ? true : false;
255 * Set Window Template
257 * Sets a path to a template to use overriding modal's window template.
261 this.setWindowTmpl = function(val){
262 if(angular.isDefined(val))
264 }; // end setWindowTmpl
269 * Sets the modal size to use (sm,lg,md), requires Angular-ui-Bootstrap 0.11.0 and Bootstrap 3.1.0 +
271 * @param val string (sm,lg,md)
273 this.setSize = function(val){
274 if(angular.isDefined(val))
275 _wSize = (angular.equals(val,'sm') || angular.equals(val,'lg') || angular.equals(val,'md')) ? val : _wSize;
281 * Sets Font-Awesome flag to true and substitutes font-awesome icons for
282 * Bootstrap's glyphicons.
284 this.useFontAwesome = function(){
286 }; // end useFontAwesome
289 this.$get = ['$modal',function ($modal){
295 * @param header string
299 error : function(header,msg,opts){
300 opts = _setOpts(opts);
303 templateUrl : '/dialogs/error.html',
304 controller : 'errorDialogCtrl',
307 windowClass: opts.wc,
312 header : angular.copy(header),
313 msg : angular.copy(msg),
318 }); // end modal.open
324 * @param header string
326 * @param progress int
329 wait : function(header,msg,progress,opts){
330 opts = _setOpts(opts);
333 templateUrl : '/dialogs/wait.html',
334 controller : 'waitDialogCtrl',
337 windowClass: opts.wc,
342 header : angular.copy(header),
343 msg : angular.copy(msg),
344 progress : angular.copy(progress),
349 }); // end modal.open
355 * @param header string
359 notify : function(header,msg,opts){
360 opts = _setOpts(opts);
363 templateUrl : '/dialogs/notify.html',
364 controller : 'notifyDialogCtrl',
367 windowClass: opts.wc,
372 header : angular.copy(header),
373 msg : angular.copy(msg),
378 }); // end modal.open
384 * @param header string
388 confirm : function(header,msg,opts){
389 opts = _setOpts(opts);
392 templateUrl : '/dialogs/confirm.html',
393 controller : 'confirmDialogCtrl',
396 windowClass: opts.wc,
401 header : angular.copy(header),
402 msg : angular.copy(msg),
407 }); // end modal.open
411 * Create Custom Dialog
414 * @param ctrlr string
418 create : function(url,ctrlr,data,opts){
419 var copy = (opts && angular.isDefined(opts.copy)) ? opts.copy : _copy;
420 opts = _setOpts(opts);
427 windowClass: opts.wc,
432 return angular.copy(data);
437 }); // end modal.open
443 }]); // end provider dialogs
444 //== Dialogs.Main Module =====================================================//
447 * Include this module 'dialogs.main' in your module's dependency list where you
448 * intend to use it. Then inject the 'dialogs' service in your controllers that
452 angular.module('dialogs.main',['dialogs.services','ngSanitize']) // requires angular-sanitize.min.js (ngSanitize) //code.angularjs.org/1.2.1/angular-sanitize.min.js
454 .config(['$translateProvider','dialogsProvider',function($translateProvider,dialogsProvider){
456 * if Angular-Translate is not loaded, use the translate substitute
457 * module and create default translations to use as default modal texts
460 angular.module('pascalprecht.translate');
462 // console.log('Dialogs: Creating default translations for use without Angular-Translate.');
464 // This will set default modal buttons, header and message text
465 $translateProvider.translations('en-US',{
466 DIALOGS_ERROR: "Error",
467 DIALOGS_ERROR_MSG: "An unknown error has occurred.",
468 DIALOGS_CLOSE: "Close",
469 DIALOGS_PLEASE_WAIT: "Please Wait",
470 DIALOGS_PLEASE_WAIT_ELIPS: "Please Wait...",
471 DIALOGS_PLEASE_WAIT_MSG: "Waiting on operation to complete.",
472 DIALOGS_PERCENT_COMPLETE: "% Complete",
473 DIALOGS_NOTIFICATION: "Notification",
474 DIALOGS_NOTIFICATION_MSG: "Unknown application notification.",
475 DIALOGS_CONFIRMATION: "Confirmation",
476 DIALOGS_CONFIRMATION_MSG: "Confirmation required.",
484 * Attempt to ascertain if page is using Font Awesome instead of the
485 * regular Bootstrap Icons. If you are changing the stylesheet name or
486 * not including it from a CDN or have included Font-Awesome as a
487 * concatentation of CSS sheets together, then you will have to manually
488 * set Font-Awesome usage in your Angular Module's config by including
489 * the $dialogsProvider and calling the method $dialogsProvider.useFontAwesome().
492 var _sheets = document.styleSheets;
495 for(var i = (_sheets.length - 1);i >= 0;i--){
499 if(!_sheets[i].disabled){
500 // check href of style sheet first
501 if(_sheets[i].href !== null)
502 _matches = _sheets[i].match(/font\-*awesome/i);
504 if(angular.isArray(_matches)){
505 dialogsProvider.useFontAwesome();
506 break; // done, leave the style sheet for loop
508 // try to find css rule .fa, in case style sheet has been concatenated
509 _rules = _sheets[i].cssRules;
510 for(var x = (_rules.length - 1);x >= 0;x--){
511 if(_rules[x].selectorText.toLowerCase() == '.fa'){
512 dialogsProvider.useFontAwesome();
513 break sheetLoop; // done, exit both for loops
517 } // end if(disabled)
520 /* Removed in favor of above, will delete this permanently after more testing
521 angular.forEach(_sheets,function(_sheet,key){
523 if(!angular.equals(_sheet.href,null))
524 _matches = _sheet.href.match(/font\-*awesome/);
526 if(!_sheet.disabled && angular.isArray(_matches)){
527 // console.log('Dialogs: Using Font-Awesome Icons');
528 dialogsProvider.useFontAwesome();
533 // console.log('Error Message: ' + err);
537 // Add default templates via $templateCache
538 .run(['$templateCache','$interpolate',function($templateCache,$interpolate){
540 // get interpolation symbol (possible that someone may have changed it in their application instead of using '{{}}')
541 var startSym = $interpolate.startSymbol();
542 var endSym = $interpolate.endSymbol();
544 $templateCache.put('/dialogs/error.html','<div class="modal-header dialog-header-error"><button type="button" class="close" ng-click="close()">×</button><h4 class="modal-title text-danger"><span class="'+startSym+'icon'+endSym+'"></span> <span ng-bind-html="header"></span></h4></div><div class="modal-body text-danger" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="close()">'+startSym+'"DIALOGS_CLOSE" | translate'+endSym+'</button></div>');
545 $templateCache.put('/dialogs/wait.html','<div class="modal-header dialog-header-wait"><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body"><p ng-bind-html="msg"></p><div class="progress progress-striped active"><div class="progress-bar progress-bar-info" ng-style="getProgress()"></div><span class="sr-only">'+startSym+'progress'+endSym+''+startSym+'"DIALOGS_PERCENT_COMPLETE" | translate'+endSym+'</span></div></div>');
546 $templateCache.put('/dialogs/notify.html','<div class="modal-header dialog-header-notify"><button type="button" class="close" ng-click="close()" class="pull-right">×</button><h4 class="modal-title text-info"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body text-info" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-primary" ng-click="close()">'+startSym+'"DIALOGS_OK" | translate'+endSym+'</button></div>');
547 $templateCache.put('/dialogs/confirm.html','<div class="modal-header dialog-header-confirm"><button type="button" class="close" ng-click="no()">×</button><h4 class="modal-title"><span class="'+startSym+'icon'+endSym+'"></span> '+startSym+'header'+endSym+'</h4></div><div class="modal-body" ng-bind-html="msg"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="yes()">'+startSym+'"DIALOGS_YES" | translate'+endSym+'</button><button type="button" class="btn btn-primary" ng-click="no()">'+startSym+'"DIALOGS_NO" | translate'+endSym+'</button></div>');
548 }]); // end run / dialogs.main