knowledge
knowledge

Reputation: 1015

knockoutjs remove click binding

I use knockoutjs and have a button (id='enter') with a click binding:

<input id="enter" type="button" value="Enter" data-bind="click: function(data,event) { console.log('do something'); console.log('do something more');}"/>

If I click the button "do something" and "do something more" is logged on the console.

How can I update the click binding, e.g. set a now binding? So that the click of the button invokes another actions?

This doesnt work:

var enterButton = document.getElementById('enter');
var newClickBind = "click: function(data,event) { console.log('muh'); }";
enterButton.setAttribute('data-bind',newClickBind);

Thanks and regards

Upvotes: 1

Views: 1070

Answers (3)

Joel R Michaliszen
Joel R Michaliszen

Reputation: 4222

You can use a ko.computed that returns to the click bind the function that needs to be executed, see the example:

function AppViewModel() {
    
    this.choosenAction = ko.observable("1");
    var action1 = function(){
        console.log("Action 1 Done!!!")
    };
    
    var action2 = function(){
        console.log("Action 2 Done!!!")
    };
    
    this.onClickTest = ko.computed(function(){
        if(+this.choosenAction()===1)
            return action1;
        else
            return action2;
    },this);
    

}

// Activates knockout.js
ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<label for="act1"> Action 1 </label>
<input type="radio" id="act1" name="action" value="1" data-bind="checked: choosenAction"/>
<label for="act2"> Action 2 </label>
<input type="radio" id="act2" name="action" value="2" data-bind="checked: choosenAction"/>
</br>
</br>
<button data-bind="click: onClickTest()">Teste</button>

look that the function to be executed depends on the action choosed.

Upvotes: 0

Roy J
Roy J

Reputation: 43881

One thing you can do is make an observable that holds a function, which you can change based on the state of things in your form. The click would get bound to an invocation of that observable.

function thing1() {
  vm.output('thing 1');
}

function thing2() {
  vm.output('thing 2');
}

function thing3() {
  vm.output('thing 3');
}
var vm = {
  dynamicFunction: ko.observable(thing1),
  changeIt: function() {
    console.debug("Whatever");
    if (vm.dynamicFunction() == thing3) {
      vm.dynamicFunction(thing2);
    } else {
      vm.dynamicFunction(thing3);
    }
  },
  output: ko.observable('')
};

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="button" value="Run" data-bind="click: dynamicFunction()" />
<input type="button" value="Switch" data-bind="click: changeIt" />
<div data-bind="text:output"></div>

Upvotes: 1

indubitablee
indubitablee

Reputation: 8206

you should put all the logic of the click binding inside the viewModel. below is the VM function equivalent of your inline click binding

// Here's my data model
var ViewModel = function() {
    this.clickFunction = function(data, event) {
    	console.log('do something');
        console.log('do something else');
        console.log(data, event);
    };
};
 
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input id="enter" type="button" value="Enter" data-bind="click: function() { clickFunction($data, event); }"/>

EDIT: changing the click event based on other events

// Here's my data model
var ViewModel = function() {
    this.action = ko.observable('doNothing');
    
    this.setDoSomething = function() {
   		this.action('doSomething');
    };
    
    this.setDoSomethingElse = function() {
   		this.action('doSomethingElse');
    };
    
    this.clickFunction = function() {
    	if (this.action() == 'doSomething') {
        	doSomething();
        }
        else if (this.action() == 'doSomethingElse') {
        	doSomethingElse();
        }
        else {
        	this.action('doNothing');
        }
    };
    
    function doSomething() {
    	console.log('do something');
    }
    
    function doSomethingElse() {    	
        console.log('do something else');
    }
};
 
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<button data-bind="click: setDoSomething">Make it Do something</button><br/>
<button data-bind="click: setDoSomethingElse">Make it Do something else</button><br/>
<br/><br/>
<input id="enter" type="button" value="Enter" data-bind="click: clickFunction"/><br/>
clicking enter will <div data-bind="text: action"></div>

Upvotes: 0

Related Questions