angular-ui-bootstrap-rails 0.4.0.0 → 0.5.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: 41a0eb3d7f6aa58214fe4456e6d59f881acd73e6
|
4
|
+
data.tar.gz: 5ce4e249235df1ccd64d828b214ee2acf9b123ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1ecdcb8ea3ddb278edffd213e8befdbeafe6c114b8d1e3a33d8d0cd80f3bb9ee9a07ebab0f84072e887989bcf34bf562d6180ba6d508c2d08841edddb42eed5
|
7
|
+
data.tar.gz: 81b75e66f470254abae8c087b6a8fac53531cd2f9129a76977ec311941e86c386a459d63b03906dda4da0b3f9b5f61a6ebc575a3802b187f29dba9644189e2b7
|
@@ -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.buttons","ui.bootstrap.carousel","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/dialog/message.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.html","template/timepicker/timepicker.html","template/typeahead/typeahead.html"]);
|
1
|
+
angular.module("ui.bootstrap", ["ui.bootstrap.tpls", "ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dialog","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/dialog/message.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
|
/**
|
@@ -380,21 +380,25 @@ angular.module('ui.bootstrap.buttons', [])
|
|
380
380
|
require:'ngModel',
|
381
381
|
link:function (scope, element, attrs, ngModelCtrl) {
|
382
382
|
|
383
|
-
|
384
|
-
|
383
|
+
function getTrueValue() {
|
384
|
+
var trueValue = scope.$eval(attrs.btnCheckboxTrue);
|
385
|
+
return angular.isDefined(trueValue) ? trueValue : true;
|
386
|
+
}
|
385
387
|
|
386
|
-
|
387
|
-
|
388
|
+
function getFalseValue() {
|
389
|
+
var falseValue = scope.$eval(attrs.btnCheckboxFalse);
|
390
|
+
return angular.isDefined(falseValue) ? falseValue : false;
|
391
|
+
}
|
388
392
|
|
389
393
|
//model -> UI
|
390
394
|
ngModelCtrl.$render = function () {
|
391
|
-
element.toggleClass(activeClass, angular.equals(ngModelCtrl.$modelValue,
|
395
|
+
element.toggleClass(activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue()));
|
392
396
|
};
|
393
397
|
|
394
398
|
//ui->model
|
395
399
|
element.bind(toggleEvent, function () {
|
396
400
|
scope.$apply(function () {
|
397
|
-
ngModelCtrl.$setViewValue(element.hasClass(activeClass) ?
|
401
|
+
ngModelCtrl.$setViewValue(element.hasClass(activeClass) ? getFalseValue() : getTrueValue());
|
398
402
|
ngModelCtrl.$render();
|
399
403
|
});
|
400
404
|
});
|
@@ -733,7 +737,101 @@ function CarouselDemoCtrl($scope) {
|
|
733
737
|
};
|
734
738
|
}]);
|
735
739
|
|
736
|
-
angular.module('ui.bootstrap.
|
740
|
+
angular.module('ui.bootstrap.position', [])
|
741
|
+
|
742
|
+
/**
|
743
|
+
* A set of utility methods that can be use to retrieve position of DOM elements.
|
744
|
+
* It is meant to be used where we need to absolute-position DOM elements in
|
745
|
+
* relation to other, existing elements (this is the case for tooltips, popovers,
|
746
|
+
* typeahead suggestions etc.).
|
747
|
+
*/
|
748
|
+
.factory('$position', ['$document', '$window', function ($document, $window) {
|
749
|
+
|
750
|
+
var mouseX, mouseY;
|
751
|
+
|
752
|
+
$document.bind('mousemove', function mouseMoved(event) {
|
753
|
+
mouseX = event.pageX;
|
754
|
+
mouseY = event.pageY;
|
755
|
+
});
|
756
|
+
|
757
|
+
function getStyle(el, cssprop) {
|
758
|
+
if (el.currentStyle) { //IE
|
759
|
+
return el.currentStyle[cssprop];
|
760
|
+
} else if ($window.getComputedStyle) {
|
761
|
+
return $window.getComputedStyle(el)[cssprop];
|
762
|
+
}
|
763
|
+
// finally try and get inline style
|
764
|
+
return el.style[cssprop];
|
765
|
+
}
|
766
|
+
|
767
|
+
/**
|
768
|
+
* Checks if a given element is statically positioned
|
769
|
+
* @param element - raw DOM element
|
770
|
+
*/
|
771
|
+
function isStaticPositioned(element) {
|
772
|
+
return (getStyle(element, "position") || 'static' ) === 'static';
|
773
|
+
}
|
774
|
+
|
775
|
+
/**
|
776
|
+
* returns the closest, non-statically positioned parentOffset of a given element
|
777
|
+
* @param element
|
778
|
+
*/
|
779
|
+
var parentOffsetEl = function (element) {
|
780
|
+
var docDomEl = $document[0];
|
781
|
+
var offsetParent = element.offsetParent || docDomEl;
|
782
|
+
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
|
783
|
+
offsetParent = offsetParent.offsetParent;
|
784
|
+
}
|
785
|
+
return offsetParent || docDomEl;
|
786
|
+
};
|
787
|
+
|
788
|
+
return {
|
789
|
+
/**
|
790
|
+
* Provides read-only equivalent of jQuery's position function:
|
791
|
+
* http://api.jquery.com/position/
|
792
|
+
*/
|
793
|
+
position: function (element) {
|
794
|
+
var elBCR = this.offset(element);
|
795
|
+
var offsetParentBCR = { top: 0, left: 0 };
|
796
|
+
var offsetParentEl = parentOffsetEl(element[0]);
|
797
|
+
if (offsetParentEl != $document[0]) {
|
798
|
+
offsetParentBCR = this.offset(angular.element(offsetParentEl));
|
799
|
+
offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop;
|
800
|
+
offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft;
|
801
|
+
}
|
802
|
+
|
803
|
+
return {
|
804
|
+
width: element.prop('offsetWidth'),
|
805
|
+
height: element.prop('offsetHeight'),
|
806
|
+
top: elBCR.top - offsetParentBCR.top,
|
807
|
+
left: elBCR.left - offsetParentBCR.left
|
808
|
+
};
|
809
|
+
},
|
810
|
+
|
811
|
+
/**
|
812
|
+
* Provides read-only equivalent of jQuery's offset function:
|
813
|
+
* http://api.jquery.com/offset/
|
814
|
+
*/
|
815
|
+
offset: function (element) {
|
816
|
+
var boundingClientRect = element[0].getBoundingClientRect();
|
817
|
+
return {
|
818
|
+
width: element.prop('offsetWidth'),
|
819
|
+
height: element.prop('offsetHeight'),
|
820
|
+
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop),
|
821
|
+
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft)
|
822
|
+
};
|
823
|
+
},
|
824
|
+
|
825
|
+
/**
|
826
|
+
* Provides the coordinates of the mouse
|
827
|
+
*/
|
828
|
+
mouse: function () {
|
829
|
+
return {x: mouseX, y: mouseY};
|
830
|
+
}
|
831
|
+
};
|
832
|
+
}]);
|
833
|
+
|
834
|
+
angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.position'])
|
737
835
|
|
738
836
|
.constant('datepickerConfig', {
|
739
837
|
dayFormat: 'dd',
|
@@ -744,31 +842,139 @@ angular.module('ui.bootstrap.datepicker', [])
|
|
744
842
|
monthTitleFormat: 'yyyy',
|
745
843
|
showWeeks: true,
|
746
844
|
startingDay: 0,
|
747
|
-
yearRange: 20
|
845
|
+
yearRange: 20,
|
846
|
+
minDate: null,
|
847
|
+
maxDate: null
|
748
848
|
})
|
749
849
|
|
750
|
-
.
|
850
|
+
.controller('DatepickerController', ['$scope', '$attrs', 'dateFilter', 'datepickerConfig', function($scope, $attrs, dateFilter, dtConfig) {
|
851
|
+
var format = {
|
852
|
+
day: getValue($attrs.dayFormat, dtConfig.dayFormat),
|
853
|
+
month: getValue($attrs.monthFormat, dtConfig.monthFormat),
|
854
|
+
year: getValue($attrs.yearFormat, dtConfig.yearFormat),
|
855
|
+
dayHeader: getValue($attrs.dayHeaderFormat, dtConfig.dayHeaderFormat),
|
856
|
+
dayTitle: getValue($attrs.dayTitleFormat, dtConfig.dayTitleFormat),
|
857
|
+
monthTitle: getValue($attrs.monthTitleFormat, dtConfig.monthTitleFormat)
|
858
|
+
},
|
859
|
+
startingDay = getValue($attrs.startingDay, dtConfig.startingDay),
|
860
|
+
yearRange = getValue($attrs.yearRange, dtConfig.yearRange);
|
861
|
+
|
862
|
+
this.minDate = dtConfig.minDate ? new Date(dtConfig.minDate) : null;
|
863
|
+
this.maxDate = dtConfig.maxDate ? new Date(dtConfig.maxDate) : null;
|
864
|
+
|
865
|
+
function getValue(value, defaultValue) {
|
866
|
+
return angular.isDefined(value) ? $scope.$parent.$eval(value) : defaultValue;
|
867
|
+
}
|
868
|
+
|
869
|
+
function getDaysInMonth( year, month ) {
|
870
|
+
return new Date(year, month, 0).getDate();
|
871
|
+
}
|
872
|
+
|
873
|
+
function getDates(startDate, n) {
|
874
|
+
var dates = new Array(n);
|
875
|
+
var current = startDate, i = 0;
|
876
|
+
while (i < n) {
|
877
|
+
dates[i++] = new Date(current);
|
878
|
+
current.setDate( current.getDate() + 1 );
|
879
|
+
}
|
880
|
+
return dates;
|
881
|
+
}
|
882
|
+
|
883
|
+
function makeDate(date, format, isSelected, isSecondary) {
|
884
|
+
return { date: date, label: dateFilter(date, format), selected: !!isSelected, secondary: !!isSecondary };
|
885
|
+
}
|
886
|
+
|
887
|
+
this.modes = [
|
888
|
+
{
|
889
|
+
name: 'day',
|
890
|
+
getVisibleDates: function(date, selected) {
|
891
|
+
var year = date.getFullYear(), month = date.getMonth(), firstDayOfMonth = new Date(year, month, 1);
|
892
|
+
var difference = startingDay - firstDayOfMonth.getDay(),
|
893
|
+
numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : - difference,
|
894
|
+
firstDate = new Date(firstDayOfMonth), numDates = 0;
|
895
|
+
|
896
|
+
if ( numDisplayedFromPreviousMonth > 0 ) {
|
897
|
+
firstDate.setDate( - numDisplayedFromPreviousMonth + 1 );
|
898
|
+
numDates += numDisplayedFromPreviousMonth; // Previous
|
899
|
+
}
|
900
|
+
numDates += getDaysInMonth(year, month + 1); // Current
|
901
|
+
numDates += (7 - numDates % 7) % 7; // Next
|
902
|
+
|
903
|
+
var days = getDates(firstDate, numDates), labels = new Array(7);
|
904
|
+
for (var i = 0; i < numDates; i ++) {
|
905
|
+
var dt = new Date(days[i]);
|
906
|
+
days[i] = makeDate(dt, format.day, (selected && selected.getDate() === dt.getDate() && selected.getMonth() === dt.getMonth() && selected.getFullYear() === dt.getFullYear()), dt.getMonth() !== month);
|
907
|
+
}
|
908
|
+
for (var j = 0; j < 7; j++) {
|
909
|
+
labels[j] = dateFilter(days[j].date, format.dayHeader);
|
910
|
+
}
|
911
|
+
return { objects: days, title: dateFilter(date, format.dayTitle), labels: labels };
|
912
|
+
},
|
913
|
+
compare: function(date1, date2) {
|
914
|
+
return (new Date( date1.getFullYear(), date1.getMonth(), date1.getDate() ) - new Date( date2.getFullYear(), date2.getMonth(), date2.getDate() ) );
|
915
|
+
},
|
916
|
+
split: 7,
|
917
|
+
step: { months: 1 }
|
918
|
+
},
|
919
|
+
{
|
920
|
+
name: 'month',
|
921
|
+
getVisibleDates: function(date, selected) {
|
922
|
+
var months = new Array(12), year = date.getFullYear();
|
923
|
+
for ( var i = 0; i < 12; i++ ) {
|
924
|
+
var dt = new Date(year, i, 1);
|
925
|
+
months[i] = makeDate(dt, format.month, (selected && selected.getMonth() === i && selected.getFullYear() === year));
|
926
|
+
}
|
927
|
+
return { objects: months, title: dateFilter(date, format.monthTitle) };
|
928
|
+
},
|
929
|
+
compare: function(date1, date2) {
|
930
|
+
return new Date( date1.getFullYear(), date1.getMonth() ) - new Date( date2.getFullYear(), date2.getMonth() );
|
931
|
+
},
|
932
|
+
split: 3,
|
933
|
+
step: { years: 1 }
|
934
|
+
},
|
935
|
+
{
|
936
|
+
name: 'year',
|
937
|
+
getVisibleDates: function(date, selected) {
|
938
|
+
var years = new Array(yearRange), year = date.getFullYear(), startYear = parseInt((year - 1) / yearRange, 10) * yearRange + 1;
|
939
|
+
for ( var i = 0; i < yearRange; i++ ) {
|
940
|
+
var dt = new Date(startYear + i, 0, 1);
|
941
|
+
years[i] = makeDate(dt, format.year, (selected && selected.getFullYear() === dt.getFullYear()));
|
942
|
+
}
|
943
|
+
return { objects: years, title: [years[0].label, years[yearRange - 1].label].join(' - ') };
|
944
|
+
},
|
945
|
+
compare: function(date1, date2) {
|
946
|
+
return date1.getFullYear() - date2.getFullYear();
|
947
|
+
},
|
948
|
+
split: 5,
|
949
|
+
step: { years: yearRange }
|
950
|
+
}
|
951
|
+
];
|
952
|
+
|
953
|
+
this.isDisabled = function(date, mode) {
|
954
|
+
var currentMode = this.modes[mode || 0];
|
955
|
+
return ((this.minDate && currentMode.compare(date, this.minDate) < 0) || (this.maxDate && currentMode.compare(date, this.maxDate) > 0) || ($scope.dateDisabled && $scope.dateDisabled({date: date, mode: currentMode.name})));
|
956
|
+
};
|
957
|
+
}])
|
958
|
+
|
959
|
+
.directive( 'datepicker', ['dateFilter', '$parse', 'datepickerConfig', '$log', function (dateFilter, $parse, datepickerConfig, $log) {
|
751
960
|
return {
|
752
961
|
restrict: 'EA',
|
753
962
|
replace: true,
|
963
|
+
templateUrl: 'template/datepicker/datepicker.html',
|
754
964
|
scope: {
|
755
|
-
model: '=ngModel',
|
756
965
|
dateDisabled: '&'
|
757
966
|
},
|
758
|
-
|
759
|
-
|
760
|
-
|
967
|
+
require: ['datepicker', '?^ngModel'],
|
968
|
+
controller: 'DatepickerController',
|
969
|
+
link: function(scope, element, attrs, ctrls) {
|
970
|
+
var datepickerCtrl = ctrls[0], ngModel = ctrls[1];
|
971
|
+
|
972
|
+
if (!ngModel) {
|
973
|
+
return; // do nothing if no ng-model
|
974
|
+
}
|
761
975
|
|
762
976
|
// Configuration parameters
|
763
|
-
var selected = new Date(), showWeeks
|
764
|
-
format.day = angular.isDefined(attrs.dayFormat) ? scope.$eval(attrs.dayFormat) : datepickerConfig.dayFormat;
|
765
|
-
format.month = angular.isDefined(attrs.monthFormat) ? scope.$eval(attrs.monthFormat) : datepickerConfig.monthFormat;
|
766
|
-
format.year = angular.isDefined(attrs.yearFormat) ? scope.$eval(attrs.yearFormat) : datepickerConfig.yearFormat;
|
767
|
-
format.dayHeader = angular.isDefined(attrs.dayHeaderFormat) ? scope.$eval(attrs.dayHeaderFormat) : datepickerConfig.dayHeaderFormat;
|
768
|
-
format.dayTitle = angular.isDefined(attrs.dayTitleFormat) ? scope.$eval(attrs.dayTitleFormat) : datepickerConfig.dayTitleFormat;
|
769
|
-
format.monthTitle = angular.isDefined(attrs.monthTitleFormat) ? scope.$eval(attrs.monthTitleFormat) : datepickerConfig.monthTitleFormat;
|
770
|
-
var startingDay = angular.isDefined(attrs.startingDay) ? scope.$eval(attrs.startingDay) : datepickerConfig.startingDay;
|
771
|
-
var yearRange = angular.isDefined(attrs.yearRange) ? scope.$eval(attrs.yearRange) : datepickerConfig.yearRange;
|
977
|
+
var mode = 0, selected = new Date(), showWeeks = datepickerConfig.showWeeks;
|
772
978
|
|
773
979
|
if (attrs.showWeeks) {
|
774
980
|
scope.$parent.$watch($parse(attrs.showWeeks), function(value) {
|
@@ -776,174 +982,282 @@ angular.module('ui.bootstrap.datepicker', [])
|
|
776
982
|
updateShowWeekNumbers();
|
777
983
|
});
|
778
984
|
} else {
|
779
|
-
showWeeks = datepickerConfig.showWeeks;
|
780
985
|
updateShowWeekNumbers();
|
781
986
|
}
|
782
987
|
|
783
988
|
if (attrs.min) {
|
784
989
|
scope.$parent.$watch($parse(attrs.min), function(value) {
|
785
|
-
minDate = new Date(value);
|
990
|
+
datepickerCtrl.minDate = value ? new Date(value) : null;
|
786
991
|
refill();
|
787
992
|
});
|
788
993
|
}
|
789
994
|
if (attrs.max) {
|
790
995
|
scope.$parent.$watch($parse(attrs.max), function(value) {
|
791
|
-
maxDate = new Date(value);
|
996
|
+
datepickerCtrl.maxDate = value ? new Date(value) : null;
|
792
997
|
refill();
|
793
998
|
});
|
794
999
|
}
|
795
1000
|
|
796
|
-
function
|
797
|
-
scope.
|
798
|
-
scope.labels = labels;
|
799
|
-
scope.title = title;
|
1001
|
+
function updateShowWeekNumbers() {
|
1002
|
+
scope.showWeekNumbers = mode === 0 && showWeeks;
|
800
1003
|
}
|
801
1004
|
|
802
|
-
//
|
803
|
-
function
|
804
|
-
|
1005
|
+
// Split array into smaller arrays
|
1006
|
+
function split(arr, size) {
|
1007
|
+
var arrays = [];
|
1008
|
+
while (arr.length > 0) {
|
1009
|
+
arrays.push(arr.splice(0, size));
|
1010
|
+
}
|
1011
|
+
return arrays;
|
805
1012
|
}
|
806
1013
|
|
807
|
-
function
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
1014
|
+
function refill( updateSelected ) {
|
1015
|
+
var date = null, valid = true;
|
1016
|
+
|
1017
|
+
if ( ngModel.$modelValue ) {
|
1018
|
+
date = new Date( ngModel.$modelValue );
|
1019
|
+
|
1020
|
+
if ( isNaN(date) ) {
|
1021
|
+
valid = false;
|
1022
|
+
$log.error('Datepicker 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.');
|
1023
|
+
} else if ( updateSelected ) {
|
1024
|
+
selected = date;
|
1025
|
+
}
|
814
1026
|
}
|
1027
|
+
ngModel.$setValidity('date', valid);
|
1028
|
+
|
1029
|
+
var currentMode = datepickerCtrl.modes[mode], data = currentMode.getVisibleDates(selected, date);
|
1030
|
+
angular.forEach(data.objects, function(obj) {
|
1031
|
+
obj.disabled = datepickerCtrl.isDisabled(obj.date, mode);
|
1032
|
+
});
|
1033
|
+
|
1034
|
+
ngModel.$setValidity('date-disabled', (!date || !datepickerCtrl.isDisabled(date)));
|
1035
|
+
|
1036
|
+
scope.rows = split(data.objects, currentMode.split);
|
1037
|
+
scope.labels = data.labels || [];
|
1038
|
+
scope.title = data.title;
|
815
1039
|
}
|
816
1040
|
|
817
|
-
function
|
818
|
-
|
1041
|
+
function setMode(value) {
|
1042
|
+
mode = value;
|
1043
|
+
updateShowWeekNumbers();
|
1044
|
+
refill();
|
819
1045
|
}
|
820
1046
|
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
1047
|
+
ngModel.$render = function() {
|
1048
|
+
refill( true );
|
1049
|
+
};
|
1050
|
+
|
1051
|
+
scope.select = function( date ) {
|
1052
|
+
if ( mode === 0 ) {
|
1053
|
+
var dt = new Date( ngModel.$modelValue );
|
1054
|
+
dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
|
1055
|
+
ngModel.$setViewValue( dt );
|
1056
|
+
refill( true );
|
1057
|
+
} else {
|
1058
|
+
selected = date;
|
1059
|
+
setMode( mode - 1 );
|
826
1060
|
}
|
827
|
-
return arrays;
|
828
1061
|
};
|
829
|
-
|
830
|
-
|
1062
|
+
scope.move = function(direction) {
|
1063
|
+
var step = datepickerCtrl.modes[mode].step;
|
1064
|
+
selected.setMonth( selected.getMonth() + direction * (step.months || 0) );
|
1065
|
+
selected.setFullYear( selected.getFullYear() + direction * (step.years || 0) );
|
1066
|
+
refill();
|
1067
|
+
};
|
1068
|
+
scope.toggleMode = function() {
|
1069
|
+
setMode( (mode + 1) % datepickerCtrl.modes.length );
|
1070
|
+
};
|
1071
|
+
scope.getWeekNumber = function(row) {
|
1072
|
+
return ( mode === 0 && scope.showWeekNumbers && row.length === 7 ) ? getISO8601WeekNumber(row[0].date) : null;
|
831
1073
|
};
|
832
1074
|
|
833
|
-
|
834
|
-
|
835
|
-
|
1075
|
+
function getISO8601WeekNumber(date) {
|
1076
|
+
var checkDate = new Date(date);
|
1077
|
+
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); // Thursday
|
1078
|
+
var time = checkDate.getTime();
|
1079
|
+
checkDate.setMonth(0); // Compare with Jan 1
|
1080
|
+
checkDate.setDate(1);
|
1081
|
+
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
1082
|
+
}
|
1083
|
+
}
|
1084
|
+
};
|
1085
|
+
}])
|
836
1086
|
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
}
|
842
|
-
lastDate = dt;
|
843
|
-
}
|
1087
|
+
.constant('datepickerPopupConfig', {
|
1088
|
+
dateFormat: 'yyyy-MM-dd',
|
1089
|
+
closeOnDateSelection: true
|
1090
|
+
})
|
844
1091
|
|
845
|
-
|
846
|
-
|
1092
|
+
.directive('datepickerPopup', ['$compile', '$parse', '$document', '$position', 'dateFilter', 'datepickerPopupConfig',
|
1093
|
+
function ($compile, $parse, $document, $position, dateFilter, datepickerPopupConfig) {
|
1094
|
+
return {
|
1095
|
+
restrict: 'EA',
|
1096
|
+
require: 'ngModel',
|
1097
|
+
link: function(originalScope, element, attrs, ngModel) {
|
847
1098
|
|
848
|
-
|
849
|
-
|
1099
|
+
var closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection;
|
1100
|
+
var dateFormat = attrs.datepickerPopup || datepickerPopupConfig.dateFormat;
|
850
1101
|
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
addDays(lastDate, (7 - days.length % 7) % 7, false);
|
1102
|
+
// create a child scope for the datepicker directive so we are not polluting original scope
|
1103
|
+
var scope = originalScope.$new();
|
1104
|
+
originalScope.$on('$destroy', function() {
|
1105
|
+
scope.$destroy();
|
1106
|
+
});
|
857
1107
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
}
|
870
|
-
updateCalendar( split( months, 3 ), [], dateFilter(selected, format.monthTitle) );
|
871
|
-
},
|
872
|
-
year: function() {
|
873
|
-
var years = [], year = parseInt((selected.getFullYear() - 1) / yearRange, 10) * yearRange + 1;
|
874
|
-
for ( var i = 0; i < yearRange; i++ ) {
|
875
|
-
var dt = new Date(year + i, 0, 1);
|
876
|
-
years.push( {date: dt, isCurrent: true, isSelected: isSelected(dt), label: dateFilter(dt, format.year), disabled: isDisabled(dt)} );
|
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;
|
877
1119
|
}
|
878
|
-
|
879
|
-
|
1120
|
+
}
|
1121
|
+
return value;
|
1122
|
+
}
|
1123
|
+
ngModel.$parsers.push(parseDate);
|
1124
|
+
|
1125
|
+
var getIsOpen, setIsOpen;
|
1126
|
+
if ( attrs.open ) {
|
1127
|
+
getIsOpen = $parse(attrs.open);
|
1128
|
+
setIsOpen = getIsOpen.assign;
|
1129
|
+
|
1130
|
+
originalScope.$watch(getIsOpen, function updateOpen(value) {
|
1131
|
+
scope.isOpen = !! value;
|
1132
|
+
});
|
1133
|
+
}
|
1134
|
+
scope.isOpen = getIsOpen ? getIsOpen(originalScope) : false; // Initial state
|
1135
|
+
|
1136
|
+
function setOpen( value ) {
|
1137
|
+
if (setIsOpen) {
|
1138
|
+
setIsOpen(originalScope, !!value);
|
1139
|
+
} else {
|
1140
|
+
scope.isOpen = !!value;
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
|
1144
|
+
var documentClickBind = function(event) {
|
1145
|
+
if (scope.isOpen && event.target !== element[0]) {
|
1146
|
+
scope.$apply(function() {
|
1147
|
+
setOpen(false);
|
1148
|
+
});
|
880
1149
|
}
|
881
1150
|
};
|
882
|
-
|
883
|
-
|
1151
|
+
|
1152
|
+
var elementFocusBind = function() {
|
1153
|
+
scope.$apply(function() {
|
1154
|
+
setOpen( true );
|
1155
|
+
});
|
884
1156
|
};
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
1157
|
+
|
1158
|
+
// popup element used to display calendar
|
1159
|
+
var popupEl = angular.element('<datepicker-popup-wrap><datepicker></datepicker></datepicker-popup-wrap>');
|
1160
|
+
popupEl.attr({
|
1161
|
+
'ng-model': 'date',
|
1162
|
+
'ng-change': 'dateSelection()'
|
1163
|
+
});
|
1164
|
+
var datepickerEl = popupEl.find('datepicker');
|
1165
|
+
if (attrs.datepickerOptions) {
|
1166
|
+
datepickerEl.attr(angular.extend({}, originalScope.$eval(attrs.datepickerOptions)));
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
var $setModelValue = $parse(attrs.ngModel).assign;
|
1170
|
+
|
1171
|
+
// Inner change
|
1172
|
+
scope.dateSelection = function() {
|
1173
|
+
$setModelValue(originalScope, scope.date);
|
1174
|
+
if (closeOnDateSelection) {
|
1175
|
+
setOpen( false );
|
893
1176
|
}
|
894
|
-
return false;
|
895
1177
|
};
|
896
1178
|
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
1179
|
+
// Outter change
|
1180
|
+
scope.$watch(function() {
|
1181
|
+
return ngModel.$modelValue;
|
1182
|
+
}, function(value) {
|
1183
|
+
if (angular.isString(value)) {
|
1184
|
+
var date = parseDate(value);
|
901
1185
|
|
902
|
-
|
903
|
-
|
1186
|
+
if (value && !date) {
|
1187
|
+
$setModelValue(originalScope, null);
|
1188
|
+
throw new Error(value + ' cannot be parsed to a date object.');
|
1189
|
+
} else {
|
1190
|
+
value = date;
|
1191
|
+
}
|
904
1192
|
}
|
905
|
-
|
906
|
-
|
907
|
-
updateShowWeekNumbers();
|
908
|
-
refill();
|
1193
|
+
scope.date = value;
|
1194
|
+
updatePosition();
|
909
1195
|
});
|
910
1196
|
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
} else if ( scope.mode === 'month' ) {
|
918
|
-
scope.mode = 'day';
|
919
|
-
selected.setMonth( dt.getMonth() );
|
920
|
-
} else if ( scope.mode === 'day' ) {
|
921
|
-
scope.model = new Date(selected);
|
1197
|
+
function addWatchableAttribute(attribute, scopeProperty, datepickerAttribute) {
|
1198
|
+
if (attribute) {
|
1199
|
+
originalScope.$watch($parse(attribute), function(value){
|
1200
|
+
scope[scopeProperty] = value;
|
1201
|
+
});
|
1202
|
+
datepickerEl.attr(datepickerAttribute || scopeProperty, scopeProperty);
|
922
1203
|
}
|
923
|
-
}
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
1204
|
+
}
|
1205
|
+
addWatchableAttribute(attrs.min, 'min');
|
1206
|
+
addWatchableAttribute(attrs.max, 'max');
|
1207
|
+
if (attrs.showWeeks) {
|
1208
|
+
addWatchableAttribute(attrs.showWeeks, 'showWeeks', 'show-weeks');
|
1209
|
+
} else {
|
1210
|
+
scope.showWeeks = true;
|
1211
|
+
datepickerEl.attr('show-weeks', 'showWeeks');
|
1212
|
+
}
|
1213
|
+
if (attrs.dateDisabled) {
|
1214
|
+
datepickerEl.attr('date-disabled', attrs.dateDisabled);
|
1215
|
+
}
|
1216
|
+
|
1217
|
+
function updatePosition() {
|
1218
|
+
scope.position = $position.position(element);
|
1219
|
+
scope.position.top = scope.position.top + element.prop('offsetHeight');
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
scope.$watch('isOpen', function(value) {
|
1223
|
+
if (value) {
|
1224
|
+
updatePosition();
|
1225
|
+
$document.bind('click', documentClickBind);
|
1226
|
+
element.unbind('focus', elementFocusBind);
|
1227
|
+
element.focus();
|
1228
|
+
} else {
|
1229
|
+
$document.unbind('click', documentClickBind);
|
1230
|
+
element.bind('focus', elementFocusBind);
|
931
1231
|
}
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
scope.mode = ( scope.mode === 'day' ) ? 'month' : ( scope.mode === 'month' ) ? 'year' : 'day';
|
936
|
-
};
|
937
|
-
scope.getWeekNumber = function(row) {
|
938
|
-
if ( scope.mode !== 'day' || ! scope.showWeekNumbers || row.length !== 7 ) {
|
939
|
-
return;
|
1232
|
+
|
1233
|
+
if ( setIsOpen ) {
|
1234
|
+
setIsOpen(originalScope, value);
|
940
1235
|
}
|
1236
|
+
});
|
941
1237
|
|
942
|
-
|
943
|
-
|
944
|
-
d.setHours(0, 0, 0);
|
945
|
-
return Math.ceil((((d - new Date(d.getFullYear(), 0, 1)) / 86400000) + 1) / 7); // 86400000 = 1000*60*60*24;
|
1238
|
+
scope.today = function() {
|
1239
|
+
$setModelValue(originalScope, new Date());
|
946
1240
|
};
|
1241
|
+
scope.clear = function() {
|
1242
|
+
$setModelValue(originalScope, null);
|
1243
|
+
};
|
1244
|
+
|
1245
|
+
element.after($compile(popupEl)(scope));
|
1246
|
+
}
|
1247
|
+
};
|
1248
|
+
}])
|
1249
|
+
|
1250
|
+
.directive('datepickerPopupWrap', [function() {
|
1251
|
+
return {
|
1252
|
+
restrict:'E',
|
1253
|
+
replace: true,
|
1254
|
+
transclude: true,
|
1255
|
+
templateUrl: 'template/datepicker/popup.html',
|
1256
|
+
link:function (scope, element, attrs) {
|
1257
|
+
element.bind('click', function(event) {
|
1258
|
+
event.preventDefault();
|
1259
|
+
event.stopPropagation();
|
1260
|
+
});
|
947
1261
|
}
|
948
1262
|
};
|
949
1263
|
}]);
|
@@ -975,9 +1289,9 @@ dialogModule.provider("$dialog", function(){
|
|
975
1289
|
keyboard: true, // close with esc key
|
976
1290
|
backdropClick: true // only in conjunction with backdrop=true
|
977
1291
|
/* other options: template, templateUrl, controller */
|
978
|
-
|
1292
|
+
};
|
979
1293
|
|
980
|
-
|
1294
|
+
var globalOptions = {};
|
981
1295
|
|
982
1296
|
var activeBackdrops = {value : 0};
|
983
1297
|
|
@@ -987,21 +1301,21 @@ dialogModule.provider("$dialog", function(){
|
|
987
1301
|
// // don't close dialog when backdrop is clicked by default
|
988
1302
|
// $dialogProvider.options({backdropClick: false});
|
989
1303
|
// });
|
990
|
-
|
991
|
-
|
992
|
-
|
1304
|
+
this.options = function(value){
|
1305
|
+
globalOptions = value;
|
1306
|
+
};
|
993
1307
|
|
994
1308
|
// Returns the actual `$dialog` service that is injected in controllers
|
995
|
-
|
1309
|
+
this.$get = ["$http", "$document", "$compile", "$rootScope", "$controller", "$templateCache", "$q", "$transition", "$injector",
|
996
1310
|
function ($http, $document, $compile, $rootScope, $controller, $templateCache, $q, $transition, $injector) {
|
997
1311
|
|
998
|
-
|
1312
|
+
var body = $document.find('body');
|
999
1313
|
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1314
|
+
function createElement(clazz) {
|
1315
|
+
var el = angular.element("<div>");
|
1316
|
+
el.addClass(clazz);
|
1317
|
+
return el;
|
1318
|
+
}
|
1005
1319
|
|
1006
1320
|
// The `Dialog` class represents a modal dialog. The dialog class can be invoked by providing an options object
|
1007
1321
|
// containing at lest template or templateUrl and controller:
|
@@ -1011,7 +1325,7 @@ dialogModule.provider("$dialog", function(){
|
|
1011
1325
|
// Dialogs can also be created using templateUrl and controller as distinct arguments:
|
1012
1326
|
//
|
1013
1327
|
// var d = new Dialog('path/to/dialog.html', MyDialogController);
|
1014
|
-
|
1328
|
+
function Dialog(opts) {
|
1015
1329
|
|
1016
1330
|
var self = this, options = this.options = angular.extend({}, defaults, globalOptions, opts);
|
1017
1331
|
this._open = false;
|
@@ -1041,10 +1355,6 @@ dialogModule.provider("$dialog", function(){
|
|
1041
1355
|
e.preventDefault();
|
1042
1356
|
self.$scope.$apply();
|
1043
1357
|
};
|
1044
|
-
|
1045
|
-
this.handleLocationChange = function() {
|
1046
|
-
self.close();
|
1047
|
-
};
|
1048
1358
|
}
|
1049
1359
|
|
1050
1360
|
// The `isOpen()` method returns wether the dialog is currently visible.
|
@@ -1333,25 +1643,41 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.dialog'])
|
|
1333
1643
|
}]);
|
1334
1644
|
angular.module('ui.bootstrap.pagination', [])
|
1335
1645
|
|
1336
|
-
.controller('PaginationController', ['$scope', function (scope) {
|
1646
|
+
.controller('PaginationController', ['$scope', '$interpolate', function ($scope, $interpolate) {
|
1647
|
+
|
1648
|
+
this.currentPage = 1;
|
1337
1649
|
|
1338
|
-
|
1339
|
-
return
|
1650
|
+
this.noPrevious = function() {
|
1651
|
+
return this.currentPage === 1;
|
1340
1652
|
};
|
1341
|
-
|
1342
|
-
return
|
1653
|
+
this.noNext = function() {
|
1654
|
+
return this.currentPage === $scope.numPages;
|
1343
1655
|
};
|
1344
1656
|
|
1345
|
-
|
1346
|
-
return
|
1657
|
+
this.isActive = function(page) {
|
1658
|
+
return this.currentPage === page;
|
1347
1659
|
};
|
1348
1660
|
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1661
|
+
this.reset = function() {
|
1662
|
+
$scope.pages = [];
|
1663
|
+
this.currentPage = parseInt($scope.currentPage, 10);
|
1664
|
+
|
1665
|
+
if ( this.currentPage > $scope.numPages ) {
|
1666
|
+
$scope.selectPage($scope.numPages);
|
1667
|
+
}
|
1668
|
+
};
|
1669
|
+
|
1670
|
+
var self = this;
|
1671
|
+
$scope.selectPage = function(page) {
|
1672
|
+
if ( ! self.isActive(page) && page > 0 && page <= $scope.numPages) {
|
1673
|
+
$scope.currentPage = page;
|
1674
|
+
$scope.onSelectPage({ page: page });
|
1353
1675
|
}
|
1354
1676
|
};
|
1677
|
+
|
1678
|
+
this.getAttributeValue = function(attribute, defaultValue, interpolate) {
|
1679
|
+
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
|
1680
|
+
};
|
1355
1681
|
}])
|
1356
1682
|
|
1357
1683
|
.constant('paginationConfig', {
|
@@ -1364,7 +1690,7 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1364
1690
|
rotate: true
|
1365
1691
|
})
|
1366
1692
|
|
1367
|
-
.directive('pagination', ['paginationConfig', function(
|
1693
|
+
.directive('pagination', ['paginationConfig', function(config) {
|
1368
1694
|
return {
|
1369
1695
|
restrict: 'EA',
|
1370
1696
|
scope: {
|
@@ -1376,16 +1702,16 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1376
1702
|
controller: 'PaginationController',
|
1377
1703
|
templateUrl: 'template/pagination/pagination.html',
|
1378
1704
|
replace: true,
|
1379
|
-
link: function(scope, element, attrs) {
|
1705
|
+
link: function(scope, element, attrs, paginationCtrl) {
|
1380
1706
|
|
1381
1707
|
// Setup configuration parameters
|
1382
|
-
var boundaryLinks =
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1708
|
+
var boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks ),
|
1709
|
+
directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks ),
|
1710
|
+
firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true),
|
1711
|
+
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
1712
|
+
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1713
|
+
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
|
1714
|
+
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
|
1389
1715
|
|
1390
1716
|
// Create page object used in template
|
1391
1717
|
function makePage(number, text, isActive, isDisabled) {
|
@@ -1398,8 +1724,8 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1398
1724
|
}
|
1399
1725
|
|
1400
1726
|
scope.$watch('numPages + currentPage + maxSize', function() {
|
1401
|
-
|
1402
|
-
|
1727
|
+
paginationCtrl.reset();
|
1728
|
+
|
1403
1729
|
// Default page limits
|
1404
1730
|
var startPage = 1, endPage = scope.numPages;
|
1405
1731
|
var isMaxSized = ( angular.isDefined(scope.maxSize) && scope.maxSize < scope.numPages );
|
@@ -1408,7 +1734,7 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1408
1734
|
if ( isMaxSized ) {
|
1409
1735
|
if ( rotate ) {
|
1410
1736
|
// Current page is displayed in the middle of the visible ones
|
1411
|
-
startPage = Math.max(
|
1737
|
+
startPage = Math.max(paginationCtrl.currentPage - Math.floor(scope.maxSize/2), 1);
|
1412
1738
|
endPage = startPage + scope.maxSize - 1;
|
1413
1739
|
|
1414
1740
|
// Adjust if limit is exceeded
|
@@ -1418,7 +1744,7 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1418
1744
|
}
|
1419
1745
|
} else {
|
1420
1746
|
// Visible pages are paginated with maxSize
|
1421
|
-
startPage = ((Math.ceil(
|
1747
|
+
startPage = ((Math.ceil(paginationCtrl.currentPage / scope.maxSize) - 1) * scope.maxSize) + 1;
|
1422
1748
|
|
1423
1749
|
// Adjust last page if limit is exceeded
|
1424
1750
|
endPage = Math.min(startPage + scope.maxSize - 1, scope.numPages);
|
@@ -1427,7 +1753,7 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1427
1753
|
|
1428
1754
|
// Add page number links
|
1429
1755
|
for (var number = startPage; number <= endPage; number++) {
|
1430
|
-
var page = makePage(number, number,
|
1756
|
+
var page = makePage(number, number, paginationCtrl.isActive(number), false);
|
1431
1757
|
scope.pages.push(page);
|
1432
1758
|
}
|
1433
1759
|
|
@@ -1446,25 +1772,21 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1446
1772
|
|
1447
1773
|
// Add previous & next links
|
1448
1774
|
if (directionLinks) {
|
1449
|
-
var previousPage = makePage(
|
1775
|
+
var previousPage = makePage(paginationCtrl.currentPage - 1, previousText, false, paginationCtrl.noPrevious());
|
1450
1776
|
scope.pages.unshift(previousPage);
|
1451
1777
|
|
1452
|
-
var nextPage = makePage(
|
1778
|
+
var nextPage = makePage(paginationCtrl.currentPage + 1, nextText, false, paginationCtrl.noNext());
|
1453
1779
|
scope.pages.push(nextPage);
|
1454
1780
|
}
|
1455
1781
|
|
1456
1782
|
// Add first & last links
|
1457
1783
|
if (boundaryLinks) {
|
1458
|
-
var firstPage = makePage(1, firstText, false,
|
1784
|
+
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
|
1459
1785
|
scope.pages.unshift(firstPage);
|
1460
1786
|
|
1461
|
-
var lastPage = makePage(scope.numPages, lastText, false,
|
1787
|
+
var lastPage = makePage(scope.numPages, lastText, false, paginationCtrl.noNext());
|
1462
1788
|
scope.pages.push(lastPage);
|
1463
1789
|
}
|
1464
|
-
|
1465
|
-
if ( scope.currentPage > scope.numPages ) {
|
1466
|
-
scope.selectPage(scope.numPages);
|
1467
|
-
}
|
1468
1790
|
});
|
1469
1791
|
}
|
1470
1792
|
};
|
@@ -1490,9 +1812,9 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1490
1812
|
link: function(scope, element, attrs, paginationCtrl) {
|
1491
1813
|
|
1492
1814
|
// Setup configuration parameters
|
1493
|
-
var previousText =
|
1494
|
-
|
1495
|
-
|
1815
|
+
var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
|
1816
|
+
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
|
1817
|
+
align = paginationCtrl.getAttributeValue(attrs.align, config.align);
|
1496
1818
|
|
1497
1819
|
// Create page object used in template
|
1498
1820
|
function makePage(number, text, isDisabled, isPrevious, isNext) {
|
@@ -1506,117 +1828,19 @@ angular.module('ui.bootstrap.pagination', [])
|
|
1506
1828
|
}
|
1507
1829
|
|
1508
1830
|
scope.$watch('numPages + currentPage', function() {
|
1509
|
-
|
1831
|
+
paginationCtrl.reset();
|
1510
1832
|
|
1511
1833
|
// Add previous & next links
|
1512
|
-
var previousPage = makePage(
|
1834
|
+
var previousPage = makePage(paginationCtrl.currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false);
|
1513
1835
|
scope.pages.unshift(previousPage);
|
1514
1836
|
|
1515
|
-
var nextPage = makePage(
|
1837
|
+
var nextPage = makePage(paginationCtrl.currentPage + 1, nextText, paginationCtrl.noNext(), false, true);
|
1516
1838
|
scope.pages.push(nextPage);
|
1517
|
-
|
1518
|
-
if ( scope.currentPage > scope.numPages ) {
|
1519
|
-
scope.selectPage(scope.numPages);
|
1520
|
-
}
|
1521
1839
|
});
|
1522
1840
|
}
|
1523
1841
|
};
|
1524
1842
|
}]);
|
1525
1843
|
|
1526
|
-
angular.module('ui.bootstrap.position', [])
|
1527
|
-
|
1528
|
-
/**
|
1529
|
-
* A set of utility methods that can be use to retrieve position of DOM elements.
|
1530
|
-
* It is meant to be used where we need to absolute-position DOM elements in
|
1531
|
-
* relation to other, existing elements (this is the case for tooltips, popovers,
|
1532
|
-
* typeahead suggestions etc.).
|
1533
|
-
*/
|
1534
|
-
.factory('$position', ['$document', '$window', function ($document, $window) {
|
1535
|
-
|
1536
|
-
var mouseX, mouseY;
|
1537
|
-
|
1538
|
-
$document.bind('mousemove', function mouseMoved(event) {
|
1539
|
-
mouseX = event.pageX;
|
1540
|
-
mouseY = event.pageY;
|
1541
|
-
});
|
1542
|
-
|
1543
|
-
function getStyle(el, cssprop) {
|
1544
|
-
if (el.currentStyle) { //IE
|
1545
|
-
return el.currentStyle[cssprop];
|
1546
|
-
} else if ($window.getComputedStyle) {
|
1547
|
-
return $window.getComputedStyle(el)[cssprop];
|
1548
|
-
}
|
1549
|
-
// finally try and get inline style
|
1550
|
-
return el.style[cssprop];
|
1551
|
-
}
|
1552
|
-
|
1553
|
-
/**
|
1554
|
-
* Checks if a given element is statically positioned
|
1555
|
-
* @param element - raw DOM element
|
1556
|
-
*/
|
1557
|
-
function isStaticPositioned(element) {
|
1558
|
-
return (getStyle(element, "position") || 'static' ) === 'static';
|
1559
|
-
}
|
1560
|
-
|
1561
|
-
/**
|
1562
|
-
* returns the closest, non-statically positioned parentOffset of a given element
|
1563
|
-
* @param element
|
1564
|
-
*/
|
1565
|
-
var parentOffsetEl = function (element) {
|
1566
|
-
var docDomEl = $document[0];
|
1567
|
-
var offsetParent = element.offsetParent || docDomEl;
|
1568
|
-
while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) {
|
1569
|
-
offsetParent = offsetParent.offsetParent;
|
1570
|
-
}
|
1571
|
-
return offsetParent || docDomEl;
|
1572
|
-
};
|
1573
|
-
|
1574
|
-
return {
|
1575
|
-
/**
|
1576
|
-
* Provides read-only equivalent of jQuery's position function:
|
1577
|
-
* http://api.jquery.com/position/
|
1578
|
-
*/
|
1579
|
-
position: function (element) {
|
1580
|
-
var elBCR = this.offset(element);
|
1581
|
-
var offsetParentBCR = { top: 0, left: 0 };
|
1582
|
-
var offsetParentEl = parentOffsetEl(element[0]);
|
1583
|
-
if (offsetParentEl != $document[0]) {
|
1584
|
-
offsetParentBCR = this.offset(angular.element(offsetParentEl));
|
1585
|
-
offsetParentBCR.top += offsetParentEl.clientTop;
|
1586
|
-
offsetParentBCR.left += offsetParentEl.clientLeft;
|
1587
|
-
}
|
1588
|
-
|
1589
|
-
return {
|
1590
|
-
width: element.prop('offsetWidth'),
|
1591
|
-
height: element.prop('offsetHeight'),
|
1592
|
-
top: elBCR.top - offsetParentBCR.top,
|
1593
|
-
left: elBCR.left - offsetParentBCR.left
|
1594
|
-
};
|
1595
|
-
},
|
1596
|
-
|
1597
|
-
/**
|
1598
|
-
* Provides read-only equivalent of jQuery's offset function:
|
1599
|
-
* http://api.jquery.com/offset/
|
1600
|
-
*/
|
1601
|
-
offset: function (element) {
|
1602
|
-
var boundingClientRect = element[0].getBoundingClientRect();
|
1603
|
-
return {
|
1604
|
-
width: element.prop('offsetWidth'),
|
1605
|
-
height: element.prop('offsetHeight'),
|
1606
|
-
top: boundingClientRect.top + ($window.pageYOffset || $document[0].body.scrollTop),
|
1607
|
-
left: boundingClientRect.left + ($window.pageXOffset || $document[0].body.scrollLeft)
|
1608
|
-
};
|
1609
|
-
},
|
1610
|
-
|
1611
|
-
/**
|
1612
|
-
* Provides the coordinates of the mouse
|
1613
|
-
*/
|
1614
|
-
mouse: function () {
|
1615
|
-
return {x: mouseX, y: mouseY};
|
1616
|
-
}
|
1617
|
-
};
|
1618
|
-
}]);
|
1619
|
-
|
1620
1844
|
/**
|
1621
1845
|
* The following features are still outstanding: animation as a
|
1622
1846
|
* function, placement as a function, inside, support for more triggers than
|
@@ -1655,9 +1879,9 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1655
1879
|
* $tooltipProvider.options( { placement: 'left' } );
|
1656
1880
|
* });
|
1657
1881
|
*/
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1882
|
+
this.options = function( value ) {
|
1883
|
+
angular.extend( globalOptions, value );
|
1884
|
+
};
|
1661
1885
|
|
1662
1886
|
/**
|
1663
1887
|
* This allows you to extend the set of trigger mappings available. E.g.:
|
@@ -1701,16 +1925,9 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1701
1925
|
* undefined; otherwise, it uses the `triggerMap` value of the show
|
1702
1926
|
* trigger; else it will just use the show trigger.
|
1703
1927
|
*/
|
1704
|
-
function
|
1705
|
-
var show
|
1706
|
-
|
1707
|
-
show = trigger || options.trigger || defaultTriggerShow;
|
1708
|
-
if ( angular.isDefined ( options.trigger ) ) {
|
1709
|
-
hide = triggerMap[options.trigger] || show;
|
1710
|
-
} else {
|
1711
|
-
hide = triggerMap[show] || show;
|
1712
|
-
}
|
1713
|
-
|
1928
|
+
function getTriggers ( trigger ) {
|
1929
|
+
var show = trigger || options.trigger || defaultTriggerShow;
|
1930
|
+
var hide = triggerMap[show] || show;
|
1714
1931
|
return {
|
1715
1932
|
show: show,
|
1716
1933
|
hide: hide
|
@@ -1718,7 +1935,6 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1718
1935
|
}
|
1719
1936
|
|
1720
1937
|
var directiveName = snake_case( type );
|
1721
|
-
var triggers = setTriggers( undefined );
|
1722
1938
|
|
1723
1939
|
var startSym = $interpolate.startSymbol();
|
1724
1940
|
var endSym = $interpolate.endSymbol();
|
@@ -1741,6 +1957,8 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1741
1957
|
var popupTimeout;
|
1742
1958
|
var $body;
|
1743
1959
|
var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
|
1960
|
+
var triggers = getTriggers( undefined );
|
1961
|
+
var hasRegisteredTriggers = false;
|
1744
1962
|
|
1745
1963
|
// By default, the tooltip is not open.
|
1746
1964
|
// TODO add ability to start tooltip opened
|
@@ -1800,7 +2018,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1800
2018
|
}
|
1801
2019
|
|
1802
2020
|
// Get the position of the directive element.
|
1803
|
-
position =
|
2021
|
+
position = appendToBody ? $position.offset( element ) : $position.position( element );
|
1804
2022
|
|
1805
2023
|
// Get the height and width of the tooltip so we can center it.
|
1806
2024
|
ttWidth = tooltip.prop( 'offsetWidth' );
|
@@ -1895,10 +2113,13 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1895
2113
|
});
|
1896
2114
|
|
1897
2115
|
attrs.$observe( prefix+'Trigger', function ( val ) {
|
1898
|
-
element.unbind( triggers.show );
|
1899
|
-
element.unbind( triggers.hide );
|
1900
2116
|
|
1901
|
-
|
2117
|
+
if (hasRegisteredTriggers) {
|
2118
|
+
element.unbind( triggers.show, showTooltipBind );
|
2119
|
+
element.unbind( triggers.hide, hideTooltipBind );
|
2120
|
+
}
|
2121
|
+
|
2122
|
+
triggers = getTriggers( val );
|
1902
2123
|
|
1903
2124
|
if ( triggers.show === triggers.hide ) {
|
1904
2125
|
element.bind( triggers.show, toggleTooltipBind );
|
@@ -1906,6 +2127,8 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] )
|
|
1906
2127
|
element.bind( triggers.show, showTooltipBind );
|
1907
2128
|
element.bind( triggers.hide, hideTooltipBind );
|
1908
2129
|
}
|
2130
|
+
|
2131
|
+
hasRegisteredTriggers = true;
|
1909
2132
|
});
|
1910
2133
|
|
1911
2134
|
attrs.$observe( prefix+'AppendToBody', function ( val ) {
|
@@ -2098,13 +2321,15 @@ angular.module('ui.bootstrap.rating', [])
|
|
2098
2321
|
return {
|
2099
2322
|
restrict: 'EA',
|
2100
2323
|
scope: {
|
2101
|
-
value: '='
|
2324
|
+
value: '=',
|
2325
|
+
onHover: '&',
|
2326
|
+
onLeave: '&'
|
2102
2327
|
},
|
2103
2328
|
templateUrl: 'template/rating/rating.html',
|
2104
2329
|
replace: true,
|
2105
2330
|
link: function(scope, element, attrs) {
|
2106
2331
|
|
2107
|
-
var maxRange = angular.isDefined(attrs.max) ? scope.$eval(attrs.max) : ratingConfig.max;
|
2332
|
+
var maxRange = angular.isDefined(attrs.max) ? scope.$parent.$eval(attrs.max) : ratingConfig.max;
|
2108
2333
|
|
2109
2334
|
scope.range = [];
|
2110
2335
|
for (var i = 1; i <= maxRange; i++) {
|
@@ -2121,10 +2346,12 @@ angular.module('ui.bootstrap.rating', [])
|
|
2121
2346
|
if ( ! scope.readonly ) {
|
2122
2347
|
scope.val = value;
|
2123
2348
|
}
|
2349
|
+
scope.onHover({value: value});
|
2124
2350
|
};
|
2125
2351
|
|
2126
2352
|
scope.reset = function() {
|
2127
2353
|
scope.val = angular.copy(scope.value);
|
2354
|
+
scope.onLeave();
|
2128
2355
|
};
|
2129
2356
|
scope.reset();
|
2130
2357
|
|
@@ -2158,26 +2385,27 @@ angular.module('ui.bootstrap.tabs', [])
|
|
2158
2385
|
};
|
2159
2386
|
})
|
2160
2387
|
|
2161
|
-
.controller('TabsetController', ['$scope', '$element',
|
2388
|
+
.controller('TabsetController', ['$scope', '$element',
|
2162
2389
|
function TabsetCtrl($scope, $element) {
|
2390
|
+
|
2163
2391
|
var ctrl = this,
|
2164
2392
|
tabs = ctrl.tabs = $scope.tabs = [];
|
2165
2393
|
|
2166
2394
|
ctrl.select = function(tab) {
|
2167
2395
|
angular.forEach(tabs, function(tab) {
|
2168
2396
|
tab.active = false;
|
2169
|
-
});
|
2397
|
+
});
|
2170
2398
|
tab.active = true;
|
2171
2399
|
};
|
2172
2400
|
|
2173
2401
|
ctrl.addTab = function addTab(tab) {
|
2174
2402
|
tabs.push(tab);
|
2175
|
-
if (tabs.length
|
2403
|
+
if (tabs.length === 1 || tab.active) {
|
2176
2404
|
ctrl.select(tab);
|
2177
2405
|
}
|
2178
2406
|
};
|
2179
2407
|
|
2180
|
-
ctrl.removeTab = function removeTab(tab) {
|
2408
|
+
ctrl.removeTab = function removeTab(tab) {
|
2181
2409
|
var index = tabs.indexOf(tab);
|
2182
2410
|
//Select a new tab if the tab to be removed is selected
|
2183
2411
|
if (tab.active && tabs.length > 1) {
|
@@ -2198,6 +2426,8 @@ function TabsetCtrl($scope, $element) {
|
|
2198
2426
|
* Tabset is the outer container for the tabs directive
|
2199
2427
|
*
|
2200
2428
|
* @param {boolean=} vertical Whether or not to use vertical styling for the tabs.
|
2429
|
+
* @param {string=} direction What direction the tabs should be rendered. Available:
|
2430
|
+
* 'right', 'left', 'below'.
|
2201
2431
|
*
|
2202
2432
|
* @example
|
2203
2433
|
<example module="ui.bootstrap">
|
@@ -2218,12 +2448,20 @@ function TabsetCtrl($scope, $element) {
|
|
2218
2448
|
return {
|
2219
2449
|
restrict: 'EA',
|
2220
2450
|
transclude: true,
|
2451
|
+
replace: true,
|
2452
|
+
require: '^tabset',
|
2221
2453
|
scope: {},
|
2222
2454
|
controller: 'TabsetController',
|
2223
2455
|
templateUrl: 'template/tabs/tabset.html',
|
2224
|
-
|
2225
|
-
scope
|
2226
|
-
|
2456
|
+
compile: function(elm, attrs, transclude) {
|
2457
|
+
return function(scope, element, attrs, tabsetCtrl) {
|
2458
|
+
scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false;
|
2459
|
+
scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs';
|
2460
|
+
scope.direction = angular.isDefined(attrs.direction) ? scope.$parent.$eval(attrs.direction) : 'top';
|
2461
|
+
scope.tabsAbove = (scope.direction != 'below');
|
2462
|
+
tabsetCtrl.$scope = scope;
|
2463
|
+
tabsetCtrl.$transcludeFn = transclude;
|
2464
|
+
};
|
2227
2465
|
}
|
2228
2466
|
};
|
2229
2467
|
})
|
@@ -2238,7 +2476,7 @@ function TabsetCtrl($scope, $element) {
|
|
2238
2476
|
* @param {boolean=} active A binding, telling whether or not this tab is selected.
|
2239
2477
|
* @param {boolean=} disabled A binding, telling whether or not this tab is disabled.
|
2240
2478
|
*
|
2241
|
-
* @description
|
2479
|
+
* @description
|
2242
2480
|
* Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}.
|
2243
2481
|
*
|
2244
2482
|
* @example
|
@@ -2318,8 +2556,9 @@ function($parse, $http, $templateCache, $compile) {
|
|
2318
2556
|
transclude: true,
|
2319
2557
|
scope: {
|
2320
2558
|
heading: '@',
|
2321
|
-
onSelect: '&select' //This callback is called in contentHeadingTransclude
|
2559
|
+
onSelect: '&select', //This callback is called in contentHeadingTransclude
|
2322
2560
|
//once it inserts the tab's content into the dom
|
2561
|
+
onDeselect: '&deselect'
|
2323
2562
|
},
|
2324
2563
|
controller: function() {
|
2325
2564
|
//Empty controller so other directives can require being 'under' a tab
|
@@ -2327,17 +2566,13 @@ function($parse, $http, $templateCache, $compile) {
|
|
2327
2566
|
compile: function(elm, attrs, transclude) {
|
2328
2567
|
return function postLink(scope, elm, attrs, tabsetCtrl) {
|
2329
2568
|
var getActive, setActive;
|
2330
|
-
scope.active = false; // default value
|
2331
2569
|
if (attrs.active) {
|
2332
2570
|
getActive = $parse(attrs.active);
|
2333
2571
|
setActive = getActive.assign;
|
2334
2572
|
scope.$parent.$watch(getActive, function updateActive(value) {
|
2335
|
-
|
2336
|
-
setActive(scope.$parent, false); // Prevent active assignment
|
2337
|
-
} else {
|
2338
|
-
scope.active = !!value;
|
2339
|
-
}
|
2573
|
+
scope.active = !!value;
|
2340
2574
|
});
|
2575
|
+
scope.active = getActive(scope.$parent);
|
2341
2576
|
} else {
|
2342
2577
|
setActive = getActive = angular.noop;
|
2343
2578
|
}
|
@@ -2347,6 +2582,8 @@ function($parse, $http, $templateCache, $compile) {
|
|
2347
2582
|
if (active) {
|
2348
2583
|
tabsetCtrl.select(scope);
|
2349
2584
|
scope.onSelect();
|
2585
|
+
} else {
|
2586
|
+
scope.onDeselect();
|
2350
2587
|
}
|
2351
2588
|
});
|
2352
2589
|
|
@@ -2367,42 +2604,14 @@ function($parse, $http, $templateCache, $compile) {
|
|
2367
2604
|
scope.$on('$destroy', function() {
|
2368
2605
|
tabsetCtrl.removeTab(scope);
|
2369
2606
|
});
|
2370
|
-
//If the tabset sets this tab to active, set the parent scope's active
|
2371
|
-
//binding too. We do this so the watch for the parent's initial active
|
2372
|
-
//value won't overwrite what is initially set by the tabset
|
2373
2607
|
if (scope.active) {
|
2374
2608
|
setActive(scope.$parent, true);
|
2375
|
-
}
|
2376
|
-
|
2377
|
-
|
2378
|
-
//
|
2379
|
-
//
|
2380
|
-
|
2381
|
-
//Look at every element in the clone collection. If it's tab-heading,
|
2382
|
-
//mark it as that. If it's not tab-heading, mark it as tab contents
|
2383
|
-
var contents = [], heading;
|
2384
|
-
angular.forEach(clone, function(el) {
|
2385
|
-
//See if it's a tab-heading attr or element directive
|
2386
|
-
//First make sure it's a normal element, one that has a tagName
|
2387
|
-
if (el.tagName &&
|
2388
|
-
(el.hasAttribute("tab-heading") ||
|
2389
|
-
el.hasAttribute("data-tab-heading") ||
|
2390
|
-
el.tagName.toLowerCase() == "tab-heading" ||
|
2391
|
-
el.tagName.toLowerCase() == "data-tab-heading"
|
2392
|
-
)) {
|
2393
|
-
heading = el;
|
2394
|
-
} else {
|
2395
|
-
contents.push(el);
|
2396
|
-
}
|
2397
|
-
});
|
2398
|
-
//Share what we found on the scope, so our tabHeadingTransclude and
|
2399
|
-
//tabContentTransclude directives can find out what the heading and
|
2400
|
-
//contents are.
|
2401
|
-
if (heading) {
|
2402
|
-
scope.headingElement = angular.element(heading);
|
2403
|
-
}
|
2404
|
-
scope.contentElement = angular.element(contents);
|
2405
|
-
});
|
2609
|
+
}
|
2610
|
+
|
2611
|
+
|
2612
|
+
//We need to transclude later, once the content container is ready.
|
2613
|
+
//when this link happens, we're inside a tab heading.
|
2614
|
+
scope.$transcludeFn = transclude;
|
2406
2615
|
};
|
2407
2616
|
}
|
2408
2617
|
};
|
@@ -2411,7 +2620,7 @@ function($parse, $http, $templateCache, $compile) {
|
|
2411
2620
|
.directive('tabHeadingTransclude', [function() {
|
2412
2621
|
return {
|
2413
2622
|
restrict: 'A',
|
2414
|
-
require: '^tab',
|
2623
|
+
require: '^tab',
|
2415
2624
|
link: function(scope, elm, attrs, tabCtrl) {
|
2416
2625
|
scope.$watch('headingElement', function updateHeadingElement(heading) {
|
2417
2626
|
if (heading) {
|
@@ -2423,21 +2632,56 @@ function($parse, $http, $templateCache, $compile) {
|
|
2423
2632
|
};
|
2424
2633
|
}])
|
2425
2634
|
|
2426
|
-
.directive('tabContentTransclude', ['$parse', function($parse) {
|
2635
|
+
.directive('tabContentTransclude', ['$compile', '$parse', function($compile, $parse) {
|
2427
2636
|
return {
|
2428
2637
|
restrict: 'A',
|
2429
2638
|
require: '^tabset',
|
2430
|
-
link: function(scope, elm, attrs
|
2431
|
-
scope.$
|
2432
|
-
|
2433
|
-
|
2434
|
-
|
2435
|
-
|
2639
|
+
link: function(scope, elm, attrs) {
|
2640
|
+
var tab = scope.$eval(attrs.tabContentTransclude);
|
2641
|
+
|
2642
|
+
//Now our tab is ready to be transcluded: both the tab heading area
|
2643
|
+
//and the tab content area are loaded. Transclude 'em both.
|
2644
|
+
tab.$transcludeFn(tab.$parent, function(contents) {
|
2645
|
+
angular.forEach(contents, function(node) {
|
2646
|
+
if (isTabHeading(node)) {
|
2647
|
+
//Let tabHeadingTransclude know.
|
2648
|
+
tab.headingElement = node;
|
2649
|
+
} else {
|
2650
|
+
elm.append(node);
|
2651
|
+
}
|
2652
|
+
});
|
2436
2653
|
});
|
2437
2654
|
}
|
2438
2655
|
};
|
2656
|
+
function isTabHeading(node) {
|
2657
|
+
return node.tagName && (
|
2658
|
+
node.hasAttribute('tab-heading') ||
|
2659
|
+
node.hasAttribute('data-tab-heading') ||
|
2660
|
+
node.tagName.toLowerCase() === 'tab-heading' ||
|
2661
|
+
node.tagName.toLowerCase() === 'data-tab-heading'
|
2662
|
+
);
|
2663
|
+
}
|
2439
2664
|
}])
|
2440
2665
|
|
2666
|
+
.directive('tabsetTitles', function($http) {
|
2667
|
+
return {
|
2668
|
+
restrict: 'A',
|
2669
|
+
require: '^tabset',
|
2670
|
+
templateUrl: 'template/tabs/tabset-titles.html',
|
2671
|
+
replace: true,
|
2672
|
+
link: function(scope, elm, attrs, tabsetCtrl) {
|
2673
|
+
if (!scope.$eval(attrs.tabsetTitles)) {
|
2674
|
+
elm.remove();
|
2675
|
+
} else {
|
2676
|
+
//now that tabs location has been decided, transclude the tab titles in
|
2677
|
+
tabsetCtrl.$transcludeFn(tabsetCtrl.$scope.$parent, function(node) {
|
2678
|
+
elm.append(node);
|
2679
|
+
});
|
2680
|
+
}
|
2681
|
+
}
|
2682
|
+
};
|
2683
|
+
})
|
2684
|
+
|
2441
2685
|
;
|
2442
2686
|
|
2443
2687
|
|
@@ -2533,20 +2777,22 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2533
2777
|
// Respond on mousewheel spin
|
2534
2778
|
var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
|
2535
2779
|
if ( mousewheel ) {
|
2536
|
-
|
2780
|
+
|
2537
2781
|
var isScrollingUp = function(e) {
|
2538
2782
|
if (e.originalEvent) {
|
2539
2783
|
e = e.originalEvent;
|
2540
2784
|
}
|
2541
|
-
|
2785
|
+
//pick correct delta variable depending on event
|
2786
|
+
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
|
2787
|
+
return (e.detail || delta > 0);
|
2542
2788
|
};
|
2543
|
-
|
2544
|
-
hoursInputEl.bind('mousewheel', function(e) {
|
2789
|
+
|
2790
|
+
hoursInputEl.bind('mousewheel wheel', function(e) {
|
2545
2791
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
|
2546
2792
|
e.preventDefault();
|
2547
2793
|
});
|
2548
2794
|
|
2549
|
-
minutesInputEl.bind('mousewheel', function(e) {
|
2795
|
+
minutesInputEl.bind('mousewheel wheel', function(e) {
|
2550
2796
|
scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
|
2551
2797
|
e.preventDefault();
|
2552
2798
|
});
|
@@ -2633,10 +2879,8 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2633
2879
|
|
2634
2880
|
function addMinutes( minutes ) {
|
2635
2881
|
var dt = new Date( selected.getTime() + minutes * 60000 );
|
2636
|
-
|
2637
|
-
|
2638
|
-
}
|
2639
|
-
selected.setTime( dt.getTime() );
|
2882
|
+
selected.setHours( dt.getHours() );
|
2883
|
+
selected.setMinutes( dt.getMinutes() );
|
2640
2884
|
scope.model = new Date( selected );
|
2641
2885
|
}
|
2642
2886
|
|
@@ -2658,6 +2902,7 @@ angular.module('ui.bootstrap.timepicker', [])
|
|
2658
2902
|
}
|
2659
2903
|
};
|
2660
2904
|
}]);
|
2905
|
+
|
2661
2906
|
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
2662
2907
|
|
2663
2908
|
/**
|
@@ -2697,7 +2942,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2697
2942
|
require:'ngModel',
|
2698
2943
|
link:function (originalScope, element, attrs, modelCtrl) {
|
2699
2944
|
|
2700
|
-
|
2945
|
+
//SUPPORTED ATTRIBUTES (OPTIONS)
|
2701
2946
|
|
2702
2947
|
//minimal no of characters that needs to be entered before typeahead kicks-in
|
2703
2948
|
var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
|
@@ -2705,16 +2950,26 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2705
2950
|
//minimal wait time after last character typed before typehead kicks-in
|
2706
2951
|
var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
|
2707
2952
|
|
2708
|
-
//expressions used by typeahead
|
2709
|
-
var parserResult = typeaheadParser.parse(attrs.typeahead);
|
2710
|
-
|
2711
2953
|
//should it restrict model values to the ones selected from the popup only?
|
2712
2954
|
var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false;
|
2713
2955
|
|
2956
|
+
//binding to a variable that indicates if matches are being retrieved asynchronously
|
2714
2957
|
var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;
|
2715
2958
|
|
2959
|
+
//a callback executed when a match is selected
|
2716
2960
|
var onSelectCallback = $parse(attrs.typeaheadOnSelect);
|
2717
2961
|
|
2962
|
+
var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined;
|
2963
|
+
|
2964
|
+
//INTERNAL VARIABLES
|
2965
|
+
|
2966
|
+
//model setter executed upon match selection
|
2967
|
+
var $setModelValue = $parse(attrs.ngModel).assign;
|
2968
|
+
|
2969
|
+
//expressions used by typeahead
|
2970
|
+
var parserResult = typeaheadParser.parse(attrs.typeahead);
|
2971
|
+
|
2972
|
+
|
2718
2973
|
//pop-up element used to display matches
|
2719
2974
|
var popUpEl = angular.element('<typeahead-popup></typeahead-popup>');
|
2720
2975
|
popUpEl.attr({
|
@@ -2724,6 +2979,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2724
2979
|
query: 'query',
|
2725
2980
|
position: 'position'
|
2726
2981
|
});
|
2982
|
+
//custom item template
|
2983
|
+
if (angular.isDefined(attrs.typeaheadTemplateUrl)) {
|
2984
|
+
popUpEl.attr('template-url', attrs.typeaheadTemplateUrl);
|
2985
|
+
}
|
2727
2986
|
|
2728
2987
|
//create a child scope for the typeahead directive so we are not polluting original scope
|
2729
2988
|
//with typeahead-specific data (matches, query etc.)
|
@@ -2783,55 +3042,69 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2783
3042
|
//we need to propagate user's query so we can higlight matches
|
2784
3043
|
scope.query = undefined;
|
2785
3044
|
|
3045
|
+
//Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
|
3046
|
+
var timeoutPromise;
|
3047
|
+
|
2786
3048
|
//plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
|
2787
3049
|
//$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
|
2788
3050
|
modelCtrl.$parsers.push(function (inputValue) {
|
2789
3051
|
|
2790
|
-
var timeoutId;
|
2791
|
-
|
2792
3052
|
resetMatches();
|
2793
|
-
if (
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2797
|
-
if (waitTime > 0) {
|
2798
|
-
if (timeoutId) {
|
2799
|
-
$timeout.cancel(timeoutId);//cancel previous timeout
|
2800
|
-
}
|
2801
|
-
timeoutId = $timeout(function () {
|
2802
|
-
getMatchesAsync(inputValue);
|
2803
|
-
}, waitTime);
|
2804
|
-
} else {
|
2805
|
-
getMatchesAsync(inputValue);
|
3053
|
+
if (inputValue && inputValue.length >= minSearch) {
|
3054
|
+
if (waitTime > 0) {
|
3055
|
+
if (timeoutPromise) {
|
3056
|
+
$timeout.cancel(timeoutPromise);//cancel previous timeout
|
2806
3057
|
}
|
3058
|
+
timeoutPromise = $timeout(function () {
|
3059
|
+
getMatchesAsync(inputValue);
|
3060
|
+
}, waitTime);
|
3061
|
+
} else {
|
3062
|
+
getMatchesAsync(inputValue);
|
2807
3063
|
}
|
2808
3064
|
}
|
2809
3065
|
|
2810
3066
|
return isEditable ? inputValue : undefined;
|
2811
3067
|
});
|
2812
3068
|
|
2813
|
-
modelCtrl.$
|
3069
|
+
modelCtrl.$formatters.push(function (modelValue) {
|
3070
|
+
|
3071
|
+
var candidateViewValue, emptyViewValue;
|
2814
3072
|
var locals = {};
|
2815
|
-
|
2816
|
-
|
2817
|
-
|
2818
|
-
|
3073
|
+
|
3074
|
+
if (inputFormatter) {
|
3075
|
+
|
3076
|
+
locals['$model'] = modelValue;
|
3077
|
+
return inputFormatter(originalScope, locals);
|
3078
|
+
|
3079
|
+
} else {
|
3080
|
+
locals[parserResult.itemName] = modelValue;
|
3081
|
+
|
3082
|
+
//it might happen that we don't have enough info to properly render input value
|
3083
|
+
//we need to check for this situation and simply return model value if we can't apply custom formatting
|
3084
|
+
candidateViewValue = parserResult.viewMapper(originalScope, locals);
|
3085
|
+
emptyViewValue = parserResult.viewMapper(originalScope, {});
|
3086
|
+
|
3087
|
+
return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue;
|
3088
|
+
}
|
3089
|
+
});
|
2819
3090
|
|
2820
3091
|
scope.select = function (activeIdx) {
|
2821
3092
|
//called from within the $digest() cycle
|
2822
3093
|
var locals = {};
|
2823
3094
|
var model, item;
|
2824
|
-
locals[parserResult.itemName] = item = selected = scope.matches[activeIdx].model;
|
2825
3095
|
|
2826
|
-
|
2827
|
-
|
2828
|
-
|
2829
|
-
|
3096
|
+
locals[parserResult.itemName] = item = scope.matches[activeIdx].model;
|
3097
|
+
model = parserResult.modelMapper(originalScope, locals);
|
3098
|
+
$setModelValue(originalScope, model);
|
3099
|
+
|
3100
|
+
onSelectCallback(originalScope, {
|
2830
3101
|
$item: item,
|
2831
3102
|
$model: model,
|
2832
|
-
$label: parserResult.viewMapper(
|
3103
|
+
$label: parserResult.viewMapper(originalScope, locals)
|
2833
3104
|
});
|
2834
3105
|
|
3106
|
+
//return focus to the input element if a mach was selected via a mouse click event
|
3107
|
+
resetMatches();
|
2835
3108
|
element[0].focus();
|
2836
3109
|
};
|
2837
3110
|
|
@@ -2888,9 +3161,11 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2888
3161
|
select:'&'
|
2889
3162
|
},
|
2890
3163
|
replace:true,
|
2891
|
-
templateUrl:'template/typeahead/typeahead.html',
|
3164
|
+
templateUrl:'template/typeahead/typeahead-popup.html',
|
2892
3165
|
link:function (scope, element, attrs) {
|
2893
3166
|
|
3167
|
+
scope.templateUrl = attrs.templateUrl;
|
3168
|
+
|
2894
3169
|
scope.isOpen = function () {
|
2895
3170
|
return scope.matches.length > 0;
|
2896
3171
|
};
|
@@ -2910,6 +3185,23 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2910
3185
|
};
|
2911
3186
|
})
|
2912
3187
|
|
3188
|
+
.directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) {
|
3189
|
+
return {
|
3190
|
+
restrict:'E',
|
3191
|
+
scope:{
|
3192
|
+
index:'=',
|
3193
|
+
match:'=',
|
3194
|
+
query:'='
|
3195
|
+
},
|
3196
|
+
link:function (scope, element, attrs) {
|
3197
|
+
var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html';
|
3198
|
+
$http.get(tplUrl, {cache: $templateCache}).success(function(tplContent){
|
3199
|
+
element.replaceWith($compile(tplContent.trim())(scope));
|
3200
|
+
});
|
3201
|
+
}
|
3202
|
+
};
|
3203
|
+
}])
|
3204
|
+
|
2913
3205
|
.filter('typeaheadHighlight', function() {
|
2914
3206
|
|
2915
3207
|
function escapeRegexp(queryToEscape) {
|
@@ -2920,7 +3212,6 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])
|
|
2920
3212
|
return query ? matchItem.replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : query;
|
2921
3213
|
};
|
2922
3214
|
});
|
2923
|
-
|
2924
3215
|
angular.module("template/accordion/accordion-group.html", []).run(["$templateCache", function($templateCache) {
|
2925
3216
|
$templateCache.put("template/accordion/accordion-group.html",
|
2926
3217
|
"<div class=\"accordion-group\">\n" +
|
@@ -2971,12 +3262,12 @@ angular.module("template/carousel/slide.html", []).run(["$templateCache", functi
|
|
2971
3262
|
|
2972
3263
|
angular.module("template/datepicker/datepicker.html", []).run(["$templateCache", function($templateCache) {
|
2973
3264
|
$templateCache.put("template/datepicker/datepicker.html",
|
2974
|
-
"<table
|
3265
|
+
"<table>\n" +
|
2975
3266
|
" <thead>\n" +
|
2976
3267
|
" <tr class=\"text-center\">\n" +
|
2977
|
-
" <th><button class=\"btn pull-left\" ng-click=\"move(-1)\"><i class=\"icon-chevron-left\"></i></button></th>\n" +
|
2978
|
-
" <th colspan=\"{{rows[0].length - 2 + showWeekNumbers}}\"><button class=\"btn btn-block\" ng-click=\"toggleMode()\"><strong>{{title}}</strong></button></th>\n" +
|
2979
|
-
" <th><button class=\"btn pull-right\" ng-click=\"move(1)\"><i class=\"icon-chevron-right\"></i></button></th>\n" +
|
3268
|
+
" <th><button type=\"button\" class=\"btn pull-left\" ng-click=\"move(-1)\"><i class=\"icon-chevron-left\"></i></button></th>\n" +
|
3269
|
+
" <th colspan=\"{{rows[0].length - 2 + showWeekNumbers}}\"><button type=\"button\" class=\"btn btn-block\" ng-click=\"toggleMode()\"><strong>{{title}}</strong></button></th>\n" +
|
3270
|
+
" <th><button type=\"button\" class=\"btn pull-right\" ng-click=\"move(1)\"><i class=\"icon-chevron-right\"></i></button></th>\n" +
|
2980
3271
|
" </tr>\n" +
|
2981
3272
|
" <tr class=\"text-center\" ng-show=\"labels.length > 0\">\n" +
|
2982
3273
|
" <th ng-show=\"showWeekNumbers\">#</th>\n" +
|
@@ -2987,7 +3278,7 @@ angular.module("template/datepicker/datepicker.html", []).run(["$templateCache",
|
|
2987
3278
|
" <tr ng-repeat=\"row in rows\">\n" +
|
2988
3279
|
" <td ng-show=\"showWeekNumbers\" class=\"text-center\"><em>{{ getWeekNumber(row) }}</em></td>\n" +
|
2989
3280
|
" <td ng-repeat=\"dt in row\" class=\"text-center\">\n" +
|
2990
|
-
" <button style=\"width:100%;\" class=\"btn\" ng-class=\"{'btn-info': dt.
|
3281
|
+
" <button type=\"button\" style=\"width:100%;\" class=\"btn\" ng-class=\"{'btn-info': dt.selected}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{muted: dt.secondary}\">{{dt.label}}</span></button>\n" +
|
2991
3282
|
" </td>\n" +
|
2992
3283
|
" </tr>\n" +
|
2993
3284
|
" </tbody>\n" +
|
@@ -2995,23 +3286,39 @@ angular.module("template/datepicker/datepicker.html", []).run(["$templateCache",
|
|
2995
3286
|
"");
|
2996
3287
|
}]);
|
2997
3288
|
|
3289
|
+
angular.module("template/datepicker/popup.html", []).run(["$templateCache", function($templateCache) {
|
3290
|
+
$templateCache.put("template/datepicker/popup.html",
|
3291
|
+
"<ul class=\"dropdown-menu\" ng-style=\"{display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'}\" class=\"dropdown-menu\">\n" +
|
3292
|
+
" <li ng-transclude></li>\n" +
|
3293
|
+
" <li class=\"divider\"></li>\n" +
|
3294
|
+
" <li style=\"padding: 9px;\">\n" +
|
3295
|
+
" <span class=\"btn-group\">\n" +
|
3296
|
+
" <button class=\"btn btn-small btn-inverse\" ng-click=\"today()\">Today</button>\n" +
|
3297
|
+
" <button class=\"btn btn-small btn-info\" ng-click=\"showWeeks = ! showWeeks\" ng-class=\"{active: showWeeks}\">Weeks</button>\n" +
|
3298
|
+
" <button class=\"btn btn-small btn-danger\" ng-click=\"clear()\">Clear</button>\n" +
|
3299
|
+
" </span>\n" +
|
3300
|
+
" <button class=\"btn btn-small btn-success pull-right\" ng-click=\"isOpen = false\">Close</button>\n" +
|
3301
|
+
" </li>\n" +
|
3302
|
+
"</ul>");
|
3303
|
+
}]);
|
3304
|
+
|
2998
3305
|
angular.module("template/dialog/message.html", []).run(["$templateCache", function($templateCache) {
|
2999
3306
|
$templateCache.put("template/dialog/message.html",
|
3000
3307
|
"<div class=\"modal-header\">\n" +
|
3001
|
-
"
|
3308
|
+
" <h3>{{ title }}</h3>\n" +
|
3002
3309
|
"</div>\n" +
|
3003
3310
|
"<div class=\"modal-body\">\n" +
|
3004
|
-
"
|
3311
|
+
" <p>{{ message }}</p>\n" +
|
3005
3312
|
"</div>\n" +
|
3006
3313
|
"<div class=\"modal-footer\">\n" +
|
3007
|
-
"
|
3314
|
+
" <button ng-repeat=\"btn in buttons\" ng-click=\"close(btn.result)\" class=\"btn\" ng-class=\"btn.cssClass\">{{ btn.label }}</button>\n" +
|
3008
3315
|
"</div>\n" +
|
3009
3316
|
"");
|
3010
3317
|
}]);
|
3011
3318
|
|
3012
3319
|
angular.module("template/modal/backdrop.html", []).run(["$templateCache", function($templateCache) {
|
3013
3320
|
$templateCache.put("template/modal/backdrop.html",
|
3014
|
-
"<div class=\"modal-backdrop\"></div>");
|
3321
|
+
"<div class=\"modal-backdrop fade in\"></div>");
|
3015
3322
|
}]);
|
3016
3323
|
|
3017
3324
|
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
|
@@ -3082,9 +3389,8 @@ angular.module("template/progressbar/progress.html", []).run(["$templateCache",
|
|
3082
3389
|
angular.module("template/rating/rating.html", []).run(["$templateCache", function($templateCache) {
|
3083
3390
|
$templateCache.put("template/rating/rating.html",
|
3084
3391
|
"<span ng-mouseleave=\"reset()\">\n" +
|
3085
|
-
"
|
3086
|
-
"</span
|
3087
|
-
"");
|
3392
|
+
" <i ng-repeat=\"number in range\" ng-mouseenter=\"enter(number)\" ng-click=\"rate(number)\" ng-class=\"{'icon-star': number <= val, 'icon-star-empty': number > val}\"></i>\n" +
|
3393
|
+
"</span>");
|
3088
3394
|
}]);
|
3089
3395
|
|
3090
3396
|
angular.module("template/tabs/pane.html", []).run(["$templateCache", function($templateCache) {
|
@@ -3114,19 +3420,26 @@ angular.module("template/tabs/tabs.html", []).run(["$templateCache", function($t
|
|
3114
3420
|
"");
|
3115
3421
|
}]);
|
3116
3422
|
|
3423
|
+
angular.module("template/tabs/tabset-titles.html", []).run(["$templateCache", function($templateCache) {
|
3424
|
+
$templateCache.put("template/tabs/tabset-titles.html",
|
3425
|
+
"<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n" +
|
3426
|
+
"</ul>\n" +
|
3427
|
+
"");
|
3428
|
+
}]);
|
3429
|
+
|
3117
3430
|
angular.module("template/tabs/tabset.html", []).run(["$templateCache", function($templateCache) {
|
3118
3431
|
$templateCache.put("template/tabs/tabset.html",
|
3119
3432
|
"\n" +
|
3120
|
-
"<div class=\"tabbable\">\n" +
|
3121
|
-
" <
|
3122
|
-
" </ul>\n" +
|
3433
|
+
"<div class=\"tabbable\" ng-class=\"{'tabs-right': direction == 'right', 'tabs-left': direction == 'left', 'tabs-below': direction == 'below'}\">\n" +
|
3434
|
+
" <div tabset-titles=\"tabsAbove\"></div>\n" +
|
3123
3435
|
" <div class=\"tab-content\">\n" +
|
3124
3436
|
" <div class=\"tab-pane\" \n" +
|
3125
3437
|
" ng-repeat=\"tab in tabs\" \n" +
|
3126
3438
|
" ng-class=\"{active: tab.active}\"\n" +
|
3127
|
-
" tab-content-transclude=\"tab\"
|
3439
|
+
" tab-content-transclude=\"tab\">\n" +
|
3128
3440
|
" </div>\n" +
|
3129
3441
|
" </div>\n" +
|
3442
|
+
" <div tabset-titles=\"!tabsAbove\"></div>\n" +
|
3130
3443
|
"</div>\n" +
|
3131
3444
|
"");
|
3132
3445
|
}]);
|
@@ -3134,27 +3447,41 @@ angular.module("template/tabs/tabset.html", []).run(["$templateCache", function(
|
|
3134
3447
|
angular.module("template/timepicker/timepicker.html", []).run(["$templateCache", function($templateCache) {
|
3135
3448
|
$templateCache.put("template/timepicker/timepicker.html",
|
3136
3449
|
"<table class=\"form-inline\">\n" +
|
3137
|
-
"
|
3138
|
-
"
|
3139
|
-
"
|
3140
|
-
"
|
3141
|
-
"
|
3142
|
-
"
|
3143
|
-
"
|
3144
|
-
"
|
3145
|
-
"
|
3146
|
-
"
|
3147
|
-
"
|
3148
|
-
"
|
3149
|
-
"
|
3150
|
-
"
|
3151
|
-
"
|
3152
|
-
"
|
3153
|
-
"
|
3154
|
-
"
|
3450
|
+
" <tr class=\"text-center\">\n" +
|
3451
|
+
" <td><a ng-click=\"incrementHours()\" class=\"btn btn-link\"><i class=\"icon-chevron-up\"></i></a></td>\n" +
|
3452
|
+
" <td> </td>\n" +
|
3453
|
+
" <td><a ng-click=\"incrementMinutes()\" class=\"btn btn-link\"><i class=\"icon-chevron-up\"></i></a></td>\n" +
|
3454
|
+
" <td ng-show=\"showMeridian\"></td>\n" +
|
3455
|
+
" </tr>\n" +
|
3456
|
+
" <tr>\n" +
|
3457
|
+
" <td class=\"control-group\" ng-class=\"{'error': !validHours}\"><input type=\"text\" ng-model=\"hours\" ng-change=\"updateHours()\" class=\"span1 text-center\" ng-mousewheel=\"incrementHours()\" ng-readonly=\"readonlyInput\" maxlength=\"2\" /></td>\n" +
|
3458
|
+
" <td>:</td>\n" +
|
3459
|
+
" <td class=\"control-group\" ng-class=\"{'error': !validMinutes}\"><input type=\"text\" ng-model=\"minutes\" ng-change=\"updateMinutes()\" class=\"span1 text-center\" ng-readonly=\"readonlyInput\" maxlength=\"2\"></td>\n" +
|
3460
|
+
" <td ng-show=\"showMeridian\"><button ng-click=\"toggleMeridian()\" class=\"btn text-center\">{{meridian}}</button></td>\n" +
|
3461
|
+
" </tr>\n" +
|
3462
|
+
" <tr class=\"text-center\">\n" +
|
3463
|
+
" <td><a ng-click=\"decrementHours()\" class=\"btn btn-link\"><i class=\"icon-chevron-down\"></i></a></td>\n" +
|
3464
|
+
" <td> </td>\n" +
|
3465
|
+
" <td><a ng-click=\"decrementMinutes()\" class=\"btn btn-link\"><i class=\"icon-chevron-down\"></i></a></td>\n" +
|
3466
|
+
" <td ng-show=\"showMeridian\"></td>\n" +
|
3467
|
+
" </tr>\n" +
|
3155
3468
|
"</table>");
|
3156
3469
|
}]);
|
3157
3470
|
|
3471
|
+
angular.module("template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) {
|
3472
|
+
$templateCache.put("template/typeahead/typeahead-match.html",
|
3473
|
+
"<a tabindex=\"-1\" ng-bind-html-unsafe=\"match.label | typeaheadHighlight:query\"></a>");
|
3474
|
+
}]);
|
3475
|
+
|
3476
|
+
angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
|
3477
|
+
$templateCache.put("template/typeahead/typeahead-popup.html",
|
3478
|
+
"<ul class=\"typeahead dropdown-menu\" ng-style=\"{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
|
3479
|
+
" <li ng-repeat=\"match in matches\" ng-class=\"{active: isActive($index) }\" ng-mouseenter=\"selectActive($index)\" ng-click=\"selectMatch($index)\">\n" +
|
3480
|
+
" <typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></typeahead-match>\n" +
|
3481
|
+
" </li>\n" +
|
3482
|
+
"</ul>");
|
3483
|
+
}]);
|
3484
|
+
|
3158
3485
|
angular.module("template/typeahead/typeahead.html", []).run(["$templateCache", function($templateCache) {
|
3159
3486
|
$templateCache.put("template/typeahead/typeahead.html",
|
3160
3487
|
"<ul class=\"typeahead dropdown-menu\" ng-style=\"{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}\">\n" +
|