Skip to content

Commit bbccfe3

Browse files
authored
Merge pull request #34 from bertysentry/feature/issue-33-width-issue
Feature/issue 33 width issue
2 parents d3a22f5 + 47fb2c6 commit bbccfe3

File tree

6 files changed

+9501
-166
lines changed

6 files changed

+9501
-166
lines changed

bower.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525
"**/.*"
2626
],
2727
"dependencies": {
28-
"angular": ">=1.3.0",
28+
"angular": ">=1.7.0",
2929
"bootstrap": ">=3.2.0"
3030
},
3131
"devDependencies": {
32-
"angular-mocks": ">=1.3.0",
33-
"angular-scenario": ">=1.3.0",
34-
"angular": ">=1.3.0"
32+
"angular-mocks": ">=1.7.0",
33+
"angular-scenario": ">=1.7.0",
34+
"angular": ">=1.7.0"
3535
},
3636
"license": "MIT"
3737
}

dist/angular-bootstrap-toggle.js

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,16 @@
4141
* Description: Class for "on" state from one of standard bootstrap button types.
4242
* Possible values: btn-default, btn-primary, btn-success, btn-info, btn-warning, btn-danger
4343
*/
44-
onstyle: 'btn-primary',
44+
onClass: 'btn-primary',
45+
onstyle: '', /* for backward compatibility only */
4546
/**
4647
* Type: string
4748
* Default: "btn-default"
4849
* Description: Class for "off" state from one of standard bootstrap button types.
4950
* Possible values: btn-default, btn-primary,btn- success, btn-info, btn-warning, btn-danger
5051
*/
51-
offstyle: 'btn-default',
52+
offClass: 'btn-default',
53+
offstyle: '', /* for some backward compatibility only */
5254
/**
5355
* Type: JSON string
5456
* Default: ''
@@ -77,11 +79,11 @@
7779
* manipulates this attribute, plus there is additional code that propagates its value to child elements.
7880
* Applying "disabled" to <toggle> itself apparently does nothing, but when its value is propagated to
7981
* two child <label> elements, it allows us to disable the widget.
80-
* Note that attribute "diasbled" is not the same as ng-disabled Angular directive. In most cases, you should
81-
* use <toggle ... ng-disabled="expression"> (not <toggle ... disabled="{{expression}}">) for this to work
82-
* properly.
83-
* [Per HTML specs, the "disabled" property does not need a value. Just mentioning it is enough. Angular will,
84-
* however, also add the value "disabled" (< ... disabled="disabled">)]
82+
* Note that attribute "diasbled" is not the same as ng-disabled Angular directive. In most cases, you
83+
* should use <toggle ... ng-disabled="expression"> (not <toggle ... disabled="{{expression}}">) for this
84+
* to work properly.
85+
* [Per HTML specs, the "disabled" property does not need a value. Just mentioning it is enough. Angular
86+
* will, however, also add the value "disabled" (< ... disabled="disabled">)]
8587
*/
8688
disabled: false,
8789
})
@@ -91,19 +93,12 @@
9193
function ($scope, $attrs, $interpolate, $log, toggleConfig, $toggleSuppressError) {
9294
var self = this;
9395
var labels, spans, divs;
94-
var ngModelCtrl = {$setViewValue: angular.noop};
96+
var ngModelCtrl;
9597
var toggleConfigKeys = Object.keys(toggleConfig);
9698

9799
// Configuration attributes
98100
angular.forEach( toggleConfigKeys, function (k, i) {
99101
if (angular.isDefined($attrs[k])) {
100-
/*
101-
if (i < toggleConfigKeys.length) {
102-
self[k] = $interpolate($attrs[k])($scope.$parent);
103-
} else {
104-
self[k] = $scope.$parent.$eval($attrs[k]);
105-
}
106-
*/
107102
switch ( typeof toggleConfig[k] ) {
108103
case 'string':
109104
self[k] = $interpolate($attrs[k])($scope.$parent);
@@ -119,24 +114,36 @@
119114
}
120115
});
121116

117+
// Special treatment for onstyle and offstyle, now deprecated attributes:
118+
// If set, we will use their values for onClass and offClass respectively
119+
if (self.onstyle) {
120+
self.onClass = self.onstyle;
121+
}
122+
if (self.offstyle) {
123+
self.offClass = self.offstyle;
124+
}
125+
122126
this.init = function (ngModelCtrl_) {
123127
ngModelCtrl = ngModelCtrl_;
124128

125-
labels = self.element.find('label');
126-
spans = self.element.find('span');
127-
divs = self.element.find('div');
128-
// ^-- divs[0] is the DIV that has class="toggle btn"
129-
// divs[1] is a child of [0] and has class="toggle-group"
129+
var labels = self.element.find('label');
130+
var spans = self.element.find('span');
131+
var divs = self.element.find('div');
132+
133+
self.wrapperElement = divs[0];
134+
self.onElement = labels[0];
135+
self.offElement = labels[1];
136+
self.handleElement = spans[0];
130137

131138
// Set wigget's visible text such as On/Off or Enable/Disable
132-
angular.element(labels[0]).html(self.on);
133-
angular.element(labels[1]).html(self.off);
139+
angular.element(self.onElement).html(self.on);
140+
angular.element(self.offElement).html(self.off);
134141

135142
self.computeStyle();
136143

137144
ngModelCtrl.$render = function () {
138145
self.toggle();
139-
}
146+
};
140147

141148
// ng-change (for optional onChange event handler)
142149
if (angular.isDefined($attrs.ngChange)) {
@@ -152,79 +159,68 @@
152159
// The property must be propagated to lables and span inside the toggle-group container. This
153160
// triggers .btn[disabled] style (cursor: not-allowed; opacity: 0.65;) but it does not prohibit
154161
// the click event. Click event is handled in .onSwitch().
155-
angular.element(labels[0]).attr('disabled', self.disabled);
156-
angular.element(labels[1]).attr('disabled', self.disabled);
157-
angular.element( spans[0]).attr('disabled', self.disabled);
162+
angular.element(self.onElement).attr('disabled', self.disabled);
163+
angular.element(self.offElement).attr('disabled', self.disabled);
164+
angular.element(self.handleElement).attr('disabled', self.disabled);
158165

159166
// Build an object for widget's ng-style
160167
$scope.wrapperStyle = (self.toggleStyle) ? $scope.$parent.$eval(self.toggleStyle) : {};
161168

169+
// Calculate the proper width
162170
if (self.width) {
163171
$scope.wrapperStyle.width = self.width;
164172
} else {
165-
// INCORRECT MATH - spans[0] overlaps two side-by-side LABEL's. Half of its width should not be included in the total.
166-
//var wrapperComputedWidth = Math.max(labels[0].offsetWidth, labels[1].offsetWidth) + (spans[0].offsetWidth / 2);
167-
var wrapperComputedWidth = Math.max(labels[0].offsetWidth, labels[1].offsetWidth);
168-
var wrapperWidth = divs[0].offsetWidth;
169-
170-
if (wrapperWidth < wrapperComputedWidth) {
171-
$scope.wrapperStyle.width = wrapperComputedWidth + 'px';
172-
} else {
173-
$scope.wrapperStyle.width = wrapperWidth + 'px';
174-
}
173+
var wrapperComputedWidth = Math.max(
174+
self.onElement.scrollWidth,
175+
self.offElement.scrollWidth) + 12;
176+
$scope.wrapperStyle.width = wrapperComputedWidth + 'px';
175177
}
176178

179+
// Calculate the proper height
177180
if (self.height) {
178181
$scope.wrapperStyle.height = self.height;
179182
} else {
180-
var wrapperComputedHeight = Math.max(labels[0].offsetHeight, labels[1].offsetHeight);
181-
var wrapperHeight = divs[1].offsetHeight;
183+
var wrapperComputedHeight = Math.max(
184+
self.onElement.offsetHeight,
185+
self.offElement.offsetHeight);
186+
var wrapperHeight = self.wrapperElement.offsetHeight;
182187

183-
if (wrapperHeight < wrapperComputedHeight && self.size !== 'btn-xs' && self.size !== 'btn-sm') {
184-
$scope.wrapperStyle.height = wrapperComputedHeight + 'px';
188+
if (wrapperHeight < wrapperComputedHeight &&
189+
self.size !== 'btn-xs' && self.size !== 'btn-sm') {
190+
$scope.wrapperStyle.height = wrapperComputedHeight + 'px';
185191
} else {
186192
$scope.wrapperStyle.height = wrapperHeight + 'px';
187193
}
188194
}
189195

190196
// Build arrays that will be passed to widget's ng-class.
191-
$scope.onClass = [self.onstyle , self.size, 'toggle-on'];
192-
$scope.offClass = [self.offstyle, self.size, 'toggle-off'];
193-
$scope.handleClass = [self.size , 'toggle-handle'];
197+
$scope.onComputedClass = [self.onClass , self.size, 'toggle-on'];
198+
$scope.offComputedClass = [self.offClass, self.size, 'toggle-off'];
199+
$scope.handleComputedClass = [self.size , 'toggle-handle'];
194200
};
195201

196202
this.toggle = function () {
197-
if (angular.isDefined(ngModelCtrl.$viewValue)) {
198-
if (ngModelCtrl.$viewValue) {
199-
$scope.wrapperClass = [self.onstyle, self.size, self.style];
200-
} else {
201-
$scope.wrapperClass = [self.offstyle, 'off ', self.size, self.style];
202-
}
203-
} else {
204-
$scope.wrapperClass = [self.offstyle, 'off ', self.size, self.style];
205-
}
203+
if (ngModelCtrl.$viewValue) {
204+
angular.element(self.wrapperElement).
205+
removeClass('off ' + self.offClass).
206+
addClass(self.onClass);
207+
} else {
208+
angular.element(self.wrapperElement).
209+
addClass('off ' + self.offClass).
210+
removeClass(self.onClass);
211+
}
206212
};
207213

208214
$scope.onSwitch = function (evt) {
209-
if (self.disabled) { // prevent changing .$viewValue if .disabled == true
215+
if (self.disabled) { // prevent changing .$viewValue if .disabled == true
210216
return false;
211-
} else {
212-
ngModelCtrl.$setViewValue(!ngModelCtrl.$viewValue);
213-
ngModelCtrl.$render();
214-
}
215-
return true;
217+
} else {
218+
ngModelCtrl.$setViewValue(!ngModelCtrl.$viewValue);
219+
ngModelCtrl.$render();
220+
}
221+
return true;
216222
};
217223

218-
// Watchable data attributes
219-
angular.forEach(['ngModel'], function (key) {
220-
var watch = $scope.$parent.$watch($attrs[key], function (value) {
221-
ngModelCtrl.$render();
222-
});
223-
$scope.$parent.$on('$destroy', function () {
224-
watch();
225-
});
226-
});
227-
228224
angular.forEach( toggleConfigKeys, function (k, i) {
229225
$attrs.$observe(k, function (v) {
230226
if (self[k] !== v) {
@@ -238,14 +234,14 @@
238234
.directive('toggle', function () {
239235
return {
240236
restrict: 'E',
241-
transclude: true,
242-
template: '<div class="toggle btn" ng-class="wrapperClass" ng-style="wrapperStyle" ng-click="onSwitch($event)">' +
243-
'<div class="toggle-group">' +
244-
'<label class="btn" ng-class="onClass"></label>' +
245-
'<label class="btn active" ng-class="offClass"></label>' +
246-
'<span class="btn btn-default" ng-class="handleClass"></span>' +
247-
'</div>' +
248-
'</div>',
237+
template: '<div ng-cloak class="toggle btn off" ng-style="wrapperStyle"' +
238+
'ng-click="onSwitch($event)">' +
239+
'<div class="toggle-group">' +
240+
'<label class="btn" ng-class="onComputedClass"></label>' +
241+
'<label class="btn active" ng-class="offComputedClass"></label>' +
242+
'<span class="btn btn-default" ng-class="handleComputedClass"></span>' +
243+
'</div>' +
244+
'</div>',
249245
scope: {
250246
ngModel: '='
251247
},
@@ -254,13 +250,13 @@
254250
controllerAs: 'toggle',
255251
compile: function (element, attrs, transclude) {
256252
return {
257-
pre: function (scope, element, attrs, ctrls) {
253+
post: function (scope, element, attrs, ctrls) {
258254
var toggleCtrl = ctrls[0], ngModelCtrl = ctrls[1];
259255
toggleCtrl.element = element;
260256
toggleCtrl.init(ngModelCtrl);
261257
},
262-
post: function () {}
263-
}
258+
pre: function () {}
259+
};
264260
}
265261
};
266262
}

0 commit comments

Comments
 (0)