Keiran Lovett
Keiran Lovett

Reputation: 604

Toggle with two functions

I'm trying to set up a checkbox, that when given a true value will load information, and when false unload that information. Currently I have two buttons with these functions, but wish to have a quick access toggle. I can't seem to figure out how to have if true/false for a toggle function however.

HTML - hardcoded button for loading.

<span class="label" data-bind="css: {click: function () {$root.loadLayerSource(Source, ReadableName, Type, URL, Description)}">Load</span>

JS:

//Disable layers if checkbox is false
this.disableLayer = function (layerId, type) {
   //            
}

// .....

//Enable layers if checkbox is true
this.loadLayerSource = function (source, name, type, url, description){
  //...
}

Upvotes: 0

Views: 87

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074295

In a comment you've said:

I don't want to show or hide HTML elements, rather I need to execute two different functions loadLayerSource or disableLayer

If there's no showing/hiding and it's purely a matter of calling functions, then bind the checkbox to a boolean observable via the checked binding and subscribe to it:

var vm = {
  showing: ko.observable(false),
  output: ko.observableArray()
};
vm.showing.subscribe(function(newValue) {
  if (newValue) {
    doThis();
  } else {
    doThat();
  }
});
ko.applyBindings(vm, document.body);

function doThis() {
  vm.output.push("Doing 'this' because value was true");
}

function doThat() {
  vm.output.push("Doing 'that' because value was false");
}
<label>
  <input type="checkbox" data-bind="checked: showing">
  Show
</label>
<div data-bind="foreach: output">
  <div data-bind="text: $data"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>


Original answer when I thought you were mostly showing/hiding stuff, with optional subscription as well:

Bind the checkbox to a boolean observable via the checked binding, then show/hide the other information based on the value of that observable.

var vm = {
  showing: ko.observable(false)
};
ko.applyBindings(vm, document.body);
<label>
  <input type="checkbox" data-bind="checked: showing">
  Show
</label>
<div data-bind="visible: showing">This is visible when showing</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

If you need to kick off some further process when the observable changes, you can do that by subscribing to it.

var vm = {
  showing: ko.observable(false),
  loading: ko.observable(false),
  data: ko.observable(null),
  loadData: function() {
    this.loading(true);
    setTimeout(function() {
      vm.loading(false);
      vm.data("The data is ready now");
    }, 500);
  }
};
vm.showing.subscribe(function(newValue) {
  if (newValue && !vm.data()) {
    vm.loadData();
  }
});
ko.applyBindings(vm, document.body);
<label>
  <input type="checkbox" data-bind="checked: showing">
  Show
</label>
<div data-bind="visible: showing">
  <div data-bind="visible: loading">Loading...</div>
  <div data-bind="visible: data, text: data"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Upvotes: 3

Related Questions