Passing a parameter using onclick or binding clicks using KnockoutJS

I have this function:

function make(place) { place.innerHTML = "somthing" } 

I used this with regular JavaScript and html:

 <button onclick="make(this.parent)">click me</button> 

How to do this using idiomatic knockout.js?

+43
javascript html onclick
Apr 6 2018-12-12T00:
source share
5 answers

If you configured click binding in Knockout, the event is passed as the second parameter. You can use this event to get the element that the click occurred on and perform any action you want.

Here is a fiddle that demonstrates: http://jsfiddle.net/jearles/xSKyR/

Alternatively, you can create your own binding, which will receive the element to which it is bound as the first parameter. In init, you can attach your own click event handler to perform any action.

http://knockoutjs.com/documentation/custom-bindings.html

HTML

 <div> <button data-bind="click: clickMe">Click Me!</button> </div> 

Js

 var ViewModel = function() { var self = this; self.clickMe = function(data,event) { var target = event.target || event.srcElement; if (target.nodeType == 3) // defeat Safari bug target = target.parentNode; target.parentNode.innerHTML = "something"; } } ko.applyBindings(new ViewModel()); 
+26
Apr 6 2018-12-12T00:
source share

Use binding, as in this example:

 <a href="#new-search" data-bind="click:SearchManager.bind($data,'1')"> Search Manager </a> 
 var ViewModelStructure = function () { var self = this; this.SearchManager = function (search) { console.log(search); }; }(); 
+68
Feb 22 '13 at 14:31
source share

I know this is an old question, but here is my contribution. Instead of all these tricks, you can just simply wrap a function inside another function. Like I did here:

 <div data-bind="click: function(){ f('hello parameter'); }">Click me once</div> <div data-bind="click: function(){ f('no no parameter'); }">Click me twice</div> var VM = function(){ this.f = function(param){ console.log(param); } } ko.applyBindings(new VM()); 

And here is the fiddle

+22
Apr 22 '14 at 8:35
source share

General answer on how to handle click events with KnockoutJS ...

Not immediately the answer to the question as asked, but probably the answer to the question that most Googlers adventures are here: use the click binding from KnockoutJS instead of onclick . Like this:

 function Item(parent, txt) { var self = this; self.doStuff = function(data, event) { console.log(data, event); parent.log(parent.log() + "\n data = " + ko.toJSON(data)); }; self.doOtherStuff = function(customParam, data, event) { console.log(data, event); parent.log(parent.log() + "\n data = " + ko.toJSON(data) + ", customParam = " + customParam); }; self.txt = ko.observable(txt); } function RootVm(items) { var self = this; self.doParentStuff = function(data, event) { console.log(data, event); self.log(self.log() + "\n data = " + ko.toJSON(data)); }; self.items = ko.observableArray([ new Item(self, "John Doe"), new Item(self, "Marcus Aurelius") ]); self.log = ko.observable("Started logging..."); } ko.applyBindings(new RootVm()); 
 .parent { background: rgba(150, 150, 200, 0.5); padding: 2px; margin: 5px; } button { margin: 2px 0; font-family: consolas; font-size: 11px; } pre { background: #eee; border: 1px solid #ccc; padding: 5px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> <div data-bind="foreach: items"> <div class="parent"> <span data-bind="text: txt"></span><br> <button data-bind="click: doStuff">click: doStuff</button><br> <button data-bind="click: $parent.doParentStuff">click: $parent.doParentStuff</button><br> <button data-bind="click: $root.doParentStuff">click: $root.doParentStuff</button><br> <button data-bind="click: function(data, event) { $parent.log($parent.log() + '\n data = ' + ko.toJSON(data)); }">click: function(data, event) { $parent.log($parent.log() + '\n data = ' + ko.toJSON(data)); }</button><br> <button data-bind="click: doOtherStuff.bind($data, 'test 123')">click: doOtherStuff.bind($data, 'test 123')</button><br> <button data-bind="click: function(data, event) { doOtherStuff('test 123', $data, event); }">click: function(data, event) { doOtherStuff($data, 'test 123', event); }</button><br> </div> </div> Click log: <pre data-bind="text: log"></pre> 



** Note on the current issue ... *

There is one interesting bit in the actual question:

 // Uh oh! Modifying the DOM.... place.innerHTML = "somthing" 

Do not do this! Do not modify the DOM as with the MVVM framework such as KnockoutJS, especially not the DOM part that is your own parent. If you do this, the button will disappear (if you replace the innerHTML parent, you yourself will leave forever!).

Instead, change the View Model in your handler and respond with View. For example:

 function RootVm() { var self = this; self.buttonWasClickedOnce = ko.observable(false); self.toggle = function(data, event) { self.buttonWasClickedOnce(!self.buttonWasClickedOnce()); }; } ko.applyBindings(new RootVm()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> <div> <div data-bind="visible: !buttonWasClickedOnce()"> <button data-bind="click: toggle">Toggle!</button> </div> <div data-bind="visible: buttonWasClickedOnce"> Can be made visible with toggle... <button data-bind="click: toggle">Untoggle!</button> </div> </div> 
+7
Mar 14 '16 at 19:35
source share

The knockout documentation also mentions a much simpler way of passing additional parameters to functions related to using on-click bindings using the .bind function as follows:

 <button data-bind="click: myFunction.bind($data, 'param1', 'param2')"> Click me </button> 
+3
May 16 '16 at 6:49
source share



All Articles