I have a custom knockout binding that animates a toggle switch to an 'on' or 'off' position. My problem is the update function only fires immediately after the init and not when the observable value changes. Any ideas what I'm doing wrong?
ko.bindingHandlers.toggleSwitch = {
init: function (element, valueAccessor) {
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
var value = valueUnwrapped.value;
var target = $(element);
var disabled = valueAccessor().disabled;
var id = 'ul' + (++ko.bindingHandlers['uniqueId'].currentIndex);
var html = ['<div class="switch-mask"><ul id="' + id + '"', 'class="on-off-switch">', '<li class="on-switch">' + valueAccessor().on + '</li>', '<li class="on-off-knob"></li>', '<li class="off-switch">' + valueAccessor().off + '</li>', '</ul></div>'].join('');
target.replaceWith(html);
var mainTarget = $('#' + id);
if (value()) {
mainTarget.children('.on-switch').animate({ 'margin-left': '0px' });
mainTarget.children('.on-off-knob').animate({ 'margin-left': '0px' });
}
else {
mainTarget.children('.on-switch').animate({ 'margin-left': '-28px' });
mainTarget.children('.on-off-knob').animate({ 'margin-left': '-1px' });
};
if (!disabled) {
mainTarget.on('click', function() {
//this fires every time the toggle switch is clicked.
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
if (value()) {
mainTarget.children('.on-switch').animate({ 'margin-left': '0px' });
mainTarget.children('.on-off-knob').animate({ 'margin-left': '0px' });
value(false);
} else {
mainTarget.children('.on-switch').animate({ 'margin-left': '-28px' });
mainTarget.children('.on-off-knob').animate({ 'margin-left': '-1px' });
value(true);
}
value.valueHasMutated();
});
}
},
update: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
console.log('update called');
}
};
ko.virtualElements.allowedBindings.toggleSwitch = true;
This is my binding:
<!-- ko toggleSwitch:{value:data.model.Settings.HtmlEmail,on:'On',off:'Off'}-->
<!-- /ko -->
The update event is not being fired because you're not binding directly to the observable, but to an object containing a property named value
set to the observable. How I've accomplished this in the past is to omit the update function on the custom binding and just set a subscription on the observable in the in the init function, like this:
ko.bindingHandlers.toggleSwitch = {
init: function (element, valueAccessor) {
var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
var value = valueUnwrapped.value;
/// logic omitted for clarity
value.subscribe(function(newValue) {
console.log('update called');
});
if (!disabled) {
/// omitted for clarity
}
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With