commit | author | age
|
1759c2
|
1 |
/** |
RM |
2 |
* angular-strap |
|
3 |
* @version v2.0.3 - 2014-05-30 |
|
4 |
* @link http://mgcrea.github.io/angular-strap |
|
5 |
* @author Olivier Louvignes (olivier@mg-crea.com) |
|
6 |
* @license MIT License, http://www.opensource.org/licenses/MIT |
|
7 |
*/ |
|
8 |
'use strict'; |
|
9 |
angular.module('mgcrea.ngStrap.button', []).provider('$button', function () { |
|
10 |
var defaults = this.defaults = { |
|
11 |
activeClass: 'active', |
|
12 |
toggleEvent: 'click' |
|
13 |
}; |
|
14 |
this.$get = function () { |
|
15 |
return { defaults: defaults }; |
|
16 |
}; |
|
17 |
}).directive('bsCheckboxGroup', function () { |
|
18 |
return { |
|
19 |
restrict: 'A', |
|
20 |
require: 'ngModel', |
|
21 |
compile: function postLink(element, attr) { |
|
22 |
element.attr('data-toggle', 'buttons'); |
|
23 |
element.removeAttr('ng-model'); |
|
24 |
var children = element[0].querySelectorAll('input[type="checkbox"]'); |
|
25 |
angular.forEach(children, function (child) { |
|
26 |
var childEl = angular.element(child); |
|
27 |
childEl.attr('bs-checkbox', ''); |
|
28 |
childEl.attr('ng-model', attr.ngModel + '.' + childEl.attr('value')); |
|
29 |
}); |
|
30 |
} |
|
31 |
}; |
|
32 |
}).directive('bsCheckbox', [ |
|
33 |
'$button', |
|
34 |
'$$rAF', |
|
35 |
function ($button, $$rAF) { |
|
36 |
var defaults = $button.defaults; |
|
37 |
var constantValueRegExp = /^(true|false|\d+)$/; |
|
38 |
return { |
|
39 |
restrict: 'A', |
|
40 |
require: 'ngModel', |
|
41 |
link: function postLink(scope, element, attr, controller) { |
|
42 |
var options = defaults; |
|
43 |
// Support label > input[type="checkbox"] |
|
44 |
var isInput = element[0].nodeName === 'INPUT'; |
|
45 |
var activeElement = isInput ? element.parent() : element; |
|
46 |
var trueValue = angular.isDefined(attr.trueValue) ? attr.trueValue : true; |
|
47 |
if (constantValueRegExp.test(attr.trueValue)) { |
|
48 |
trueValue = scope.$eval(attr.trueValue); |
|
49 |
} |
|
50 |
var falseValue = angular.isDefined(attr.falseValue) ? attr.falseValue : false; |
|
51 |
if (constantValueRegExp.test(attr.falseValue)) { |
|
52 |
falseValue = scope.$eval(attr.falseValue); |
|
53 |
} |
|
54 |
// Parse exotic values |
|
55 |
var hasExoticValues = typeof trueValue !== 'boolean' || typeof falseValue !== 'boolean'; |
|
56 |
if (hasExoticValues) { |
|
57 |
controller.$parsers.push(function (viewValue) { |
|
58 |
// console.warn('$parser', element.attr('ng-model'), 'viewValue', viewValue); |
|
59 |
return viewValue ? trueValue : falseValue; |
|
60 |
}); |
|
61 |
// Fix rendering for exotic values |
|
62 |
scope.$watch(attr.ngModel, function (newValue, oldValue) { |
|
63 |
controller.$render(); |
|
64 |
}); |
|
65 |
} |
|
66 |
// model -> view |
|
67 |
controller.$render = function () { |
|
68 |
// console.warn('$render', element.attr('ng-model'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue); |
|
69 |
var isActive = angular.equals(controller.$modelValue, trueValue); |
|
70 |
$$rAF(function () { |
|
71 |
if (isInput) |
|
72 |
element[0].checked = isActive; |
|
73 |
activeElement.toggleClass(options.activeClass, isActive); |
|
74 |
}); |
|
75 |
}; |
|
76 |
// view -> model |
|
77 |
element.bind(options.toggleEvent, function () { |
|
78 |
scope.$apply(function () { |
|
79 |
// console.warn('!click', element.attr('ng-model'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue); |
|
80 |
if (!isInput) { |
|
81 |
controller.$setViewValue(!activeElement.hasClass('active')); |
|
82 |
} |
|
83 |
if (!hasExoticValues) { |
|
84 |
controller.$render(); |
|
85 |
} |
|
86 |
}); |
|
87 |
}); |
|
88 |
} |
|
89 |
}; |
|
90 |
} |
|
91 |
]).directive('bsRadioGroup', function () { |
|
92 |
return { |
|
93 |
restrict: 'A', |
|
94 |
require: 'ngModel', |
|
95 |
compile: function postLink(element, attr) { |
|
96 |
element.attr('data-toggle', 'buttons'); |
|
97 |
element.removeAttr('ng-model'); |
|
98 |
var children = element[0].querySelectorAll('input[type="radio"]'); |
|
99 |
angular.forEach(children, function (child) { |
|
100 |
angular.element(child).attr('bs-radio', ''); |
|
101 |
angular.element(child).attr('ng-model', attr.ngModel); |
|
102 |
}); |
|
103 |
} |
|
104 |
}; |
|
105 |
}).directive('bsRadio', [ |
|
106 |
'$button', |
|
107 |
'$$rAF', |
|
108 |
function ($button, $$rAF) { |
|
109 |
var defaults = $button.defaults; |
|
110 |
var constantValueRegExp = /^(true|false|\d+)$/; |
|
111 |
return { |
|
112 |
restrict: 'A', |
|
113 |
require: 'ngModel', |
|
114 |
link: function postLink(scope, element, attr, controller) { |
|
115 |
var options = defaults; |
|
116 |
// Support `label > input[type="radio"]` markup |
|
117 |
var isInput = element[0].nodeName === 'INPUT'; |
|
118 |
var activeElement = isInput ? element.parent() : element; |
|
119 |
var value = constantValueRegExp.test(attr.value) ? scope.$eval(attr.value) : attr.value; |
|
120 |
// model -> view |
|
121 |
controller.$render = function () { |
|
122 |
// console.warn('$render', element.attr('value'), 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue, 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue); |
|
123 |
var isActive = angular.equals(controller.$modelValue, value); |
|
124 |
$$rAF(function () { |
|
125 |
if (isInput) |
|
126 |
element[0].checked = isActive; |
|
127 |
activeElement.toggleClass(options.activeClass, isActive); |
|
128 |
}); |
|
129 |
}; |
|
130 |
// view -> model |
|
131 |
element.bind(options.toggleEvent, function () { |
|
132 |
scope.$apply(function () { |
|
133 |
// console.warn('!click', element.attr('value'), 'controller.$viewValue', typeof controller.$viewValue, controller.$viewValue, 'controller.$modelValue', typeof controller.$modelValue, controller.$modelValue); |
|
134 |
controller.$setViewValue(value); |
|
135 |
controller.$render(); |
|
136 |
}); |
|
137 |
}); |
|
138 |
} |
|
139 |
}; |
|
140 |
} |
|
141 |
]); |