Reputation: 4287
I'm using bootstrap switch to show checkbox as a switch and I want to bind a function to this switch, so the click
data bind does not help here because the checkbox is not being clicked.
So I probably need a "change" data bind like the onChange
event that the checkbox have, but it didn't work when I tried to data bind change
event to the checkbox...
Here is my data bind:
<input type="checkbox" onText="Active" offText="Inactive"
data-bind="bootstrapSwitchOn: ActiveFlag, change: function() { UpdateStatus() }" />
The switch is renders the checkbox like this:
<div class="has-switch" tabindex="0"
<div class="switch-on">
<span class="switch-left">Active</span
<label> </label
<span class="switch-right">Inactive</span>
<input type="checkbox" ontext="Active" offtext="Inactive"
data-bind="bootstrapSwitchOn: ActiveFlag, change: function() { UpdateStatus() }">
</div>
</div>
The checkbox gets display:"none"
so it is not clicked but its state does change when clicking the switch
Upvotes: 2
Views: 2656
Reputation: 4392
Expanding on my comment:
ActiveFlag
bound to the bootstrapSwitchOn
binding which is updated when the bootstrap switch is toggled.With the these to points in mind, if you have an observable that is bound to changes to your toggle and you want to call some function when this toggle changes then you can register a your function as a callback to listen to the changes of the observable.
Hopefully, this snippet can explain this logic:
/**
* Knockout binding handler for bootstrapSwitch indicating the status
* of the switch (on/off): https://github.com/nostalgiaz/bootstrap-switch
*/
ko.bindingHandlers.bootstrapSwitchOn = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
$elem = $(element);
$(element).bootstrapSwitch();
$(element).bootstrapSwitch('setState', ko.utils.unwrapObservable(valueAccessor())); // Set intial state
$elem.on('switch-change', function(e, data) {
valueAccessor()(data.value);
}); // Update the model when changed.
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var vStatus = $(element).bootstrapSwitch('state');
var vmStatus = ko.utils.unwrapObservable(valueAccessor());
if (vStatus != vmStatus) {
$(element).bootstrapSwitch('setState', vmStatus);
}
}
};
// your viewmodel bound to the web page
var vm = function() {
this.log = ko.observableArray([]);
// ActiveFlag observable bound to switch, synced with state of switch
this.ActiveFlag = ko.observable(false);
// the function I want to call whenever the switch state changes
var doSomethingWhenSwitchStateChanges = function(value) {
this.log.push('the switch state changed to: ' + value);
}.bind(this);
// register callback
var subscription = this.ActiveFlag.subscribe(doSomethingWhenSwitchStateChanges);
}
ko.applyBindings(new vm());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/2.0.0/css/bootstrap-switch.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/2.0.0/js/bootstrap-switch.min.js"></script>
<div class="row">
<div class="col-md-6">
<div>
<input type="checkbox" data-bind="checked: ActiveFlag" />
</div>
<div>
<input type="checkbox" data-bind="bootstrapSwitchOn: ActiveFlag" />
</div>
</div>
<div class="col-md-6" data-bind="foreach: log">
<p data-bind="text: $data"><p>
</div>
</div>
Upvotes: 1