Reputation: 1015
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
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
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
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