angular-ui-bootstrap-rails 0.5.0.0 → 0.6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 673a0814c0c59e273cfa7ad9d557d3d62881d370
|
4
|
+
data.tar.gz: ed5fd830fe8a45a920b1c53caa82a4beae0798ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76e6035443aaf8bc45b0fdffce94458455ab9e7033452bd61fb987d83d9caeaaf3da80c765ef3149fb39639c47921cb2f26720daac327ec88d27e0c5ee37b397
|
7
|
+
data.tar.gz: e54f8515bf6cb2cd25c30ef6fae535b0f897261f7289a52bc51403f561b0ba97214ee578235fc7606d00ec4ad7fd51e07cc44bd39cb0af07bd53f56f3e228fae
|
@@ -1,5 +1,5 @@
|
|
1
|
-
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.
|
2
|
-
angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/
|
1
|
+
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdownToggle","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
|
2
|
+
angular.module("ui.bootstrap.tpls", ["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/popup.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset-titles.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]);
|
3
3
|
angular.module('ui.bootstrap.transition', [])
|
4
4
|
|
5
5
|
/**
|
@@ -337,6 +337,16 @@ angular.module("ui.bootstrap.alert", []).directive('alert', function () {
|
|
337
337
|
};
|
338
338
|
});
|
339
339
|
|
340
|
+
angular.module('ui.bootstrap.bindHtml', [])
|
341
|
+
|
342
|
+
.directive('bindHtmlUnsafe', function () {
|
343
|
+
return function (scope, element, attr) {
|
344
|
+
element.addClass('ng-binding').data('$binding', attr.bindHtmlUnsafe);
|
345
|
+
scope.$watch(attr.bindHtmlUnsafe, function bindHtmlUnsafeWatchAction(value) {
|
346
|
+
element.html(value || '');
|
347
|
+
});
|
348
|
+
};
|
349
|
+
});
|
340
350
|
angular.module('ui.bootstrap.buttons', [])
|
341
351
|
|
342
352
|
.constant('buttonConfig', {
|
@@ -408,7 +418,7 @@ angular.module('ui.bootstrap.buttons', [])
|
|
408
418
|
/**
|
409
419
|
* @ngdoc overview
|
410
420
|
* @name ui.bootstrap.carousel
|
411
|
-
*
|
421
|
+
*
|
412
422
|
* @description
|
413
423
|
* AngularJS version of an image carousel.
|
414
424
|
*
|
@@ -439,10 +449,10 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
439
449
|
}
|
440
450
|
function goNext() {
|
441
451
|
//If we have a slide to transition from and we have a transition type and we're allowed, go
|
442
|
-
if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
|
452
|
+
if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
|
443
453
|
//We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
|
444
454
|
nextSlide.$element.addClass(direction);
|
445
|
-
|
455
|
+
var reflow = nextSlide.$element[0].offsetWidth; //force reflow
|
446
456
|
|
447
457
|
//Set all other slides to stop doing their stuff for the new transition
|
448
458
|
angular.forEach(slides, function(slide) {
|
@@ -481,7 +491,7 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
481
491
|
|
482
492
|
$scope.next = function() {
|
483
493
|
var newIndex = (currentIndex + 1) % slides.length;
|
484
|
-
|
494
|
+
|
485
495
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
486
496
|
if (!$scope.$currentTransition) {
|
487
497
|
return self.select(slides[newIndex], 'next');
|
@@ -490,7 +500,7 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
|
|
490
500
|
|
491
501
|
$scope.prev = function() {
|
492
502
|
var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
|
493
|
-
|
503
|
+
|
494
504
|
//Prevent this user-triggered transition from occurring if there is already one in progress
|
495
505
|
if (!$scope.$currentTransition) {
|
496
506
|
return self.select(slides[newIndex], 'prev');
|
@@ -707,7 +717,7 @@ function CarouselDemoCtrl($scope) {
|
|
707
717
|
var lastValue = scope.active = getActive(scope.$parent);
|
708
718
|
scope.$watch(function parentActiveWatch() {
|
709
719
|
var parentActive = getActive(scope.$parent);
|
710
|
-
|
720
|
+
|
711
721
|
if (parentActive !== scope.active) {
|
712
722
|
// we are out of sync and need to copy
|
713
723
|
if (parentActive !== lastValue) {
|
@@ -747,13 +757,6 @@ angular.module('ui.bootstrap.position', [])
|
|
747
757
|
*/
|
748
758
|
.factory('$position', ['$document', '$window', function ($document, $window) {
|
749
759
|
|
750
|
-
var mouseX, mouseY;
|
751
|
-
|
752
|
-
$document.bind('mousemove', function mouseMoved(event) {
|
753
|
-
mouseX = event.pageX;
|
754
|
-
mouseY = event.pageY;
|
755
|
-
});
|
756
|
-
|
757
760
|
function getStyle(el, cssprop) {
|
758
761
|
if (el.currentStyle) { //IE
|
759
762
|
return el.currentStyle[cssprop];
|
@@ -817,16 +820,9 @@ angular.module('ui.bootstrap.position', [])
|
|
817
820
|
return {
|
818
821
|
width: element.prop('offsetWidth'),
|
819
822
|
height: element.prop('offsetHeight'),
|
820
|
-
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop),
|
821
|
-
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft)
|
823
|
+
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop || $document[0].documentElement.scrollTop),
|
824
|
+
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft || $document[0].documentElement.scrollLeft)
|
822
825
|
};
|
823
|
-
},
|
824
|
-
|
825
|
-
/**
|
826
|
-
* Provides the coordinates of the mouse
|
827
|
-
*/
|
828
|
-
mouse: function () {
|
829
|
-
return {x: mouseX, y: mouseY};
|
830
826
|
}
|
831
827
|
};
|
832
828
|
}]);
|
@@ -1105,26 +1101,9 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1105
1101
|
scope.$destroy();
|
1106
1102
|
});
|
1107
1103
|
|
1108
|
-
function formatDate(value) {
|
1109
|
-
return (value) ? dateFilter(value, dateFormat) : null;
|
1110
|
-
}
|
1111
|
-
ngModel.$formatters.push(formatDate);
|
1112
|
-
|
1113
|
-
// TODO: reverse from dateFilter string to Date object
|
1114
|
-
function parseDate(value) {
|
1115
|
-
if ( value ) {
|
1116
|
-
var date = new Date(value);
|
1117
|
-
if (!isNaN(date)) {
|
1118
|
-
return date;
|
1119
|
-
}
|
1120
|
-
}
|
1121
|
-
return value;
|
1122
|
-
}
|
1123
|
-
ngModel.$parsers.push(parseDate);
|
1124
|
-
|
1125
1104
|
var getIsOpen, setIsOpen;
|
1126
|
-
if ( attrs.
|
1127
|
-
getIsOpen = $parse(attrs.
|
1105
|
+
if ( attrs.isOpen ) {
|
1106
|
+
getIsOpen = $parse(attrs.isOpen);
|
1128
1107
|
setIsOpen = getIsOpen.assign;
|
1129
1108
|
|
1130
1109
|
originalScope.$watch(getIsOpen, function updateOpen(value) {
|
@@ -1166,33 +1145,58 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1166
1145
|
datepickerEl.attr(angular.extend({}, originalScope.$eval(attrs.datepickerOptions)));
|
1167
1146
|
}
|
1168
1147
|
|
1169
|
-
|
1148
|
+
// TODO: reverse from dateFilter string to Date object
|
1149
|
+
function parseDate(viewValue) {
|
1150
|
+
if (!viewValue) {
|
1151
|
+
ngModel.$setValidity('date', true);
|
1152
|
+
return null;
|
1153
|
+
} else if (angular.isDate(viewValue)) {
|
1154
|
+
ngModel.$setValidity('date', true);
|
1155
|
+
return viewValue;
|
1156
|
+
} else if (angular.isString(viewValue)) {
|
1157
|
+
var date = new Date(viewValue);
|
1158
|
+
if (isNaN(date)) {
|
1159
|
+
ngModel.$setValidity('date', false);
|
1160
|
+
return undefined;
|
1161
|
+
} else {
|
1162
|
+
ngModel.$setValidity('date', true);
|
1163
|
+
return date;
|
1164
|
+
}
|
1165
|
+
} else {
|
1166
|
+
ngModel.$setValidity('date', false);
|
1167
|
+
return undefined;
|
1168
|
+
}
|
1169
|
+
}
|
1170
|
+
ngModel.$parsers.unshift(parseDate);
|
1170
1171
|
|
1171
1172
|
// Inner change
|
1172
1173
|
scope.dateSelection = function() {
|
1173
|
-
|
1174
|
+
ngModel.$setViewValue(scope.date);
|
1175
|
+
ngModel.$render();
|
1176
|
+
|
1174
1177
|
if (closeOnDateSelection) {
|
1175
1178
|
setOpen( false );
|
1176
1179
|
}
|
1177
1180
|
};
|
1178
1181
|
|
1182
|
+
element.bind('input change keyup', function() {
|
1183
|
+
scope.$apply(function() {
|
1184
|
+
updateCalendar();
|
1185
|
+
});
|
1186
|
+
});
|
1187
|
+
|
1179
1188
|
// Outter change
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
} else {
|
1190
|
-
value = date;
|
1191
|
-
}
|
1192
|
-
}
|
1193
|
-
scope.date = value;
|
1189
|
+
ngModel.$render = function() {
|
1190
|
+
var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
|
1191
|
+
element.val(date);
|
1192
|
+
|
1193
|
+
updateCalendar();
|
1194
|
+
};
|
1195
|
+
|
1196
|
+
function updateCalendar() {
|
1197
|
+
scope.date = ngModel.$modelValue;
|
1194
1198
|
updatePosition();
|
1195
|
-
}
|
1199
|
+
}
|
1196
1200
|
|
1197
1201
|
function addWatchableAttribute(attribute, scopeProperty, datepickerAttribute) {
|
1198
1202
|
if (attribute) {
|
@@ -1219,15 +1223,22 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1219
1223
|
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
1220
1224
|
}
|
1221
1225
|
|
1226
|
+
var documentBindingInitialized = false, elementFocusInitialized = false;
|
1222
1227
|
scope.$watch('isOpen', function(value) {
|
1223
1228
|
if (value) {
|
1224
1229
|
updatePosition();
|
1225
1230
|
$document.bind('click', documentClickBind);
|
1226
|
-
|
1227
|
-
|
1231
|
+
if(elementFocusInitialized) {
|
1232
|
+
element.unbind('focus', elementFocusBind);
|
1233
|
+
}
|
1234
|
+
element[0].focus();
|
1235
|
+
documentBindingInitialized = true;
|
1228
1236
|
} else {
|
1229
|
-
|
1237
|
+
if(documentBindingInitialized) {
|
1238
|
+
$document.unbind('click', documentClickBind);
|
1239
|
+
}
|
1230
1240
|
element.bind('focus', elementFocusBind);
|
1241
|
+
elementFocusInitialized = true;
|
1231
1242
|
}
|
1232
1243
|
|
1233
1244
|
if ( setIsOpen ) {
|
@@ -1235,6 +1246,8 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1235
1246
|
}
|
1236
1247
|
});
|
1237
1248
|
|
1249
|
+
var $setModelValue = $parse(attrs.ngModel).assign;
|
1250
|
+
|
1238
1251
|
scope.today = function() {
|
1239
1252
|
$setModelValue(originalScope, new Date());
|
1240
1253
|
};
|
@@ -1261,286 +1274,6 @@ function ($compile, $parse, $document, $position, dateFilter, datepickerPopupCon
|
|
1261
1274
|
}
|
1262
1275
|
};
|
1263
1276
|
}]);
|
1264
|
-
// The `$dialogProvider` can be used to configure global defaults for your
|
1265
|
-
// `$dialog` service.
|
1266
|
-
var dialogModule = angular.module('ui.bootstrap.dialog', ['ui.bootstrap.transition']);
|
1267
|
-
|
1268
|
-
dialogModule.controller('MessageBoxController', ['$scope', 'dialog', 'model', function($scope, dialog, model){
|
1269
|
-
$scope.title = model.title;
|
1270
|
-
$scope.message = model.message;
|
1271
|
-
$scope.buttons = model.buttons;
|
1272
|
-
$scope.close = function(res){
|
1273
|
-
dialog.close(res);
|
1274
|
-
};
|
1275
|
-
}]);
|
1276
|
-
|
1277
|
-
dialogModule.provider("$dialog", function(){
|
1278
|
-
|
1279
|
-
// The default options for all dialogs.
|
1280
|
-
var defaults = {
|
1281
|
-
backdrop: true,
|
1282
|
-
dialogClass: 'modal',
|
1283
|
-
backdropClass: 'modal-backdrop',
|
1284
|
-
transitionClass: 'fade',
|
1285
|
-
triggerClass: 'in',
|
1286
|
-
resolve:{},
|
1287
|
-
backdropFade: false,
|
1288
|
-
dialogFade:false,
|
1289
|
-
keyboard: true, // close with esc key
|
1290
|
-
backdropClick: true // only in conjunction with backdrop=true
|
1291
|
-
/* other options: template, templateUrl, controller */
|
1292
|
-
};
|
1293
|
-
|
1294
|
-
var globalOptions = {};
|
1295
|
-
|
1296
|
-
var activeBackdrops = {value : 0};
|
1297
|
-
|
1298
|
-
// The `options({})` allows global configuration of all dialogs in the application.
|
1299
|
-
//
|
1300
|
-
// var app = angular.module('App', ['ui.bootstrap.dialog'], function($dialogProvider){
|
1301
|
-
// // don't close dialog when backdrop is clicked by default
|
1302
|
-
// $dialogProvider.options({backdropClick: false});
|
1303
|
-
// });
|
1304
|
-
this.options = function(value){
|
1305
|
-
globalOptions = value;
|
1306
|
-
};
|
1307
|
-
|
1308
|
-
// Returns the actual `$dialog` service that is injected in controllers
|
1309
|
-
this.$get = ["$http", "$document", "$compile", "$rootScope", "$controller", "$templateCache", "$q", "$transition", "$injector",
|
1310
|
-
function ($http, $document, $compile, $rootScope, $controller, $templateCache, $q, $transition, $injector) {
|
1311
|
-
|
1312
|
-
var body = $document.find('body');
|
1313
|
-
|
1314
|
-
function createElement(clazz) {
|
1315
|
-
var el = angular.element("<div>");
|
1316
|
-
el.addClass(clazz);
|
1317
|
-
return el;
|
1318
|
-
}
|
1319
|
-
|
1320
|
-
// The `Dialog` class represents a modal dialog. The dialog class can be invoked by providing an options object
|
1321
|
-
// containing at lest template or templateUrl and controller:
|
1322
|
-
//
|
1323
|
-
// var d = new Dialog({templateUrl: 'foo.html', controller: 'BarController'});
|
1324
|
-
//
|
1325
|
-
// Dialogs can also be created using templateUrl and controller as distinct arguments:
|
1326
|
-
//
|
1327
|
-
// var d = new Dialog('path/to/dialog.html', MyDialogController);
|
1328
|
-
function Dialog(opts) {
|
1329
|
-
|
1330
|
-
var self = this, options = this.options = angular.extend({}, defaults, globalOptions, opts);
|
1331
|
-
this._open = false;
|
1332
|
-
|
1333
|
-
this.backdropEl = createElement(options.backdropClass);
|
1334
|
-
if(options.backdropFade){
|
1335
|
-
this.backdropEl.addClass(options.transitionClass);
|
1336
|
-
this.backdropEl.removeClass(options.triggerClass);
|
1337
|
-
}
|
1338
|
-
|
1339
|
-
this.modalEl = createElement(options.dialogClass);
|
1340
|
-
if(options.dialogFade){
|
1341
|
-
this.modalEl.addClass(options.transitionClass);
|
1342
|
-
this.modalEl.removeClass(options.triggerClass);
|
1343
|
-
}
|
1344
|
-
|
1345
|
-
this.handledEscapeKey = function(e) {
|
1346
|
-
if (e.which === 27) {
|
1347
|
-
self.close();
|
1348
|
-
e.preventDefault();
|
1349
|
-
self.$scope.$apply();
|
1350
|
-
}
|
1351
|
-
};
|
1352
|
-
|
1353
|
-
this.handleBackDropClick = function(e) {
|
1354
|
-
self.close();
|
1355
|
-
e.preventDefault();
|
1356
|
-
self.$scope.$apply();
|
1357
|
-
};
|
1358
|
-
}
|
1359
|
-
|
1360
|
-
// The `isOpen()` method returns wether the dialog is currently visible.
|
1361
|
-
Dialog.prototype.isOpen = function(){
|
1362
|
-
return this._open;
|
1363
|
-
};
|
1364
|
-
|
1365
|
-
// The `open(templateUrl, controller)` method opens the dialog.
|
1366
|
-
// Use the `templateUrl` and `controller` arguments if specifying them at dialog creation time is not desired.
|
1367
|
-
Dialog.prototype.open = function(templateUrl, controller){
|
1368
|
-
var self = this, options = this.options;
|
1369
|
-
|
1370
|
-
if(templateUrl){
|
1371
|
-
options.templateUrl = templateUrl;
|
1372
|
-
}
|
1373
|
-
if(controller){
|
1374
|
-
options.controller = controller;
|
1375
|
-
}
|
1376
|
-
|
1377
|
-
if(!(options.template || options.templateUrl)) {
|
1378
|
-
throw new Error('Dialog.open expected template or templateUrl, neither found. Use options or open method to specify them.');
|
1379
|
-
}
|
1380
|
-
|
1381
|
-
this._loadResolves().then(function(locals) {
|
1382
|
-
var $scope = locals.$scope = self.$scope = locals.$scope ? locals.$scope : $rootScope.$new();
|
1383
|
-
|
1384
|
-
self.modalEl.html(locals.$template);
|
1385
|
-
|
1386
|
-
if (self.options.controller) {
|
1387
|
-
var ctrl = $controller(self.options.controller, locals);
|
1388
|
-
self.modalEl.children().data('ngControllerController', ctrl);
|
1389
|
-
}
|
1390
|
-
|
1391
|
-
$compile(self.modalEl)($scope);
|
1392
|
-
self._addElementsToDom();
|
1393
|
-
|
1394
|
-
// trigger tranisitions
|
1395
|
-
setTimeout(function(){
|
1396
|
-
if(self.options.dialogFade){ self.modalEl.addClass(self.options.triggerClass); }
|
1397
|
-
if(self.options.backdropFade){ self.backdropEl.addClass(self.options.triggerClass); }
|
1398
|
-
});
|
1399
|
-
|
1400
|
-
self._bindEvents();
|
1401
|
-
});
|
1402
|
-
|
1403
|
-
this.deferred = $q.defer();
|
1404
|
-
return this.deferred.promise;
|
1405
|
-
};
|
1406
|
-
|
1407
|
-
// closes the dialog and resolves the promise returned by the `open` method with the specified result.
|
1408
|
-
Dialog.prototype.close = function(result){
|
1409
|
-
var self = this;
|
1410
|
-
var fadingElements = this._getFadingElements();
|
1411
|
-
|
1412
|
-
if(fadingElements.length > 0){
|
1413
|
-
for (var i = fadingElements.length - 1; i >= 0; i--) {
|
1414
|
-
$transition(fadingElements[i], removeTriggerClass).then(onCloseComplete);
|
1415
|
-
}
|
1416
|
-
return;
|
1417
|
-
}
|
1418
|
-
|
1419
|
-
this._onCloseComplete(result);
|
1420
|
-
|
1421
|
-
function removeTriggerClass(el){
|
1422
|
-
el.removeClass(self.options.triggerClass);
|
1423
|
-
}
|
1424
|
-
|
1425
|
-
function onCloseComplete(){
|
1426
|
-
if(self._open){
|
1427
|
-
self._onCloseComplete(result);
|
1428
|
-
}
|
1429
|
-
}
|
1430
|
-
};
|
1431
|
-
|
1432
|
-
Dialog.prototype._getFadingElements = function(){
|
1433
|
-
var elements = [];
|
1434
|
-
if(this.options.dialogFade){
|
1435
|
-
elements.push(this.modalEl);
|
1436
|
-
}
|
1437
|
-
if(this.options.backdropFade){
|
1438
|
-
elements.push(this.backdropEl);
|
1439
|
-
}
|
1440
|
-
|
1441
|
-
return elements;
|
1442
|
-
};
|
1443
|
-
|
1444
|
-
Dialog.prototype._bindEvents = function() {
|
1445
|
-
if(this.options.keyboard){ body.bind('keydown', this.handledEscapeKey); }
|
1446
|
-
if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.bind('click', this.handleBackDropClick); }
|
1447
|
-
};
|
1448
|
-
|
1449
|
-
Dialog.prototype._unbindEvents = function() {
|
1450
|
-
if(this.options.keyboard){ body.unbind('keydown', this.handledEscapeKey); }
|
1451
|
-
if(this.options.backdrop && this.options.backdropClick){ this.backdropEl.unbind('click', this.handleBackDropClick); }
|
1452
|
-
};
|
1453
|
-
|
1454
|
-
Dialog.prototype._onCloseComplete = function(result) {
|
1455
|
-
this._removeElementsFromDom();
|
1456
|
-
this._unbindEvents();
|
1457
|
-
|
1458
|
-
this.deferred.resolve(result);
|
1459
|
-
};
|
1460
|
-
|
1461
|
-
Dialog.prototype._addElementsToDom = function(){
|
1462
|
-
body.append(this.modalEl);
|
1463
|
-
|
1464
|
-
if(this.options.backdrop) {
|
1465
|
-
if (activeBackdrops.value === 0) {
|
1466
|
-
body.append(this.backdropEl);
|
1467
|
-
}
|
1468
|
-
activeBackdrops.value++;
|
1469
|
-
}
|
1470
|
-
|
1471
|
-
this._open = true;
|
1472
|
-
};
|
1473
|
-
|
1474
|
-
Dialog.prototype._removeElementsFromDom = function(){
|
1475
|
-
this.modalEl.remove();
|
1476
|
-
|
1477
|
-
if(this.options.backdrop) {
|
1478
|
-
activeBackdrops.value--;
|
1479
|
-
if (activeBackdrops.value === 0) {
|
1480
|
-
this.backdropEl.remove();
|
1481
|
-
}
|
1482
|
-
}
|
1483
|
-
this._open = false;
|
1484
|
-
};
|
1485
|
-
|
1486
|
-
// Loads all `options.resolve` members to be used as locals for the controller associated with the dialog.
|
1487
|
-
Dialog.prototype._loadResolves = function(){
|
1488
|
-
var values = [], keys = [], templatePromise, self = this;
|
1489
|
-
|
1490
|
-
if (this.options.template) {
|
1491
|
-
templatePromise = $q.when(this.options.template);
|
1492
|
-
} else if (this.options.templateUrl) {
|
1493
|
-
templatePromise = $http.get(this.options.templateUrl, {cache:$templateCache})
|
1494
|
-
.then(function(response) { return response.data; });
|
1495
|
-
}
|
1496
|
-
|
1497
|
-
angular.forEach(this.options.resolve || [], function(value, key) {
|
1498
|
-
keys.push(key);
|
1499
|
-
values.push(angular.isString(value) ? $injector.get(value) : $injector.invoke(value));
|
1500
|
-
});
|
1501
|
-
|
1502
|
-
keys.push('$template');
|
1503
|
-
values.push(templatePromise);
|
1504
|
-
|
1505
|
-
return $q.all(values).then(function(values) {
|
1506
|
-
var locals = {};
|
1507
|
-
angular.forEach(values, function(value, index) {
|
1508
|
-
locals[keys[index]] = value;
|
1509
|
-
});
|
1510
|
-
locals.dialog = self;
|
1511
|
-
return locals;
|
1512
|
-
});
|
1513
|
-
};
|
1514
|
-
|
1515
|
-
// The actual `$dialog` service that is injected in controllers.
|
1516
|
-
return {
|
1517
|
-
// Creates a new `Dialog` with the specified options.
|
1518
|
-
dialog: function(opts){
|
1519
|
-
return new Dialog(opts);
|
1520
|
-
},
|
1521
|
-
// creates a new `Dialog` tied to the default message box template and controller.
|
1522
|
-
//
|
1523
|
-
// Arguments `title` and `message` are rendered in the modal header and body sections respectively.
|
1524
|
-
// The `buttons` array holds an object with the following members for each button to include in the
|
1525
|
-
// modal footer section:
|
1526
|
-
//
|
1527
|
-
// * `result`: the result to pass to the `close` method of the dialog when the button is clicked
|
1528
|
-
// * `label`: the label of the button
|
1529
|
-
// * `cssClass`: additional css class(es) to apply to the button for styling
|
1530
|
-
messageBox: function(title, message, buttons){
|
1531
|
-
return new Dialog({templateUrl: 'template/dialog/message.html', controller: 'MessageBoxController', resolve:
|
1532
|
-
{model: function() {
|
1533
|
-
return {
|
1534
|
-
title: title,
|
1535
|
-
message: message,
|
1536
|
-
buttons: buttons
|
1537
|
-
};
|
1538
|
-
}
|
1539
|
-
}});
|
1540
|
-
}
|
1541
|
-
};
|
1542
|
-
}];
|
1543
|
-
});
|
1544
1277
|
|
1545
1278
|
/*
|
1546
1279
|
* dropdownToggle - Provides dropdown menu functionality in place of bootstrap js
|
@@ -1594,93 +1327,391 @@ angular.module('ui.bootstrap.dropdownToggle', []).directive('dropdownToggle', ['
|
|
1594
1327
|
}
|
1595
1328
|
};
|
1596
1329
|
}]);
|
1597
|
-
angular.module('ui.bootstrap.modal', [
|
1598
|
-
.directive('modal', ['$parse', '$dialog', function($parse, $dialog) {
|
1599
|
-
return {
|
1600
|
-
restrict: 'EA',
|
1601
|
-
terminal: true,
|
1602
|
-
link: function(scope, elm, attrs) {
|
1603
|
-
var opts = angular.extend({}, scope.$eval(attrs.uiOptions || attrs.bsOptions || attrs.options));
|
1604
|
-
var shownExpr = attrs.modal || attrs.show;
|
1605
|
-
var setClosed;
|
1606
|
-
|
1607
|
-
// Create a dialog with the template as the contents of the directive
|
1608
|
-
// Add the current scope as the resolve in order to make the directive scope as a dialog controller scope
|
1609
|
-
opts = angular.extend(opts, {
|
1610
|
-
template: elm.html(),
|
1611
|
-
resolve: { $scope: function() { return scope; } }
|
1612
|
-
});
|
1613
|
-
var dialog = $dialog.dialog(opts);
|
1330
|
+
angular.module('ui.bootstrap.modal', [])
|
1614
1331
|
|
1615
|
-
|
1332
|
+
/**
|
1333
|
+
* A helper, internal data structure that acts as a map but also allows getting / removing
|
1334
|
+
* elements in the LIFO order
|
1335
|
+
*/
|
1336
|
+
.factory('$$stackedMap', function () {
|
1337
|
+
return {
|
1338
|
+
createNew: function () {
|
1339
|
+
var stack = [];
|
1616
1340
|
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1341
|
+
return {
|
1342
|
+
add: function (key, value) {
|
1343
|
+
stack.push({
|
1344
|
+
key: key,
|
1345
|
+
value: value
|
1346
|
+
});
|
1347
|
+
},
|
1348
|
+
get: function (key) {
|
1349
|
+
for (var i = 0; i < stack.length; i++) {
|
1350
|
+
if (key == stack[i].key) {
|
1351
|
+
return stack[i];
|
1352
|
+
}
|
1353
|
+
}
|
1354
|
+
},
|
1355
|
+
keys: function() {
|
1356
|
+
var keys = [];
|
1357
|
+
for (var i = 0; i < stack.length; i++) {
|
1358
|
+
keys.push(stack[i].key);
|
1359
|
+
}
|
1360
|
+
return keys;
|
1361
|
+
},
|
1362
|
+
top: function () {
|
1363
|
+
return stack[stack.length - 1];
|
1364
|
+
},
|
1365
|
+
remove: function (key) {
|
1366
|
+
var idx = -1;
|
1367
|
+
for (var i = 0; i < stack.length; i++) {
|
1368
|
+
if (key == stack[i].key) {
|
1369
|
+
idx = i;
|
1370
|
+
break;
|
1371
|
+
}
|
1372
|
+
}
|
1373
|
+
return stack.splice(idx, 1)[0];
|
1374
|
+
},
|
1375
|
+
removeTop: function () {
|
1376
|
+
return stack.splice(stack.length - 1, 1)[0];
|
1377
|
+
},
|
1378
|
+
length: function () {
|
1379
|
+
return stack.length;
|
1380
|
+
}
|
1620
1381
|
};
|
1621
|
-
}
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1382
|
+
}
|
1383
|
+
};
|
1384
|
+
})
|
1385
|
+
|
1386
|
+
/**
|
1387
|
+
* A helper directive for the $modal service. It creates a backdrop element.
|
1388
|
+
*/
|
1389
|
+
.directive('modalBackdrop', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
|
1390
|
+
return {
|
1391
|
+
restrict: 'EA',
|
1392
|
+
replace: true,
|
1393
|
+
templateUrl: 'template/modal/backdrop.html',
|
1394
|
+
link: function (scope, element, attrs) {
|
1395
|
+
|
1396
|
+
//trigger CSS transitions
|
1397
|
+
$timeout(function () {
|
1398
|
+
scope.animate = true;
|
1399
|
+
});
|
1400
|
+
|
1401
|
+
scope.close = function (evt) {
|
1402
|
+
var modal = $modalStack.getTop();
|
1403
|
+
if (modal && modal.value.backdrop && modal.value.backdrop != 'static') {
|
1404
|
+
evt.preventDefault();
|
1405
|
+
evt.stopPropagation();
|
1406
|
+
$modalStack.dismiss(modal.key, 'backdrop click');
|
1625
1407
|
}
|
1626
1408
|
};
|
1627
1409
|
}
|
1410
|
+
};
|
1411
|
+
}])
|
1628
1412
|
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1413
|
+
.directive('modalWindow', ['$timeout', function ($timeout) {
|
1414
|
+
return {
|
1415
|
+
restrict: 'EA',
|
1416
|
+
scope: {
|
1417
|
+
index: '@'
|
1418
|
+
},
|
1419
|
+
replace: true,
|
1420
|
+
transclude: true,
|
1421
|
+
templateUrl: 'template/modal/window.html',
|
1422
|
+
link: function (scope, element, attrs) {
|
1423
|
+
scope.windowClass = attrs.windowClass || '';
|
1424
|
+
|
1425
|
+
//trigger CSS transitions
|
1426
|
+
$timeout(function () {
|
1427
|
+
scope.animate = true;
|
1428
|
+
});
|
1429
|
+
}
|
1430
|
+
};
|
1431
|
+
}])
|
1432
|
+
|
1433
|
+
.factory('$modalStack', ['$document', '$compile', '$rootScope', '$$stackedMap',
|
1434
|
+
function ($document, $compile, $rootScope, $$stackedMap) {
|
1435
|
+
|
1436
|
+
var backdropjqLiteEl, backdropDomEl;
|
1437
|
+
var backdropScope = $rootScope.$new(true);
|
1438
|
+
var body = $document.find('body').eq(0);
|
1439
|
+
var openedWindows = $$stackedMap.createNew();
|
1440
|
+
var $modalStack = {};
|
1441
|
+
|
1442
|
+
function backdropIndex() {
|
1443
|
+
var topBackdropIndex = -1;
|
1444
|
+
var opened = openedWindows.keys();
|
1445
|
+
for (var i = 0; i < opened.length; i++) {
|
1446
|
+
if (openedWindows.get(opened[i]).value.backdrop) {
|
1447
|
+
topBackdropIndex = i;
|
1638
1448
|
}
|
1639
1449
|
}
|
1450
|
+
return topBackdropIndex;
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
$rootScope.$watch(backdropIndex, function(newBackdropIndex){
|
1454
|
+
backdropScope.index = newBackdropIndex;
|
1640
1455
|
});
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1456
|
+
|
1457
|
+
function removeModalWindow(modalInstance) {
|
1458
|
+
|
1459
|
+
var modalWindow = openedWindows.get(modalInstance).value;
|
1460
|
+
|
1461
|
+
//clean up the stack
|
1462
|
+
openedWindows.remove(modalInstance);
|
1463
|
+
|
1464
|
+
//remove window DOM element
|
1465
|
+
modalWindow.modalDomEl.remove();
|
1466
|
+
|
1467
|
+
//remove backdrop if no longer needed
|
1468
|
+
if (backdropIndex() == -1) {
|
1469
|
+
backdropDomEl.remove();
|
1470
|
+
backdropDomEl = undefined;
|
1471
|
+
}
|
1472
|
+
|
1473
|
+
//destroy scope
|
1474
|
+
modalWindow.modalScope.$destroy();
|
1475
|
+
}
|
1476
|
+
|
1477
|
+
$document.bind('keydown', function (evt) {
|
1478
|
+
var modal;
|
1479
|
+
|
1480
|
+
if (evt.which === 27) {
|
1481
|
+
modal = openedWindows.top();
|
1482
|
+
if (modal && modal.value.keyboard) {
|
1483
|
+
$rootScope.$apply(function () {
|
1484
|
+
$modalStack.dismiss(modal.key);
|
1485
|
+
});
|
1486
|
+
}
|
1487
|
+
}
|
1488
|
+
});
|
1489
|
+
|
1490
|
+
$modalStack.open = function (modalInstance, modal) {
|
1491
|
+
|
1492
|
+
openedWindows.add(modalInstance, {
|
1493
|
+
deferred: modal.deferred,
|
1494
|
+
modalScope: modal.scope,
|
1495
|
+
backdrop: modal.backdrop,
|
1496
|
+
keyboard: modal.keyboard
|
1497
|
+
});
|
1498
|
+
|
1499
|
+
var angularDomEl = angular.element('<div modal-window></div>');
|
1500
|
+
angularDomEl.attr('window-class', modal.windowClass);
|
1501
|
+
angularDomEl.attr('index', openedWindows.length() - 1);
|
1502
|
+
angularDomEl.html(modal.content);
|
1503
|
+
|
1504
|
+
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
1505
|
+
openedWindows.top().value.modalDomEl = modalDomEl;
|
1506
|
+
body.append(modalDomEl);
|
1507
|
+
|
1508
|
+
if (backdropIndex() >= 0 && !backdropDomEl) {
|
1509
|
+
backdropjqLiteEl = angular.element('<div modal-backdrop></div>');
|
1510
|
+
backdropDomEl = $compile(backdropjqLiteEl)(backdropScope);
|
1511
|
+
body.append(backdropDomEl);
|
1512
|
+
}
|
1513
|
+
};
|
1514
|
+
|
1515
|
+
$modalStack.close = function (modalInstance, result) {
|
1516
|
+
var modal = openedWindows.get(modalInstance);
|
1517
|
+
if (modal) {
|
1518
|
+
modal.value.deferred.resolve(result);
|
1519
|
+
removeModalWindow(modalInstance);
|
1520
|
+
}
|
1521
|
+
};
|
1522
|
+
|
1523
|
+
$modalStack.dismiss = function (modalInstance, reason) {
|
1524
|
+
var modalWindow = openedWindows.get(modalInstance).value;
|
1525
|
+
if (modalWindow) {
|
1526
|
+
modalWindow.deferred.reject(reason);
|
1527
|
+
removeModalWindow(modalInstance);
|
1528
|
+
}
|
1529
|
+
};
|
1530
|
+
|
1531
|
+
$modalStack.getTop = function () {
|
1532
|
+
return openedWindows.top();
|
1533
|
+
};
|
1534
|
+
|
1535
|
+
return $modalStack;
|
1536
|
+
}])
|
1537
|
+
|
1538
|
+
.provider('$modal', function () {
|
1539
|
+
|
1540
|
+
var $modalProvider = {
|
1541
|
+
options: {
|
1542
|
+
backdrop: true, //can be also false or 'static'
|
1543
|
+
keyboard: true
|
1544
|
+
},
|
1545
|
+
$get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
|
1546
|
+
function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
|
1547
|
+
|
1548
|
+
var $modal = {};
|
1549
|
+
|
1550
|
+
function getTemplatePromise(options) {
|
1551
|
+
return options.template ? $q.when(options.template) :
|
1552
|
+
$http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
|
1553
|
+
return result.data;
|
1554
|
+
});
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
function getResolvePromises(resolves) {
|
1558
|
+
var promisesArr = [];
|
1559
|
+
angular.forEach(resolves, function (value, key) {
|
1560
|
+
if (angular.isFunction(value) || angular.isArray(value)) {
|
1561
|
+
promisesArr.push($q.when($injector.invoke(value)));
|
1562
|
+
}
|
1563
|
+
});
|
1564
|
+
return promisesArr;
|
1565
|
+
}
|
1566
|
+
|
1567
|
+
$modal.open = function (modalOptions) {
|
1568
|
+
|
1569
|
+
var modalResultDeferred = $q.defer();
|
1570
|
+
var modalOpenedDeferred = $q.defer();
|
1571
|
+
|
1572
|
+
//prepare an instance of a modal to be injected into controllers and returned to a caller
|
1573
|
+
var modalInstance = {
|
1574
|
+
result: modalResultDeferred.promise,
|
1575
|
+
opened: modalOpenedDeferred.promise,
|
1576
|
+
close: function (result) {
|
1577
|
+
$modalStack.close(modalInstance, result);
|
1578
|
+
},
|
1579
|
+
dismiss: function (reason) {
|
1580
|
+
$modalStack.dismiss(modalInstance, reason);
|
1581
|
+
}
|
1582
|
+
};
|
1583
|
+
|
1584
|
+
//merge and clean up options
|
1585
|
+
modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
|
1586
|
+
modalOptions.resolve = modalOptions.resolve || {};
|
1587
|
+
|
1588
|
+
//verify options
|
1589
|
+
if (!modalOptions.template && !modalOptions.templateUrl) {
|
1590
|
+
throw new Error('One of template or templateUrl options is required.');
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
var templateAndResolvePromise =
|
1594
|
+
$q.all([getTemplatePromise(modalOptions)].concat(getResolvePromises(modalOptions.resolve)));
|
1595
|
+
|
1596
|
+
|
1597
|
+
templateAndResolvePromise.then(function resolveSuccess(tplAndVars) {
|
1598
|
+
|
1599
|
+
var modalScope = (modalOptions.scope || $rootScope).$new();
|
1600
|
+
modalScope.$close = modalInstance.close;
|
1601
|
+
modalScope.$dismiss = modalInstance.dismiss;
|
1602
|
+
|
1603
|
+
var ctrlInstance, ctrlLocals = {};
|
1604
|
+
var resolveIter = 1;
|
1605
|
+
|
1606
|
+
//controllers
|
1607
|
+
if (modalOptions.controller) {
|
1608
|
+
ctrlLocals.$scope = modalScope;
|
1609
|
+
ctrlLocals.$modalInstance = modalInstance;
|
1610
|
+
angular.forEach(modalOptions.resolve, function (value, key) {
|
1611
|
+
ctrlLocals[key] = tplAndVars[resolveIter++];
|
1612
|
+
});
|
1613
|
+
|
1614
|
+
ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
$modalStack.open(modalInstance, {
|
1618
|
+
scope: modalScope,
|
1619
|
+
deferred: modalResultDeferred,
|
1620
|
+
content: tplAndVars[0],
|
1621
|
+
backdrop: modalOptions.backdrop,
|
1622
|
+
keyboard: modalOptions.keyboard,
|
1623
|
+
windowClass: modalOptions.windowClass
|
1624
|
+
});
|
1625
|
+
|
1626
|
+
}, function resolveError(reason) {
|
1627
|
+
modalResultDeferred.reject(reason);
|
1628
|
+
});
|
1629
|
+
|
1630
|
+
templateAndResolvePromise.then(function () {
|
1631
|
+
modalOpenedDeferred.resolve(true);
|
1632
|
+
}, function () {
|
1633
|
+
modalOpenedDeferred.reject(false);
|
1634
|
+
});
|
1635
|
+
|
1636
|
+
return modalInstance;
|
1637
|
+
};
|
1638
|
+
|
1639
|
+
return $modal;
|
1640
|
+
}]
|
1641
|
+
};
|
1642
|
+
|
1643
|
+
return $modalProvider;
|
1644
|
+
});
|
1644
1645
|
angular.module('ui.bootstrap.pagination', [])
|
1645
1646
|
|
1646
|
-
.controller('PaginationController', ['$scope', '$interpolate', function ($scope, $interpolate) {
|
1647
|
+
.controller('PaginationController', ['$scope', '$attrs', '$parse', '$interpolate', function ($scope, $attrs, $parse, $interpolate) {
|
1648
|
+
var self = this;
|
1647
1649
|
|
1648
|
-
this.
|
1650
|
+
this.init = function(defaultItemsPerPage) {
|
1651
|
+
if ($attrs.itemsPerPage) {
|
1652
|
+
$scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
|
1653
|
+
self.itemsPerPage = parseInt(value, 10);
|
1654
|
+
$scope.totalPages = self.calculateTotalPages();
|
1655
|
+
});
|
1656
|
+
} else {
|
1657
|
+
this.itemsPerPage = defaultItemsPerPage;
|
1658
|
+
}
|
1659
|
+
};
|
1649
1660
|
|
1650
1661
|
this.noPrevious = function() {
|
1651
|
-
return this.
|
1662
|
+
return this.page === 1;
|
1652
1663
|
};
|
1653
1664
|
this.noNext = function() {
|
1654
|
-
return this.
|
1665
|
+
return this.page === $scope.totalPages;
|
1655
1666
|
};
|
1656
1667
|
|
1657
1668
|
this.isActive = function(page) {
|
1658
|
-
return this.
|
1669
|
+
return this.page === page;
|
1659
1670
|
};
|
1660
1671
|
|
1661
|
-
this.
|
1662
|
-
$scope.
|
1663
|
-
|
1672
|
+
this.calculateTotalPages = function() {
|
1673
|
+
return this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
|
1674
|
+
};
|
1664
1675
|
|
1665
|
-
|
1666
|
-
|
1667
|
-
|
1676
|
+
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
|
1677
|
+
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
|
1678
|
+
};
|
1679
|
+
|
1680
|
+
this.render = function() {
|
1681
|
+
this.page = parseInt($scope.page, 10) || 1;
|
1682
|
+
$scope.pages = this.getPages(this.page, $scope.totalPages);
|
1668
1683
|
};
|
1669
1684
|
|
1670
|
-
var self = this;
|
1671
1685
|
$scope.selectPage = function(page) {
|
1672
|
-
if ( ! self.isActive(page) && page > 0 && page <= $scope.
|
1673
|
-
$scope.
|
1686
|
+
if ( ! self.isActive(page) && page > 0 && page <= $scope.totalPages) {
|
1687
|
+
$scope.page = page;
|
1674
1688
|
$scope.onSelectPage({ page: page });
|
1675
1689
|
}
|
1676
1690
|
};
|
1677
1691
|
|
1678
|
-
|
1679
|
-
|
1680
|
-
};
|
1692
|
+
$scope.$watch('totalItems', function() {
|
1693
|
+
$scope.totalPages = self.calculateTotalPages();
|
1694
|
+
});
|
1695
|
+
|
1696
|
+
$scope.$watch('totalPages', function(value) {
|
1697
|
+
if ( $attrs.numPages ) {
|
1698
|
+
$scope.numPages = value; // Readonly variable
|
1699
|
+
}
|
1700
|
+
|
1701
|
+
if ( self.page > value ) {
|
1702
|
+
$scope.selectPage(value);
|
1703
|
+
} else {
|
1704
|
+
self.render();
|
1705
|
+
}
|
1706
|
+
});
|
1707
|
+
|
1708
|
+
$scope.$watch('page', function() {
|
1709
|
+
self.render();
|
1710
|
+
});
|
1681
1711
|
}])
|
1682
1712
|
|
1683
1713
|
.constant('paginationConfig', {
|
1714
|
+
itemsPerPage: 10,
|
1684
1715
|
boundaryLinks: false,
|
1685
1716
|
directionLinks: true,
|
1686
1717
|
firstText: 'First',
|
@@ -1690,14 +1721,14 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1690
1721
|
rotate: true
|
1691
1722
|
})
|
1692
1723
|
|
1693
|
-
.directive('pagination', ['paginationConfig', function(config) {
|
1724
|
+
.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
|
1694
1725
|
return {
|
1695
1726
|
restrict: 'EA',
|
1696
1727
|
scope: {
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1728
|
+
page: '=',
|
1729
|
+
totalItems: '=',
|
1730
|
+
onSelectPage:' &',
|
1731
|
+
numPages: '='
|
1701
1732
|
},
|
1702
1733
|
controller: 'PaginationController',
|
1703
1734
|
templateUrl: 'template/pagination/pagination.html',
|
@@ -1705,13 +1736,23 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1705
1736
|
link: function(scope, element, attrs, paginationCtrl) {
|
1706
1737
|
|
1707
1738
|
// Setup configuration parameters
|
1708
|
-
var
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1712
|
-
|
1713
|
-
|
1714
|
-
|
1739
|
+
var maxSize,
|
1740
|
+
boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks ),
|
1741
|
+
directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks ),
|
1742
|
+
firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true),
|
1743
|
+
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
1744
|
+
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1745
|
+
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
|
1746
|
+
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
|
1747
|
+
|
1748
|
+
paginationCtrl.init(config.itemsPerPage);
|
1749
|
+
|
1750
|
+
if (attrs.maxSize) {
|
1751
|
+
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
|
1752
|
+
maxSize = parseInt(value, 10);
|
1753
|
+
paginationCtrl.render();
|
1754
|
+
});
|
1755
|
+
}
|
1715
1756
|
|
1716
1757
|
// Create page object used in template
|
1717
1758
|
function makePage(number, text, isActive, isDisabled) {
|
@@ -1723,76 +1764,79 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1723
1764
|
};
|
1724
1765
|
}
|
1725
1766
|
|
1726
|
-
|
1727
|
-
|
1767
|
+
paginationCtrl.getPages = function(currentPage, totalPages) {
|
1768
|
+
var pages = [];
|
1728
1769
|
|
1729
1770
|
// Default page limits
|
1730
|
-
var startPage = 1, endPage =
|
1731
|
-
var isMaxSized = ( angular.isDefined(
|
1771
|
+
var startPage = 1, endPage = totalPages;
|
1772
|
+
var isMaxSized = ( angular.isDefined(maxSize) && maxSize < totalPages );
|
1732
1773
|
|
1733
1774
|
// recompute if maxSize
|
1734
1775
|
if ( isMaxSized ) {
|
1735
1776
|
if ( rotate ) {
|
1736
1777
|
// Current page is displayed in the middle of the visible ones
|
1737
|
-
startPage = Math.max(
|
1738
|
-
endPage = startPage +
|
1778
|
+
startPage = Math.max(currentPage - Math.floor(maxSize/2), 1);
|
1779
|
+
endPage = startPage + maxSize - 1;
|
1739
1780
|
|
1740
1781
|
// Adjust if limit is exceeded
|
1741
|
-
if (endPage >
|
1742
|
-
endPage =
|
1743
|
-
startPage = endPage -
|
1782
|
+
if (endPage > totalPages) {
|
1783
|
+
endPage = totalPages;
|
1784
|
+
startPage = endPage - maxSize + 1;
|
1744
1785
|
}
|
1745
1786
|
} else {
|
1746
1787
|
// Visible pages are paginated with maxSize
|
1747
|
-
startPage = ((Math.ceil(
|
1788
|
+
startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1;
|
1748
1789
|
|
1749
1790
|
// Adjust last page if limit is exceeded
|
1750
|
-
endPage = Math.min(startPage +
|
1791
|
+
endPage = Math.min(startPage + maxSize - 1, totalPages);
|
1751
1792
|
}
|
1752
1793
|
}
|
1753
1794
|
|
1754
1795
|
// Add page number links
|
1755
1796
|
for (var number = startPage; number <= endPage; number++) {
|
1756
1797
|
var page = makePage(number, number, paginationCtrl.isActive(number), false);
|
1757
|
-
|
1798
|
+
pages.push(page);
|
1758
1799
|
}
|
1759
1800
|
|
1760
1801
|
// Add links to move between page sets
|
1761
1802
|
if ( isMaxSized && ! rotate ) {
|
1762
1803
|
if ( startPage > 1 ) {
|
1763
1804
|
var previousPageSet = makePage(startPage - 1, '...', false, false);
|
1764
|
-
|
1805
|
+
pages.unshift(previousPageSet);
|
1765
1806
|
}
|
1766
1807
|
|
1767
|
-
if ( endPage <
|
1808
|
+
if ( endPage < totalPages ) {
|
1768
1809
|
var nextPageSet = makePage(endPage + 1, '...', false, false);
|
1769
|
-
|
1810
|
+
pages.push(nextPageSet);
|
1770
1811
|
}
|
1771
1812
|
}
|
1772
1813
|
|
1773
1814
|
// Add previous & next links
|
1774
1815
|
if (directionLinks) {
|
1775
|
-
var previousPage = makePage(
|
1776
|
-
|
1816
|
+
var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
|
1817
|
+
pages.unshift(previousPage);
|
1777
1818
|
|
1778
|
-
var nextPage = makePage(
|
1779
|
-
|
1819
|
+
var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
|
1820
|
+
pages.push(nextPage);
|
1780
1821
|
}
|
1781
1822
|
|
1782
1823
|
// Add first & last links
|
1783
1824
|
if (boundaryLinks) {
|
1784
1825
|
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
|
1785
|
-
|
1826
|
+
pages.unshift(firstPage);
|
1786
1827
|
|
1787
|
-
var lastPage = makePage(
|
1788
|
-
|
1828
|
+
var lastPage = makePage(totalPages, lastText, false, paginationCtrl.noNext());
|
1829
|
+
pages.push(lastPage);
|
1789
1830
|
}
|
1790
|
-
|
1831
|
+
|
1832
|
+
return pages;
|
1833
|
+
};
|
1791
1834
|
}
|
1792
1835
|
};
|
1793
1836
|
}])
|
1794
1837
|
|
1795
1838
|
.constant('pagerConfig', {
|
1839
|
+
itemsPerPage: 10,
|
1796
1840
|
previousText: '« Previous',
|
1797
1841
|
nextText: 'Next »',
|
1798
1842
|
align: true
|
@@ -1802,9 +1846,10 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1802
1846
|
return {
|
1803
1847
|
restrict: 'EA',
|
1804
1848
|
scope: {
|
1805
|
-
|
1806
|
-
|
1807
|
-
onSelectPage:
|
1849
|
+
page: '=',
|
1850
|
+
totalItems: '=',
|
1851
|
+
onSelectPage:' &',
|
1852
|
+
numPages: '='
|
1808
1853
|
},
|
1809
1854
|
controller: 'PaginationController',
|
1810
1855
|
templateUrl: 'template/pagination/pager.html',
|
@@ -1816,6 +1861,8 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1816
1861
|
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1817
1862
|
align = paginationCtrl.getAttributeValue(attrs.align, config.align);
|
1818
1863
|
|
1864
|
+
paginationCtrl.init(config.itemsPerPage);
|
1865
|
+
|
1819
1866
|
// Create page object used in template
|
1820
1867
|
function makePage(number, text, isDisabled, isPrevious, isNext) {
|
1821
1868
|
return {
|
@@ -1827,16 +1874,12 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1827
1874
|
};
|
1828
1875
|
}
|
1829
1876
|
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
var nextPage = makePage(paginationCtrl.currentPage + 1, nextText, paginationCtrl.noNext(), false, true);
|
1838
|
-
scope.pages.push(nextPage);
|
1839
|
-
});
|
1877
|
+
paginationCtrl.getPages = function(currentPage) {
|
1878
|
+
return [
|
1879
|
+
makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
|
1880
|
+
makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
|
1881
|
+
];
|
1882
|
+
};
|
1840
1883
|
}
|
1841
1884
|
};
|
1842
1885
|
}]);
|
@@ -1846,7 +1889,7 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1846
1889
|
* function, placement as a function, inside, support for more triggers than
|
1847
1890
|
* just mouse enter/leave, html tooltips, and selector delegation.
|
1848
1891
|
*/
|
1849
|
-
angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
1892
|
+
angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap.bindHtml' ] )
|
1850
1893
|
|
1851
1894
|
/**
|
1852
1895
|
* The $tooltip service creates tooltip- and popover-like directives as well as
|
@@ -2027,13 +2070,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
2027
2070
|
// Calculate the tooltip's top and left coordinates to center it with
|
2028
2071
|
// this directive.
|
2029
2072
|
switch ( scope.tt_placement ) {
|
2030
|
-
case 'mouse':
|
2031
|
-
var mousePos = $position.mouse();
|
2032
|
-
ttPosition = {
|
2033
|
-
top: mousePos.y,
|
2034
|
-
left: mousePos.x
|
2035
|
-
};
|
2036
|
-
break;
|
2037
2073
|
case 'right':
|
2038
2074
|
ttPosition = {
|
2039
2075
|
top: position.top + position.height / 2 - ttHeight / 2,
|
@@ -2314,60 +2350,86 @@ angular.module('ui.bootstrap.progressbar', ['ui.bootstrap.transition'])
|
|
2314
2350
|
angular.module('ui.bootstrap.rating', [])
|
2315
2351
|
|
2316
2352
|
.constant('ratingConfig', {
|
2317
|
-
max: 5
|
2353
|
+
max: 5,
|
2354
|
+
stateOn: null,
|
2355
|
+
stateOff: null
|
2318
2356
|
})
|
2319
2357
|
|
2320
|
-
.
|
2321
|
-
return {
|
2322
|
-
restrict: 'EA',
|
2323
|
-
scope: {
|
2324
|
-
value: '=',
|
2325
|
-
onHover: '&',
|
2326
|
-
onLeave: '&'
|
2327
|
-
},
|
2328
|
-
templateUrl: 'template/rating/rating.html',
|
2329
|
-
replace: true,
|
2330
|
-
link: function(scope, element, attrs) {
|
2358
|
+
.controller('RatingController', ['$scope', '$attrs', '$parse', 'ratingConfig', function($scope, $attrs, $parse, ratingConfig) {
|
2331
2359
|
|
2332
|
-
|
2360
|
+
this.maxRange = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : ratingConfig.max;
|
2361
|
+
this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
|
2362
|
+
this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
|
2333
2363
|
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2364
|
+
this.createDefaultRange = function(len) {
|
2365
|
+
var defaultStateObject = {
|
2366
|
+
stateOn: this.stateOn,
|
2367
|
+
stateOff: this.stateOff
|
2368
|
+
};
|
2338
2369
|
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2370
|
+
var states = new Array(len);
|
2371
|
+
for (var i = 0; i < len; i++) {
|
2372
|
+
states[i] = defaultStateObject;
|
2373
|
+
}
|
2374
|
+
return states;
|
2375
|
+
};
|
2344
2376
|
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2377
|
+
this.normalizeRange = function(states) {
|
2378
|
+
for (var i = 0, n = states.length; i < n; i++) {
|
2379
|
+
states[i].stateOn = states[i].stateOn || this.stateOn;
|
2380
|
+
states[i].stateOff = states[i].stateOff || this.stateOff;
|
2381
|
+
}
|
2382
|
+
return states;
|
2383
|
+
};
|
2351
2384
|
|
2352
|
-
|
2353
|
-
|
2354
|
-
scope.onLeave();
|
2355
|
-
};
|
2356
|
-
scope.reset();
|
2385
|
+
// Get objects used in template
|
2386
|
+
$scope.range = angular.isDefined($attrs.ratingStates) ? this.normalizeRange(angular.copy($scope.$parent.$eval($attrs.ratingStates))): this.createDefaultRange(this.maxRange);
|
2357
2387
|
|
2358
|
-
|
2359
|
-
|
2360
|
-
|
2388
|
+
$scope.rate = function(value) {
|
2389
|
+
if ( $scope.readonly || $scope.value === value) {
|
2390
|
+
return;
|
2391
|
+
}
|
2361
2392
|
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2393
|
+
$scope.value = value;
|
2394
|
+
};
|
2395
|
+
|
2396
|
+
$scope.enter = function(value) {
|
2397
|
+
if ( ! $scope.readonly ) {
|
2398
|
+
$scope.val = value;
|
2368
2399
|
}
|
2400
|
+
$scope.onHover({value: value});
|
2369
2401
|
};
|
2370
|
-
|
2402
|
+
|
2403
|
+
$scope.reset = function() {
|
2404
|
+
$scope.val = angular.copy($scope.value);
|
2405
|
+
$scope.onLeave();
|
2406
|
+
};
|
2407
|
+
|
2408
|
+
$scope.$watch('value', function(value) {
|
2409
|
+
$scope.val = value;
|
2410
|
+
});
|
2411
|
+
|
2412
|
+
$scope.readonly = false;
|
2413
|
+
if ($attrs.readonly) {
|
2414
|
+
$scope.$parent.$watch($parse($attrs.readonly), function(value) {
|
2415
|
+
$scope.readonly = !!value;
|
2416
|
+
});
|
2417
|
+
}
|
2418
|
+
}])
|
2419
|
+
|
2420
|
+
.directive('rating', function() {
|
2421
|
+
return {
|
2422
|
+
restrict: 'EA',
|
2423
|
+
scope: {
|
2424
|
+
value: '=',
|
2425
|
+
onHover: '&',
|
2426
|
+
onLeave: '&'
|
2427
|
+
},
|
2428
|
+
controller: 'RatingController',
|
2429
|
+
templateUrl: 'template/rating/rating.html',
|
2430
|
+
replace: true
|
2431
|
+
};
|
2432
|
+
});
|
2371
2433
|
|
2372
2434
|
/**
|
2373
2435
|
* @ngdoc overview
|
@@ -2455,7 +2517,7 @@ function TabsetCtrl($scope, $element) {
|
|
2455
2517
|
templateUrl: 'template/tabs/tabset.html',
|
2456
2518
|
compile: function(elm, attrs, transclude) {
|
2457
2519
|
return function(scope, element, attrs, tabsetCtrl) {
|
2458
|
-
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
|
2520
|
+
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false;
|
2459
2521
|
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
|
2460
2522
|
scope.direction = angular.isDefined(attrs.direction) ? scope.$parent.$eval(attrs.direction) : 'top';
|
2461
2523
|
scope.tabsAbove = (scope.direction != 'below');
|
@@ -2663,7 +2725,7 @@ function($parse, $http, $templateCache, $compile) {
|
|
2663
2725
|
}
|
2664
2726
|
}])
|
2665
2727
|
|
2666
|
-
.directive('tabsetTitles', function($http) {
|
2728
|
+
.directive('tabsetTitles', ['$http', function($http) {
|
2667
2729
|
return {
|
2668
2730
|
restrict: 'A',
|
2669
2731
|
require: '^tabset',
|
@@ -2680,22 +2742,13 @@ function($parse, $http, $templateCache, $compile) {
|
|
2680
2742
|
}
|
2681
2743
|
}
|
2682
2744
|
};
|
2683
|
-
})
|
2745
|
+
}])
|
2684
2746
|
|
2685
2747
|
;
|
2686
2748
|
|
2687
2749
|
|
2688
2750
|
angular.module('ui.bootstrap.timepicker', [])
|
2689
2751
|
|
2690
|
-
.filter('pad', function() {
|
2691
|
-
return function(input) {
|
2692
|
-
if ( angular.isDefined(input) && input.toString().length < 2 ) {
|
2693
|
-
input = '0' + input;
|
2694
|
-
}
|
2695
|
-
return input;
|
2696
|
-
};
|
2697
|
-
})
|
2698
|
-
|
2699
2752
|
.constant('timepickerConfig', {
|
2700
2753
|
hourStep: 1,
|
2701
2754
|
minuteStep: 1,
|
@@ -2705,16 +2758,18 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2705
2758
|
mousewheel: true
|
2706
2759
|
})
|
2707
2760
|
|
2708
|
-
.directive('timepicker', ['
|
2761
|
+
.directive('timepicker', ['$parse', '$log', 'timepickerConfig', function ($parse, $log, timepickerConfig) {
|
2709
2762
|
return {
|
2710
2763
|
restrict: 'EA',
|
2711
|
-
require:'ngModel',
|
2764
|
+
require:'?^ngModel',
|
2712
2765
|
replace: true,
|
2766
|
+
scope: {},
|
2713
2767
|
templateUrl: 'template/timepicker/timepicker.html',
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2768
|
+
link: function(scope, element, attrs, ngModel) {
|
2769
|
+
if ( !ngModel ) {
|
2770
|
+
return; // do nothing if no ng-model
|
2771
|
+
}
|
2772
|
+
|
2718
2773
|
var selected = new Date(), meridians = timepickerConfig.meridians;
|
2719
2774
|
|
2720
2775
|
var hourStep = timepickerConfig.hourStep;
|
@@ -2735,28 +2790,27 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2735
2790
|
scope.showMeridian = timepickerConfig.showMeridian;
|
2736
2791
|
if (attrs.showMeridian) {
|
2737
2792
|
scope.$parent.$watch($parse(attrs.showMeridian), function(value) {
|
2738
|
-
scope.showMeridian = !!
|
2739
|
-
|
2740
|
-
if (
|
2741
|
-
//
|
2742
|
-
var
|
2743
|
-
|
2744
|
-
|
2745
|
-
|
2793
|
+
scope.showMeridian = !!value;
|
2794
|
+
|
2795
|
+
if ( ngModel.$error.time ) {
|
2796
|
+
// Evaluate from template
|
2797
|
+
var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate();
|
2798
|
+
if (angular.isDefined( hours ) && angular.isDefined( minutes )) {
|
2799
|
+
selected.setHours( hours );
|
2800
|
+
refresh();
|
2746
2801
|
}
|
2747
|
-
scope.model = new Date( dt );
|
2748
2802
|
} else {
|
2749
|
-
|
2803
|
+
updateTemplate();
|
2750
2804
|
}
|
2751
2805
|
});
|
2752
2806
|
}
|
2753
2807
|
|
2754
2808
|
// Get scope.hours in 24H mode if valid
|
2755
|
-
function
|
2809
|
+
function getHoursFromTemplate ( ) {
|
2756
2810
|
var hours = parseInt( scope.hours, 10 );
|
2757
2811
|
var valid = ( scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24);
|
2758
2812
|
if ( !valid ) {
|
2759
|
-
return;
|
2813
|
+
return undefined;
|
2760
2814
|
}
|
2761
2815
|
|
2762
2816
|
if ( scope.showMeridian ) {
|
@@ -2770,14 +2824,22 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2770
2824
|
return hours;
|
2771
2825
|
}
|
2772
2826
|
|
2827
|
+
function getMinutesFromTemplate() {
|
2828
|
+
var minutes = parseInt(scope.minutes, 10);
|
2829
|
+
return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined;
|
2830
|
+
}
|
2831
|
+
|
2832
|
+
function pad( value ) {
|
2833
|
+
return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
|
2834
|
+
}
|
2835
|
+
|
2773
2836
|
// Input elements
|
2774
|
-
var inputs = element.find('input');
|
2775
|
-
var hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
|
2837
|
+
var inputs = element.find('input'), hoursInputEl = inputs.eq(0), minutesInputEl = inputs.eq(1);
|
2776
2838
|
|
2777
2839
|
// Respond on mousewheel spin
|
2778
2840
|
var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
|
2779
2841
|
if ( mousewheel ) {
|
2780
|
-
|
2842
|
+
|
2781
2843
|
var isScrollingUp = function(e) {
|
2782
2844
|
if (e.originalEvent) {
|
2783
2845
|
e = e.originalEvent;
|
@@ -2786,7 +2848,7 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2786
2848
|
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
|
2787
2849
|
return (e.detail || delta > 0);
|
2788
2850
|
};
|
2789
|
-
|
2851
|
+
|
2790
2852
|
hoursInputEl.bind('mousewheel wheel', function(e) {
|
2791
2853
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
|
2792
2854
|
e.preventDefault();
|
@@ -2798,50 +2860,54 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2798
2860
|
});
|
2799
2861
|
}
|
2800
2862
|
|
2801
|
-
var keyboardChange = false;
|
2802
2863
|
scope.readonlyInput = (angular.isDefined(attrs.readonlyInput)) ? scope.$eval(attrs.readonlyInput) : timepickerConfig.readonlyInput;
|
2803
2864
|
if ( ! scope.readonlyInput ) {
|
2865
|
+
|
2866
|
+
var invalidate = function(invalidHours, invalidMinutes) {
|
2867
|
+
ngModel.$setViewValue( null );
|
2868
|
+
ngModel.$setValidity('time', false);
|
2869
|
+
if (angular.isDefined(invalidHours)) {
|
2870
|
+
scope.invalidHours = invalidHours;
|
2871
|
+
}
|
2872
|
+
if (angular.isDefined(invalidMinutes)) {
|
2873
|
+
scope.invalidMinutes = invalidMinutes;
|
2874
|
+
}
|
2875
|
+
};
|
2876
|
+
|
2804
2877
|
scope.updateHours = function() {
|
2805
|
-
var hours =
|
2878
|
+
var hours = getHoursFromTemplate();
|
2806
2879
|
|
2807
2880
|
if ( angular.isDefined(hours) ) {
|
2808
|
-
|
2809
|
-
|
2810
|
-
scope.model = new Date( selected );
|
2811
|
-
}
|
2812
|
-
scope.model.setHours( hours );
|
2881
|
+
selected.setHours( hours );
|
2882
|
+
refresh( 'h' );
|
2813
2883
|
} else {
|
2814
|
-
|
2815
|
-
scope.validHours = false;
|
2884
|
+
invalidate(true);
|
2816
2885
|
}
|
2817
2886
|
};
|
2818
2887
|
|
2819
2888
|
hoursInputEl.bind('blur', function(e) {
|
2820
|
-
if ( scope.validHours && scope.hours < 10) {
|
2889
|
+
if ( !scope.validHours && scope.hours < 10) {
|
2821
2890
|
scope.$apply( function() {
|
2822
|
-
scope.hours =
|
2891
|
+
scope.hours = pad( scope.hours );
|
2823
2892
|
});
|
2824
2893
|
}
|
2825
2894
|
});
|
2826
2895
|
|
2827
2896
|
scope.updateMinutes = function() {
|
2828
|
-
var minutes =
|
2829
|
-
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
}
|
2834
|
-
scope.model.setMinutes( minutes );
|
2897
|
+
var minutes = getMinutesFromTemplate();
|
2898
|
+
|
2899
|
+
if ( angular.isDefined(minutes) ) {
|
2900
|
+
selected.setMinutes( minutes );
|
2901
|
+
refresh( 'm' );
|
2835
2902
|
} else {
|
2836
|
-
|
2837
|
-
scope.validMinutes = false;
|
2903
|
+
invalidate(undefined, true);
|
2838
2904
|
}
|
2839
2905
|
};
|
2840
2906
|
|
2841
2907
|
minutesInputEl.bind('blur', function(e) {
|
2842
|
-
if ( scope.
|
2908
|
+
if ( !scope.invalidMinutes && scope.minutes < 10 ) {
|
2843
2909
|
scope.$apply( function() {
|
2844
|
-
scope.minutes =
|
2910
|
+
scope.minutes = pad( scope.minutes );
|
2845
2911
|
});
|
2846
2912
|
}
|
2847
2913
|
});
|
@@ -2850,38 +2916,49 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2850
2916
|
scope.updateMinutes = angular.noop;
|
2851
2917
|
}
|
2852
2918
|
|
2853
|
-
|
2854
|
-
|
2855
|
-
}, function( timestamp ) {
|
2856
|
-
if ( !isNaN( timestamp ) && timestamp > 0 ) {
|
2857
|
-
selected = new Date( timestamp );
|
2858
|
-
refreshTemplate();
|
2859
|
-
}
|
2860
|
-
});
|
2919
|
+
ngModel.$render = function() {
|
2920
|
+
var date = ngModel.$modelValue ? new Date( ngModel.$modelValue ) : null;
|
2861
2921
|
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2922
|
+
if ( isNaN(date) ) {
|
2923
|
+
ngModel.$setValidity('time', false);
|
2924
|
+
$log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.');
|
2925
|
+
} else {
|
2926
|
+
if ( date ) {
|
2927
|
+
selected = date;
|
2928
|
+
}
|
2929
|
+
makeValid();
|
2930
|
+
updateTemplate();
|
2867
2931
|
}
|
2868
|
-
|
2869
|
-
scope.validHours = true;
|
2932
|
+
};
|
2870
2933
|
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
2934
|
+
// Call internally when we know that model is valid.
|
2935
|
+
function refresh( keyboardChange ) {
|
2936
|
+
makeValid();
|
2937
|
+
ngModel.$setViewValue( new Date(selected) );
|
2938
|
+
updateTemplate( keyboardChange );
|
2939
|
+
}
|
2874
2940
|
|
2875
|
-
|
2941
|
+
function makeValid() {
|
2942
|
+
ngModel.$setValidity('time', true);
|
2943
|
+
scope.invalidHours = false;
|
2944
|
+
scope.invalidMinutes = false;
|
2945
|
+
}
|
2946
|
+
|
2947
|
+
function updateTemplate( keyboardChange ) {
|
2948
|
+
var hours = selected.getHours(), minutes = selected.getMinutes();
|
2876
2949
|
|
2877
|
-
|
2950
|
+
if ( scope.showMeridian ) {
|
2951
|
+
hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system
|
2952
|
+
}
|
2953
|
+
scope.hours = keyboardChange === 'h' ? hours : pad(hours);
|
2954
|
+
scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
|
2955
|
+
scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
|
2878
2956
|
}
|
2879
2957
|
|
2880
2958
|
function addMinutes( minutes ) {
|
2881
2959
|
var dt = new Date( selected.getTime() + minutes * 60000 );
|
2882
|
-
selected.setHours( dt.getHours() );
|
2883
|
-
|
2884
|
-
scope.model = new Date( selected );
|
2960
|
+
selected.setHours( dt.getHours(), dt.getMinutes() );
|
2961
|
+
refresh();
|
2885
2962
|
}
|
2886
2963
|
|
2887
2964
|
scope.incrementHours = function() {
|
@@ -2903,7 +2980,7 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2903
2980
|
};
|
2904
2981
|
}]);
|
2905
2982
|
|
2906
|
-
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
2983
|
+
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
|
2907
2984
|
|
2908
2985
|
/**
|
2909
2986
|
* A helper service that can parse typeahead's syntax (string provided by users)
|
@@ -2934,7 +3011,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2934
3011
|
};
|
2935
3012
|
}])
|
2936
3013
|
|
2937
|
-
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
|
3014
|
+
.directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser',
|
3015
|
+
function ($compile, $parse, $q, $timeout, $document, $position, typeaheadParser) {
|
2938
3016
|
|
2939
3017
|
var HOT_KEYS = [9, 13, 27, 38, 40];
|
2940
3018
|
|
@@ -3047,7 +3125,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3047
3125
|
|
3048
3126
|
//plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
|
3049
3127
|
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
|
3050
|
-
modelCtrl.$parsers.
|
3128
|
+
modelCtrl.$parsers.unshift(function (inputValue) {
|
3051
3129
|
|
3052
3130
|
resetMatches();
|
3053
3131
|
if (inputValue && inputValue.length >= minSearch) {
|
@@ -3063,7 +3141,12 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3063
3141
|
}
|
3064
3142
|
}
|
3065
3143
|
|
3066
|
-
|
3144
|
+
if (isEditable) {
|
3145
|
+
return inputValue;
|
3146
|
+
} else {
|
3147
|
+
modelCtrl.$setValidity('editable', false);
|
3148
|
+
return undefined;
|
3149
|
+
}
|
3067
3150
|
});
|
3068
3151
|
|
3069
3152
|
modelCtrl.$formatters.push(function (modelValue) {
|
@@ -3077,12 +3160,13 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3077
3160
|
return inputFormatter(originalScope, locals);
|
3078
3161
|
|
3079
3162
|
} else {
|
3080
|
-
locals[parserResult.itemName] = modelValue;
|
3081
3163
|
|
3082
3164
|
//it might happen that we don't have enough info to properly render input value
|
3083
3165
|
//we need to check for this situation and simply return model value if we can't apply custom formatting
|
3166
|
+
locals[parserResult.itemName] = modelValue;
|
3084
3167
|
candidateViewValue = parserResult.viewMapper(originalScope, locals);
|
3085
|
-
|
3168
|
+
locals[parserResult.itemName] = undefined;
|
3169
|
+
emptyViewValue = parserResult.viewMapper(originalScope, locals);
|
3086
3170
|
|
3087
3171
|
return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue;
|
3088
3172
|
}
|
@@ -3096,6 +3180,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3096
3180
|
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
|
3097
3181
|
model = parserResult.modelMapper(originalScope, locals);
|
3098
3182
|
$setModelValue(originalScope, model);
|
3183
|
+
modelCtrl.$setValidity('editable', true);
|
3099
3184
|
|
3100
3185
|
onSelectCallback(originalScope, {
|
3101
3186
|
$item: item,
|
@@ -3103,8 +3188,9 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3103
3188
|
$label: parserResult.viewMapper(originalScope, locals)
|
3104
3189
|
});
|
3105
3190
|
|
3106
|
-
//return focus to the input element if a mach was selected via a mouse click event
|
3107
3191
|
resetMatches();
|
3192
|
+
|
3193
|
+
//return focus to the input element if a mach was selected via a mouse click event
|
3108
3194
|
element[0].focus();
|
3109
3195
|
};
|
3110
3196
|
|
@@ -3139,9 +3225,18 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3139
3225
|
}
|
3140
3226
|
});
|
3141
3227
|
|
3142
|
-
|
3143
|
-
|
3144
|
-
|
3228
|
+
// Keep reference to click handler to unbind it.
|
3229
|
+
var dismissClickHandler = function (evt) {
|
3230
|
+
if (element[0] !== evt.target) {
|
3231
|
+
resetMatches();
|
3232
|
+
scope.$digest();
|
3233
|
+
}
|
3234
|
+
};
|
3235
|
+
|
3236
|
+
$document.bind('click', dismissClickHandler);
|
3237
|
+
|
3238
|
+
originalScope.$on('$destroy', function(){
|
3239
|
+
$document.unbind('click', dismissClickHandler);
|
3145
3240
|
});
|
3146
3241
|
|
3147
3242
|
element.after($compile(popUpEl)(scope));
|
@@ -3209,7 +3304,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
3209
3304
|
}
|
3210
3305
|
|
3211
3306
|
return function(matchItem, query) {
|
3212
|
-
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') :
|
3307
|
+
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
|
3213
3308
|
};
|
3214
3309
|
});
|
3215
3310
|
angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
|
@@ -3302,28 +3397,14 @@ angular.module("template/datepicker/popup.html", []).run(["$templateCache", func
|
|
3302
3397
|
"</ul>");
|
3303
3398
|
}]);
|
3304
3399
|
|
3305
|
-
angular.module("template/dialog/message.html", []).run(["$templateCache", function($templateCache) {
|
3306
|
-
$templateCache.put("template/dialog/message.html",
|
3307
|
-
"<div class=\"modal-header\">\n" +
|
3308
|
-
" <h3>{{ title }}</h3>\n" +
|
3309
|
-
"</div>\n" +
|
3310
|
-
"<div class=\"modal-body\">\n" +
|
3311
|
-
" <p>{{ message }}</p>\n" +
|
3312
|
-
"</div>\n" +
|
3313
|
-
"<div class=\"modal-footer\">\n" +
|
3314
|
-
" <button ng-repeat=\"btn in buttons\" ng-click=\"close(btn.result)\" class=\"btn\" ng-class=\"btn.cssClass\">{{ btn.label }}</button>\n" +
|
3315
|
-
"</div>\n" +
|
3316
|
-
"");
|
3317
|
-
}]);
|
3318
|
-
|
3319
3400
|
angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
|
3320
3401
|
$templateCache.put("template/modal/backdrop.html",
|
3321
|
-
"<div class=\"modal-backdrop fade in\"></div>");
|
3402
|
+
"<div class=\"modal-backdrop fade\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1040 + index*10}\" ng-click=\"close($event)\"></div>");
|
3322
3403
|
}]);
|
3323
3404
|
|
3324
3405
|
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
|
3325
3406
|
$templateCache.put("template/modal/window.html",
|
3326
|
-
"<div class=\"modal in\" ng-transclude></div>");
|
3407
|
+
"<div class=\"modal fade {{ windowClass }}\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10}\" ng-transclude></div>");
|
3327
3408
|
}]);
|
3328
3409
|
|
3329
3410
|
angular.module("template/pagination/pager.html", []).run(["$templateCache", function($templateCache) {
|
@@ -3389,7 +3470,7 @@ angular.module("template/progressbar/progress.html", []).run(["$templateCache",
|
|
3389
3470
|
angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
|
3390
3471
|
$templateCache.put("template/rating/rating.html",
|
3391
3472
|
"<span ng-mouseleave=\"reset()\">\n" +
|
3392
|
-
" <i ng-repeat=\"
|
3473
|
+
" <i ng-repeat=\"r in range\" ng-mouseenter=\"enter($index + 1)\" ng-click=\"rate($index + 1)\" ng-class=\"$index < val && (r.stateOn || 'icon-star') || (r.stateOff || 'icon-star-empty')\"></i>\n" +
|
3393
3474
|
"</span>");
|
3394
3475
|
}]);
|
3395
3476
|
|
@@ -3454,10 +3535,10 @@ angular.module("template/timepicker/timepicker.html", []).run(["$templateCache",
|
|
3454
3535
|
" <td ng-show=\"showMeridian\"></td>\n" +
|
3455
3536
|
" </tr>\n" +
|
3456
3537
|
" <tr>\n" +
|
3457
|
-
" <td class=\"control-group\" ng-class=\"{'error':
|
3538
|
+
" <td class=\"control-group\" ng-class=\"{'error': invalidHours}\"><input type=\"text\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"span1 text-center\" ng-mousewheel=\"incrementHours()\" ng-readonly=\"readonlyInput\" maxlength=\"2\" /></td>\n" +
|
3458
3539
|
" <td>:</td>\n" +
|
3459
|
-
" <td class=\"control-group\" ng-class=\"{'error':
|
3460
|
-
" <td ng-show=\"showMeridian\"><button ng-click=\"toggleMeridian()\" class=\"btn text-center\">{{meridian}}</button></td>\n" +
|
3540
|
+
" <td class=\"control-group\" ng-class=\"{'error': invalidMinutes}\"><input type=\"text\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"span1 text-center\" ng-readonly=\"readonlyInput\" maxlength=\"2\"></td>\n" +
|
3541
|
+
" <td ng-show=\"showMeridian\"><button type=\"button\" ng-click=\"toggleMeridian()\" class=\"btn text-center\">{{meridian}}</button></td>\n" +
|
3461
3542
|
" </tr>\n" +
|
3462
3543
|
" <tr class=\"text-center\">\n" +
|
3463
3544
|
" <td><a ng-click=\"decrementHours()\" class=\"btn btn-link\"><i class=\"icon-chevron-down\"></i></a></td>\n" +
|
@@ -3470,7 +3551,7 @@ angular.module("template/timepicker/timepicker.html", []).run(["$templateCache",
|
|
3470
3551
|
|
3471
3552
|
angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
|
3472
3553
|
$templateCache.put("template/typeahead/typeahead-match.html",
|
3473
|
-
"<a tabindex=\"-1\"
|
3554
|
+
"<a tabindex=\"-1\" bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a>");
|
3474
3555
|
}]);
|
3475
3556
|
|
3476
3557
|
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
|