Add onclick event for tr element dynamically from JavaScript - javascript

I am creating a table dynamically, I need to add an onclick event for each element as it is added, but this needs a dynamic parameter add, I have tried the following
trElements[i + 1].onclick = function () {
navigateToController('/Home/Client', "'" + machine.DeviceID + "'");
};
but this shows the onclick event as navigateToController('/Home/Client', "'" + machine.DeviceID + "'")
and not navigateToController('/Home/Client', 'DeviceName'); as I thought it would, I have also tried to have the onclick event in the html, and replace the DEVICEID with the actual deviceid.
var element = trElements[i + 1].outerHTML.replace('DEVICEID', machine.DeviceID);
trElements[i + 1].outerHTML = element;
this shows up as been correct, but when the page is loaded, it still has deviceid in there ?
I am sure it is something really simple... but any pointers would be appreciated.

I'm not entirely sure I understand the question, but it might be a scope issue. You might need to use bind to create the handler with the current value of DeviceID:
var machineId = 0;
function navigateToController(machineId) {
alert(machineId);
}
function addRow() {
var t = document.getElementById('thetable');
var tr = t.insertRow();
var td = tr.insertCell();
td.appendChild(document.createTextNode("machine " + machineId));
tr.addEventListener('click', navigateToController.bind(null, machineId));
machineId++;
}
<button onclick="addRow()">Add Row</button>
<table id="thetable"></table>
but this shows the onclick event as navigateToController('/Home/Client', "'" + machine.DeviceID + "'")
You're not going to see the value of the variable in the markup, if that's what you mean.
Why not just navigateToController('/Home/Client', machine.DeviceID )? It's already a string. No need to try to add quotes around it. You'd end up with a parameter that includes the quotes.
var deviceId = 'theDeviceId';
// This is not what you want. Notice this alert includes the single quotes as part of the string: "'theDeviceId'"
alert( "'" + deviceId + "'");
// This is what you want. This alert has just the (unquoted) value.
alert( deviceId );

The better way to do this is not to do it at all.
Better attach the event handler to existing container (the table in this case seems good) and check for bubbling events.
With jQuery is quite simple:
var myTable = $("table#theTable");
myTable.on("click", "tr", function(){ // Click event handler.
var clickedRow = $(this);
...
});
If you need some data related to each row, simply attach to it in "data-" attributes (i.e. «data-myId="someId"») of the tag. Then you could read them simply by clickedRow.data("myId") from event handler function.
This way you have single function to handle all events for all rows. Simpler and wasting too less mamory.

trElements[i + 1].onclick = (function () {
var deviceId = machine.DeviceID;
return function(){
navigateToController('/Home/Client', "'" + deviceId + "'");
}
})();

ok, so I couldn't get to the bottom of adding an onClick function dynamically, so, I changed my code around, and pass a viewModel array containing all the data I needed to create the table, so when I open the clients view, I send a list of all the relevant clients, and when I select the row I need, I just pass a single viewmodel of the client, I then update the html with the c# code #model.variable. I can easily update these from my signalr code once its created.
thanks for everyones input.
Just to update, I have found a solution I think, I could create the element, add the data to the innerHtml, and use:
setAttribute("onclick", "navigateToController('/Home/Client', '" + deviceId + "')");
I have used this in another part of my solution, and it works...

Related

Binding to lines in flowchart.js

I'm using flowchart.js to create diagrams. I want to be able to bind a click event to each arrow on the diagram to perform some action to that unique path.
As far as I can see in the inspector, these lines don't have IDs... Is there a way to get around this?
I verified what you wrote and you're correct, the lines (svg paths) don't have IDs. Also, it looks like they don't have much of a programming API. So I came up with a hacky way of assigning IDs for each path.
After you make your call to diagram.drawSVG(...); add the following code create unique IDs for each path.
var i = 0;
$("path").each(function() {
$(this).attr("id", "path" + i.toString());
i++;
});
I then added a click handler to the path elements to verify the IDs were properly assigned.
$(document).on("click", "path", function () {
//Display to the console
var clickedPath = $(this)[0];
console.log(clickedPath);
// Build a string of attributes by looping them
var alertString="";
for (i=0; i < clickedPath.attributes.length; i++) {
alertString += clickedPath.attributes[i].name + "=" + clickedPath.attributes[i].value + "\n";
}
//Alert the attributes
alert(alertString);
});
You can view the results at https://codepen.io/anon/pen/EoqPQG?editors=0010

Appending option tags to select tag from array using JQuery

I am trying to create an options drop down list in html using JQuery to append from an Array.
Everything appears to be working correctly apart from the text between the opening & closing tags is not appearing. Am I so tired i'm missing a simple typo or doing something wrong?!?
The JS and JQuery code is:
var displayMenuSelections = function(){
var menuSelection = menu[0].prices[0];
var menuItems = Object.keys(menuSelection);
menuItems.forEach(menuFunction);
}
function menuFunction(item){
$('#menu').append($('<option value="' + item + '">' + item + '</option'));
}
The result of a typical option tag looks like this (with the 'item' missing between the opening and closing tags):
<option value="Cafe Latte"></option>
You forgot the > for the closing option tag. JQuery tries to close it for you, and in the process the inner item text doesn't get set.
Jquery takes a philosophy where it sort of tries to work with whatever you give it - this can be both good and bad, but in this case it makes it harder to debug since there's no error/exception that is raised.
var displayMenuSelections = function(){
var menuSelection = menu[0].prices[0];
var menuItems = Object.keys(menuSelection);
menuItems.forEach(menuFunction);
}
function menuFunction(item){
$('#menu').append($('<option value="' + item + '">' + item + '</option>'));
}
It looks to me like you are not passing your parameter
item
to your function
menuFunction(item)
I'm just assuming you are trying to send
var menuSelection
so you can try changing your function call to
menuItems.forEach(menuFunction(menuSelection));
I have not tested this however!

To call Javascript Function from dynmaically created Textbox

In the below code i have a dynamically created textbox and on onfocus event i am calling a javascript function .And i am assign onfocus event values on page load .And it is not working after creating onfocus event.Pls help me to solve the issue.
Test1,Test2 values are assigned on pageload
function createFields(Test1,Test2) {
var newdiv = document.createElement('div');
if (type == "TextBox") {
newdiv.innerHTML +=
"<input class=\"form-control\" data-error=\"Please Provide "
+ DisplayName
+ "\" name=\""
+ Name
+ "\" value=\""
+ FieldValue
+ "\" onFocus=\""
+ HighlightField(Test1,Test2)
+ "\" id=\""
+ Name + "\"/>";
$('#divComplete').append(newdiv);
}
}
function HighlightField(Test1,Test2) {
}
on onfocus event i am calling a javascript function
No you're not. Look closely at what's happening here:
"onFocus=\"" + HighlightField(Test1,Test2) + "\"
You're calling HighlightField() immediately and setting its result to the onFocus handler.
Unless that function actually returns a string of valid JavaScript code, it's likely that your resulting HTML looks like this:
onFocus=""
If you want to call the function in the onFocus event, don't invoke it. Instead, just specify the function call in the string you're creating:
"onFocus=\"HighlightField(Test1,Test2)\""
Edit: Given the clarification on your question, it sounds like you want those variables to be interpreted right away. But not the function call itself. That would be done the same way it's done anywhere else in that string. Something like this:
"onFocus=\"HighlightField(" + Test1 + "," + Test2 + ")\""
Note that if those variables are expected to contain string data then you'd also need to add quotes (since strings need to be quoted):
"onFocus=\"HighlightField('" + Test1 + "','" + Test2 + "')\""
As you're probably starting to notice, dynamically building code like this is a bit unwieldy. Since you're using jQuery anyway, at the very least you should remove the in-line event handler and create a separate event handler elsewhere in the code. Something like:
$(document).on('focus', 'input.form-control', function () {
// handle your focus event here
});
Then you wouldn't need to build this complex string.

How does JQuery empty() method work?

I know that the empty method removes all children in the DOM element.
In this example however, why does removing the empty method result in duplicate entries:
and putting it in results in a normal page:
var renderNotesList = function()
{
var dummyNotesCount = 10, note, i;
var view = $(notesListSelector);
view.empty();
var ul = $("<ul id =\"notes-list\" data-role=\"listview\"></ul>").appendTo(view);
for (i=0; i<dummyNotesCount; i++)
{
$("<li>"+ "" + "<div>Note title " + i + "</div>" + "<div class=\"list-item-narrative\">Note Narrative " + i + "</div>" + "" + "</li>").appendTo(ul);
}
ul.listview();
};
I don't know why empty() doesn't work but I found this
... so until this is sorted everyone should just use:
el.children().remove(); instead of el.empty();
( jQuery.empty() does not destroy UI widgets, whereas jQuery.remove() does (using UI 1.8.4) )
Without seeing how your JavaScript is being used in your page, I suspect that you must be calling the renderNotesList() function twice and thus generating to unordered lists.
When you use the .empty() method, you are removing the first ul list, so you only see one instance. Without the call to .empty(), you retain both.
However, I can't say where or how this is happening in you web page without seeing more, but at least you now have some idea of what to look for.
Demo Fiddle
I built a demo using your JavaScript, but I was sort of guessing as to how you are using it.
Fiddle: http://jsfiddle.net/audetwebdesign/UVymE/
Footnote
It occurred to me that the function ul.listview() may actually be appending a second copy of the ul to the DOM. You need to check the code or post it for further review.

Why functionToCallOnOk I pass to my function does not get called when I attach it to callback via jQuery?

So I try such code:
function showAlertWithCallback(w, h, name, body_text, functionToCallOnOk) {
prepareWindow();
var ran_alert_number=Math.random()*50000;
$("#alert_content").html(body_text + '<br/>' + '<input type=\"button\" class=\"eButton\" value=\"Cancel\" onClick=$(\".alert\").hide() />' + '<input id=\"general-alert-'+ ran_alert_number +'\" type=\"button\" class=\"eButton\" value=\"OK\" onClick=\"$(\'.alert\').hide();\"/>');
$('#general-alert-' + ran_alert_number).click(functionToCallOnOk);
// also tried $('#general-alert-' + ran_alert_number).click(function(){functionToCallOnOk();});
showAlertBase(w, h, name);
}
called via something like:
showAlertWithCallback(
600,
100 ,
('New name for to ' + file_title + ' file.'),
'<input type="text" style="width:590px" class="text" value=\"' + file_title + '\">',
function(){
alert("hi!");
}
);
runs with no errors (chrome debugger) but function does not get called on OK click. Why and how to fix such thing?
Math.random()*50000 will produce a number like 38518.060150090605, which when you concatenate with '#general-alert-' in the jQuery call will produce a selector like this:
#general-alert-38518.060150090605
That will be treated as a selector which finds an element with id general-alert-38518 and class 060150090605, since the class name comes after the dot.
To make the random number, use, say, Math.floor(Math.random()*5000) instead.
A better option would be to use an incrementing global variable (eg, _global_counter++ each time you use it), then you would not have a chance of getting two elements with the same id.
An even better solution would be to create actual DOM elements in JavaScript, attach events to those elements, then insert those elements into the correct place in the document. That way they won't need to have ids at all.
Try removing the onClick attribute of the OK button.

Categories