Bootstrap 3 javascript checkbox and radio button toggle prevents angular's ng-model from updating on input #4516
Description
When using Bootstrap 3's javascript buttons for checkboxes, the checkbox's ng-model does not get updated. Looking into the source code for both I know why.
Bootstrap 3 html for checkbox button group:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="checkbox"> Option 1
</label>
<label class="btn btn-primary">
<input type="checkbox"> Option 2
</label>
<label class="btn btn-primary">
<input type="checkbox"> Option 3
</label>
</div>
Bootstrap 3 javascript for button toggle:
Button.prototype.toggle = function () {
var $parent = this.$element.closest('[data-toggle="buttons"]')
if ($parent.length) {
var $input = this.$element.find('input')
.prop('checked', !this.$element.hasClass('active'))
.trigger('change')
if ($input.prop('type') === 'radio') $parent.find('.active').removeClass('active')
}
this.$element.toggleClass('active')
}
Angular source for checkbox (radio button is similar):
function checkboxInputType(scope, element, attr, ctrl) {
var trueValue = attr.ngTrueValue,
falseValue = attr.ngFalseValue;
if (!isString(trueValue)) trueValue = true;
if (!isString(falseValue)) falseValue = false;
element.on('click', function () {
scope.$apply(function () {
ctrl.$setViewValue(element[0].checked);
});
});
ctrl.$render = function () {
element[0].checked = ctrl.$viewValue;
};
ctrl.$formatters.push(function (value) {
return value === trueValue;
});
ctrl.$parsers.push(function (value) {
return value ? trueValue : falseValue;
});
}
The problem is Angular's checkbox is listening for the click
event whereas Bootstrap's button handles the click
event and fires the change
event on the checkbox input.
I wrote a simple directive that does exactly what Angular's checkbox click
event listener does but instead listens for the change
event.
appModule.directive('mccCheckboxDetectChange', [function mccCheckboxDetectChange() {
return {
replace: false,
require: 'ngModel',
scope: false,
link: function (scope, element, attrs, ngModelCtrl) {
element.on('change', function () {
scope.$apply(function () {
ngModelCtrl.$setViewValue(element[0].checked);
});
});
}
};
}]);
Is there a reason why Angular listens for the click
event for radio and checkboxes instead of the change
event? Should I create a pull request and change the click
event listener to be a change
event listener? This would be my first pull request.
Thanks!
Philip