Knockout VIewModel triggers function inside foreach - javascript

I am fighting with strange issue and i am running out of ideas.
The problem is that my view model is triggering function inside foreach on click. So in this case if i click on div menuConnections testcall function is being triggered. Even if i send other value to testcall (such as div id) same value is being sent when I click on menuConnections.
How to stop this and force testcall to be executed only when i click on TheDivWhoCalls?
function ProfileViewModel(userId) {
var self = this;
self.connectionRequests = ko.observableArray();
self.getConnections = function () {
$("#menuConnections").css({ "display": "block" });
//other code which returns data
};
self.testcall = function(data) {
alert(target);
};;
}
<div id="menuConnections" data-bind='click: getConnections'>Connections</div>
<div id="connections" style="display: none">
<div data-bind="foreach: connectionRequests">
<div id="TheDivWhoCalls" data-bind='click: $root.testcall("asd")'><img src="~/Resources/Images/yesIcon.png" /></div>
</div>
</div>

I can't tell for sure without seeing an actual running example with ko.applyBindings but try changing
data-bind='click: $root.testcall("asd")
to
data-bind='click: $parent.testcall.bind($parent, "asd")
Explanation:
First I changed $root to $parent. I don't know what your $root is, but its safe to assume that your $parent is the VM with the testcall method.
More importantly, is that click: expects a function, but $root.testcall("asd") invokes the function returning undefined. Instead we use Function.prototype.bind to create a new function from testcall with the parameter set to "asd"and this set to $parent

You might need the bind syntax instead. Try data-bind="$root.testcall.bind($data, 'asd')"

Related

Jquery click event not returning anything

My jquery is not alerting anything when I click the button with the id decrease. This is my code. I am using external js file.
$(document).ready(
$('#decrease').click(function() {
var beforeIncrement = $('#amt').val();
alert(beforeIncrement);
}))
I tried doing this and it is working fine.
$(document).ready(function(){
alert("Ready");
})
This is the html code:
<div class="row justify-content-center d-flex">
<button id="decrease" class="btn btn-warning">-</button>
<input type="number" id="amt" value="1"/>
<button id="increase" class="btn btn-warning">+</button>
</div>
what's wrong with my first code snippet?
The value you pass to ready() needs to be a function.
In your first example, you are passing the return value of $('#decrease').click(...).
This means that $('#decrease').click(...) has to be evaluated immediately, so it is looking for #decrease before the DOM is ready and the element doesn't exist yet.
ready() then ignores the value you pass to it because it isn't a function.
Wrap the call to $('#decrease').click(...) in a function, just as you did for alert(...) in the second example.
You also have a missing ); at the end but I'm guessing that just got cut off when you transcribed your code to the question.
Try using this:
$('#decrease').on('click', function(){
var beforeIncrement = $('#amt').val();
alert(beforeIncrement);
})
if you have the right html syntax, the right syntax for your js script is:
(you have to use a function for document.ready):
$( document ).ready(function() {
$('#decrease').click(function() {
var beforeIncrement = $('#amt').val();
alert(beforeIncrement);
});
});
you could use the shorthand syntax:
$(function() {
$('#decrease').click(function() {
var beforeIncrement = $('#amt').val();
alert(beforeIncrement);
});
});

How to get element from DOM and set onclick event?

I have this html element:
<table id="miniToolbar">
<tbody>
<tr><td>
<button id="btnStrView" type="button" onclick='parent.ExecuteCommand()' class="button_air-medium">
<img id="streetView" class="miniToolbarContant" src="../stdicons/streetview-icon.png"></button>
</td></tr>
<tbody>
</table>
as you can see inside button I have on click event:
onclick='parent.ExecuteCommand()'
And I have this JS function:
function isMenuItemMasked(item)
{
var funcId = '75';
var elem = document.getElementById('btnStrView');
return false;
}
as you can see inside function I have variable called funcId.
I need to put this funcId to the on click event:
onclick='parent.ExecuteCommand('75')'
After I fetch element and put it inside elem variable how do I put funcId as parameter to parent.ExecuteCommand()?
I think you want to set the function argument dynamically. Without using external libraries I would do as follows:
function runSubmit() {
var value = document.getElementById("text").value;
document.getElementById("run").addEventListener('click', function() {
func(value);
});
}
function func(value) {
console.log(value);
}
<input id="text" type="text">
<input type="submit" value="Setup Param" onclick="runSubmit()">
<input id="run" type="submit" value="Run with param">
How to use this: When you run the snippet, you will see a text input, a Setup Param button and a Run with param button. Insert something in the text input and click Setup Param. After, click on Run with param to see the effect
The input text contains the string that will be used as parameter for func(value). The update of #run button callback is triggered by the "Setup param", through the runSubmit() callback. This callback adds to the #run element a listener for the 'click' event, that runs a function with the parameter fixed when event occurs.
This is only a MCVE, you should adapt it to your case scenario.
Mh... Actually #jacob-goh gave you this exact solution in a comment while I wrote this...
you can use jquery to call you function from inside the function and pass your variable to that function.
function isMenuItemMasked(item)
{
var funcId = "75";
$(document).ready(function(){
$("#btnStrView").click(function(){
parent.ExecuteCommand(funcId);
});
});
}
function ExecuteCommand(your_var){
alert(your_var);
//your code
}

How to call a function when a visibility binding is true?

for an example how to execute a javascript function when the binding is visible:true meaning BooleanIndicator() have returned true, assuming that the function called has e as a parameter, whereby e is an event.
<div data-bind="visible: shouldShowMessage">
You will see this message only when "shouldShowMessage" holds a true value.
</div>
<div >
Also show this div when the above div is visble
<div>
Binding is dependent on the data in your view model. If BooleanIndicator() is an observable property of your viewmodel you can create a computed function that should get called whenever the BooleanIndicator() changes
self.ComputedFunction = ko.computed(function() {
if (self.BooleanIndicator()){
//Do something - I'm visible
} else {
// Do something else
}
});

Javascript functions still remain after loading another partial

let's suppose the browser rendered following page
<html>
...
<body>
<div id="partialContainer">
<script>
function saveItems(){
/* do somthing*/
}
</script>
<input type="button" id="btnTest" name="btnTest" value="Test" onclick="saveItems()"/>
</div>
</body>
</html>
after an AJAX call and change the "partialContainer" content using
$("#partialContainer").html(returnedMarkup)
saveItems function still remains in page and can get executed
how can remove this function when markup get replaced to avoid name colissioning
var saveItems = function () {}
After your Ajax, assign some other value to it, preferably the one above.
Try setting saveItems to undefined
$("#partialContainer").html(returnedMarkup);
if (!!saveItems && $.isFunction(saveItems)) saveItems = void 0;
You could put your function in an object literal:
var obj = { saveItems: function() { } }
and delete it after the ajax
delete obj.saveItems
On your ajax success callback function, just do:
$("#btnTest").prop( "onclick", null );
Be aware that $.removeAttr('onclick') will fail in ie 6-8, so .prop() is better.

KnockoutJS click binding never called

function UserModel() {
self.forgeTransactions = function() {
console.log("forgeTransaction()");
}
self.navigateToNew() = function {
console.log("navigateToNew()");
}
}
ko.applyBindings(new UserModel());
<button class="btn" style="float: right" data-bind:"click: forgeTransactions">Add fake transaction</button>
The problem with this code is that forgeTransaction is never called whilst if i change the click binding to navigateToNew i can clearly see "navigateTwo" on the console.
Why is this happening?
Note: I can attach the entire source if needed.
You should write data-bind= not data-bind:
Your function is called forgeTransactions but you are attempting to call forgeTransaction in the button data-bind.

Categories