Calling an function from a dynamically added button - javascript

I want to call a function test(instance) which accept an argument as a test when I click a dynamically added button. However, it throws an error while doing it in the following way. What am I doing wrong here?
notificationList.forEach(function(hs) {
console.log(hs);
htmlStr = "<tr align='center'>";
htmlStr += "<td>" + hs.notification + "</td>";
htmlStr += "<td>" + hs.date + "</td>";
htmlStr += "<td>" + hs.instance + "</td>";
htmlStr += "<td > <input style='align-self: center' type='button' align='center' class='btn btn-primary' value='Info' onclick='test(hs)'> </input> </td>";
htmlStr += "</tr>";
index++;
$("#hs").append(htmlStr);
});
function test(instance){
console.log(instance);
}

You could bind an event just after appending the button
notificationList.forEach(function(hs) {
console.log(hs);
htmlStr = "<tr align='center'>";
htmlStr += "<td>" + hs.notification + "</td>";
htmlStr += "<td>" + hs.date + "</td>";
htmlStr += "<td>" + hs.instance + "</td>";
htmlStr += "<td>";
htmlStr += "<input style='align-self: center' type='button' align='center' class='dinamicButton btn btn-primary' value='Info' onclick='test(hs)'> </input> </td>";
htmlStr += "</tr>";
index++;
$("#hs").append(htmlStr);
$(".dinamicButton").on("click",test)
});
function test(instance){
console.log(instance);
}
I have added the "dinamicButton" class to your button to make this works.

You can use jquery on function. instead of adding onclick='test(hs)' you can add this in your javascript:
$('btn btn-primary').on('click', function() {
//your code
})
This will be triggered on future elements with the btn btn-primary class.

Try:
$("#hs").append(htmlStr).find('input').click(function() {
test(hs);
});

Your code has a few problems:
First, input is a self closing tag so:
<input ... onclick='test(hs)' />
instead of
<input ... onclick='test(hs)'> </input>
Also, in the context of your HTML, hs has no meaning... You may want to pass "hs" as a string, like so:
<input ... onclick='test("hs")' />
and then do whatever you want with that string...

You are not giving value inside quotes. Try to put value inside quotes and then try.
function addButton(){
var hs = "button Value";
var buttonText = "<button onclick='test(\"" + hs + "\");'>click here</button>"
$("#addHere").html(buttonText);
}
addButton();
function test(value){
console.log(value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addHere"></div>

You can try this
notificationList.forEach(function(hs) {
console.log(hs);
htmlStr = "<tr align='center'>";
htmlStr += "<td>" + hs.notification + "</td>";
htmlStr += "<td>" + hs.date + "</td>";
htmlStr += "<td>" + hs.instance + "</td>";
htmlStr += "<td > <input style='align-self: center' type='button' align='center' class='dinamicButton btn btn-primary' value='Info' onclick='test("hs")'> </input> </td>";
htmlStr += "</tr>";
index++;
$("#hs").append(htmlStr);
var button=document.getElementsByClassName[0];
button.addEventListener("click", test)
});
function test(instance){
console.log(instance);
}

Luigonsec solution is correcte exception for line
$(".dinamicButton").on("click",test)
You could add parameters like this :
$(".dinamicButton").on("click",function(){
test(hs);
});

Related

HTML- Header for Dynamic Table

This is my current table-
txt += "<table border='2'>";
for (x in myObj) {
txt += "<tr>"
txt += "<td>" + myObj[x].friend_id + "</td>";
txt += "<td>" + myObj[x].birth_date + "</td>";
txt += "<td>" + myObj[x].first_name + "</td>";
txt += "<td>" + myObj[x].last_name + "</td>";
txt += "<td>" + myObj[x].gender + "</td>";
txt += "<td>" + myObj[x].phone+ "</td>";
txt += "</tr>"
I'm populating it with JSON output, which works fine. However, I don't know how to add the header to the table. I tried adding the header out of the for loop, but it wouldn't align with the table in the loop. How do I connect both?
Current table- https://imgur.com/a/Fo7OdfX
txt += "<table border='2'>";
txt += "<tr>"
txt += "<th>Friend Id</th>";
txt += "<th>Birth Date</th>";
txt += "<th>First Name</th>";
txt += "<th>Last Name</th>";
txt += "<th>Gender</th>";
txt += "<th>Phone</th>";
txt += "</tr>"
for (x in myObj) {
txt += "<tr>"
txt += "<td>" + myObj[x].friend_id + "</td>";
txt += "<td>" + myObj[x].birth_date + "</td>";
txt += "<td>" + myObj[x].first_name + "</td>";
txt += "<td>" + myObj[x].last_name + "</td>";
txt += "<td>" + myObj[x].gender + "</td>";
txt += "<td>" + myObj[x].phone+ "</td>";
txt += "</tr>"
}

How to pass data into function, inside HTML tags?

I fixed the problem by calling a function, that graps the id of the table row it is placed in :)
I have this piece of code sorting some different stuff into a table, that works fine. The problem is to pass data into a function called inside HTML tags, like so:
See reference here
$.when(document, getTournamentsData()).done(function(){
var output = "";
$.each(tournamentsData, function(key, data){
output += "<tr class='data_row "+data.isOpen+"' id='"+data._id+"'>";
output += "<td>" + (key+1) + "</td>";
output += "<td><b>" + data.name + "</b></td>";
output += "<td>Start: " + data.begintime + "<br>Slut: " + data.endtime + "</td>";
output += "<td><input class='btn btn-primary' type='button' value='Se beskrivelse' onclick='showTourDescription(data.description)'/></td>";
output += "<td><input class='btn btn-primary' type='button' value='Se billede' onclick='showPic(data.image)'/></td>";
output += "<td>Max antal: "+ data.max_teams +"<br>Tilmeldte: "+ data.teams.length +"</td><br>";
output += "<td><input class='btn btn-primary' type='button' value='Se deltagere' onclick='showMembers(data.teams)'/></td>";
output += "<td>" + prizes(data.prices) + "</td>";
output += "</tr>";
});
output += "";
$('#data_insert').append(output);
});
All I do in the function is to console the data, and I get error "data is not defined"
This is the full script https://github.com/Jakobtottrup/OptekSemester2/blob/master/Web/public/js/tournaments_admin.js
// list tournaments
$.when(document, getTournamentsData()).done(function(){
var output = "";
$.each(tournamentsData, function(key, data){
output += "<tr class='data_row "+convertBoolean(data.isOpen)+"' id='"+data._id+"'>";
output += "<td>" + (key+1) + "</td>"; // index
output += "<td><b>" + data.name + "</b></td>"; // navn
output += "<td>Start: " + data.begintime + "<br>Slut: " + data.endtime + "</td>"; // start/slut
output += "<td><input class='btn btn-primary' type='button' value='Se beskrivelse' onclick='showTourDescription("+data.description+")'/></td>"; // beskrivelse TODO
output += "<td><input class='btn btn-primary' type='button' value='Se billede' onclick='showPic("+data.description+")'/></td>"; // billede
output += "<td>Max antal: "+ data.max_teams +"<br>Tilmeldte: "+ data.teams.length +"</td><br>"; // hold
output += "<td><input class='btn btn-primary' type='button' value='Se deltagere' onclick='showMembers("+data.teams"+)'/></td>"; // medlemmer
output += "<td>" + prizes(data.prices) + "</td>"; // præmier
output += "</tr>";
});
I've taken your code, and as you've done in the HTML strings themselves, concatenated in the event handlers too. Should be all you need to do.
UPDATE: Looks like you are passing data as string. See if that works
$.each(tournamentsData, function(data) {
onclick='showTourDescription(" + data.description + ")

Hide/Show for buttons in a table JavaScript

I have this function on my load event, I want the save button to be hidden and show up when I click edit button, currently only the button in the first row isn't visible as I put x[0].style.display=none. If I put this line code to x[1] and x[2] not only the button will not show but the whole line.
How can i fix it with only Javascript?
function insert(){
var tbl = document.getElementById('table');
var mybody = tbl.getElementsByTagName('tbody');
var mytable="";
for (i=0;i<=2;i++) {
mytable += "<tr>"
mytable += "<td> <span>" + students[i].userID + "</span></td>";
mytable += "<td> <span>" + students[i].firstName + "</span></td>";
mytable += "<td> <span>" + students[i].lastName + "</span></td>";
mytable += "<td> <span>" + students[i].dob + "</span></td>";
mytable += "<td> <span>" + students[i].gender + "</span></td>";
mytable += "<td> <span>" + students[i].status + "</span></td>";
mytable += "<td> <button class='del' onclick='deleteRow(this)'>Delete</button>";
mytable += "<button class='edit' onclick='editRow(this)'>Edit</button>";
mytable += "<button class='save' onclick='saveRow(this)'>Save</button>";
mytable += "<button class='cancel' onclick='cancel(this)'>Cancel</button></td>";
mytable += "</tr>";
mybody[0].innerHTML = mytable;
x = document.getElementsByClassName('save');
x[0].style.display='none';
}
}
Why did it not work?
You close the loop too late and thus your iteration gets messed up. So the first time it finds one, then two, then three.. Just add all the innerHTML with a single string after the loop.
Basic solution
To stay as close as possible to your original code (replace students. values back).
function insert(){
var tbl = document.getElementById('table');
var mybody = tbl.getElementsByTagName('tbody');
var mytable="";
for(i=0;i<=2;i++){
mytable += "<tr>"
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <span>" + i + "</span></td>";
mytable += "<td> <button class='del' onclick='deleteRow(this)'>Delete</button>";
mytable += "<button class='edit' onclick='editRow(this)'>Edit</button>";
mytable += "<button class='save' onclick='saveRow(this)'>Save</button>";
mytable += "<button class='cancel' onclick='cancel(this)'>Cancel</button></td>";
mytable += "</tr>";
} //We move the closure here.
//We assing the HTML
mybody[0].innerHTML = mytable;
//We get all buttons with the class save and hide them
x = document.querySelectorAll('button.save');
for(var i=0, j=x.length; i<j; i++) x[i].style.display = 'none';
}
Improvements
Use document.createElement() on document.createDocumentFragement() instead of innerHTML string adding method. Would also make it more easy to assign your later wanted event to show the save button again.
Edit: Thanks to Serlite to improve my english skills, always appreciated :)
Here's what you want I think ...
I've created a div and hid the button like this
x = document.getElementsByClassName("del");
x[0].style.display = 'none';
and created the div to post your html
document.getElementById('tbody').innerHTML = mytable;
Have a look at Fiddle <-- your script in action

javascript/jQuery passing arguments in a method

How can I pass argument in this code
$table += "<td>" + "<a href='#' onclick='myFunction(HERE_I_need_to_pass_an_argument);'>" + items[i].senderID +"</a>" +"------"+ items[i].startTime +"</td>";
function myFunction (myVariable) {
// my other logic goes here
}
can you help me writing an alert on that like this:
alertValue = 10;
$table += "<td>" + "<a href='#' onclick='alert(alertValue );'>" + items[i].senderID +"</a>" +"------"+ items[i].startTime +"</td>";
function myFunction (myVariable) {
// my other logic goes here
}
$table += "<td>" + "<a href='#' onclick='alert("+alertValue+");'>" + items[i].senderID +"</a>" +"------"+ items[i].startTime +"</td>";

Working with JSON input

I'm trying to get a JSON input with AJAX and load it in a select control.
but when I run it :\ It stuck on "Downloading the recipes....".
anyone see the problem maybe? (I tried couple of changes but nothing work so far)
1 more issue can anyone think on a shorter way to do the
ConvertToTable(targetNode)
cuse it's way to long and complex, I think :\
<script type="text/javascript">
function loadXMLDoc() {
var xmlhttp;
document.getElementById("span").style.visibility = "visible";
document.getElementById("span1").style.visibility = "hidden";
document.getElementById("button").style.visibility = "hidden";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
result = xmlhttp.responseText;
result = eval('(' + result + ')');
txt = "<select onchange='ShowRecipeDetails(this)'>";
for (i = 0; i < result.length; i++) {
txt = txt + "<option VALUE=" + result[i].recipe + ">" + result[i].recipe + "</option>";
}
txt = txt + "</select >";
document.getElementById("span").style.visibility = "hidden";
document.getElementById("span1").style.visibility = "visible";
document.getElementById("myDiv").innerHTML = txt;
}
}
xmlhttp.open("POST", "http://food.cs50.net/api/1.3/menus?meal=BREAKFAST&sdt=2011-03-21&output=json", true);
xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xmlhttp.send();
}
function ShowRecipeDetails(event) {
// get the index of the selected option
var idx = event.selectedIndex;
// get the value of the selected option
var field = event.options[idx].value;
$.ajax({
type: "GET",
url: "http://food.cs50.net/api/1.3/recipes?&output=json&id=" + field,
success: function (data) {
$("#TableDiv").html(ConvertToTable(data[0]));
}
});
}
function ConvertToTable(targetNode) {
var table = "<table border = 1 borderColor =green>";
table += "<tr>";
table += "<td>" + "ID" + "</td>";
table += "<td>" + targetNode.id + "</td>";
table += "</tr>";
table += "<td>" + "Ingredients:" + "</td>";
table += "<td>" + targetNode.ingredients + "</td>";
table += "</tr>";
table += "<td>" + "Name:" + "</td>";
table += "<td>" + targetNode.name + "</td>";
table += "</tr>";
table += "<td>" + "Size:" + "</td>";
table += "<td>" + targetNode.size + "</td>";
table += "</tr>";
table += "<td>" + "Unit" + "</td>";
table += "<td>" + targetNode.unit + "</td>";
table += "</tr>";
table += "<td>" + "VEGETARIAN:" + "</td>";
table += "<td>" + targetNode.VEGETARIAN + "</td>";
table += "</tr>";
table += "</tr>";
table += "</table>"
return table;
}
</script>
and the HTML:
<button id="button" type="button" onclick="loadXMLDoc()" >Get all recipes</button>
<br />
<span id="span" style="visibility:hidden">Downloading the recipes....</span>
<span id="span1" style="visibility:hidden">Please choose a recipe ID to view</span>
<div id="jsonDiv"></div>
<div id="myDiv"></div>
<div id="TableDiv"></div>
The HarvardFood API also supplies a JSONP version. So if you change your URL to this:
http://food.cs50.net/api/1.3/menus?meal=BREAKFAST&sdt=2011-03-21&output=jsonp&callback=parseResponse
you can create a parseResponse function to handle the data that comes back, and you can do the AJAX by inserting a script tag.
The problem is that you're running afoul the Same Origin Policy.
I see that you've updated the question to use jQuery AJAX. That offers a jsonp data type, which might be easier than adding a script tag.

Categories