Javascript - onchange event handler function argument not working properly - javascript

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>TEST</title>
<link rel="stylesheet" type="text/css" href="/js/jquery-ui-1.8.24.custom.css" media="screen, projection">
<script type="text/javascript" src="/js/jquery-1.8.2.js"></script>
<script type="text/javascript" src="/js/jquery-ui-1.8.24.custom.min.js"></script>
<script type="text/javascript">
<!--
function loadOperators(rowID)
{
alert("ROW: " + rowID);
}
var lastRowID = 1;
// Add new row
$('input#addrow').live('click', function(){
lastRowID += 1;
var $clonedRow = $('tr#row_1').clone();
// manipulating new ids for the elements in the newly created row
$clonedRow.find('*').andSelf().filter('[id]').each(function() {
var string = this.id;
pos = string.lastIndexOf('_');
var tempStr = string.substr(0, pos);
this.id = tempStr + "_" + lastRowID;
});
$clonedRow.insertBefore("#clone_table tr#spacer_row");
$("#field_id_" + lastRowID).on('change', function(){
loadOperators(lastRowID);
});
});
// Delete a row
$('input#delrow').live('click', function(){
if(lastRowID == 1)
{
return;
}
$('tr#row_' + lastRowID).remove();
lastRowID -= 1;
});
$(document).ready(function() {
loadOperators(lastRowID);
$("#field_id_1").on('change', function(){
loadOperators(lastRowID);
});
});
//-->
</script>
</head>
<body>
<table id="clone_table" width="700" cellpadding="0" border="0">
<colgroup>
<col width="200">
<col width="200">
<col width="200">
</colgroup>
<tr id="row_1">
<td>
<select name="field_id_1" id="field_id_1">
<option value="1">Item One</option>
<option value="2">Item Two</option>
<option value="3">Item Three</option>
</select>
</td>
<td id="operator_strip_1"></td>
<td id=""> </td>
</tr>
<tr id="spacer_row"><td colspan="3"> </td></tr>
<tr><td colspan="3"> </td></tr>
<tr><td colspan="3"><input type="button" id="addrow" value="More" /> <input type="button" id="delrow" value="Less" /></td></tr>
</table>
</body>
</html>
I am trying to add and delete rows to a HTML table dynamically.
But the generated row contains one combo box with a onchange event handler function.
I need to pass the row ID to that function. When I assign the new ID to the latest combo box's onchange event handler, it is changing the value assigned to the already generated combo boxes also. Can anyone look this code and tell me what is causing the issue here?

When you reference lastRowID in the call to loadOperators, you're getting the current value, because the variable is not local to the click handler function. You don't need the variable, you can just use this.id.
$('input#addrow').live('click', function(){
lastRowID += 1;
var $clonedRow = $('tr#row_1').clone();
// manipulating new ids for the elements in the newly created row
$clonedRow.find('*').andSelf().filter('[id]').each(function() {
var string = this.id;
pos = string.lastIndexOf('_');
var tempStr = string.substr(0, pos);
this.id = tempStr + "_" + lastRowID;
});
$clonedRow.insertBefore("#clone_table tr#spacer_row");
$("#field_id_" + lastRowID).on('change', function(){
loadOperators(this.id);
});
});
Instead of binding a handler every time you add a row, you could use delegation. Give all the field_id_N elements a class (field_class in the example below), and do this just once in the document.ready function:
$("#clone_table").on('change', '.field_class', function() {
loadOperators(this.id);
});
I'm not sure what the real loadOperators() function does (the one in your question is obviously just a stub), but I suspect you could just pass this to it instead of the ID, and you could probably get rid of all IDs in the elements that get cloned.
If you really need the lastRowID value, you can copy it into a local variable, which will be captured in the closure.
$('input#addrow').live('click', function(){
lastRowID += 1;
var thisRowID = lastRowID;
var $clonedRow = $('tr#row_1').clone();
// manipulating new ids for the elements in the newly created row
$clonedRow.find('*').andSelf().filter('[id]').each(function() {
var string = this.id;
pos = string.lastIndexOf('_');
var tempStr = string.substr(0, pos);
this.id = tempStr + "_" + lastRowID;
});
$clonedRow.insertBefore("#clone_table tr#spacer_row");
$("#field_id_" + lastRowID).on('change', function(){
loadOperators(thisRowID);
});
});

Related

I want to create a loop that will create a table out of user input data from a prompt

I want the user to input both 'part ID' and 'quantity' through prompt and have those values added to a table; which I've managed so far. After that, I want to add another row below the first one using the same method resulting in 2 rows with different values etc.
<html>
<head>
</head>
<!--CREATE AND POPULATE TABLE -->
<body onload="partID(); qty()">
<table id="resultsTable" border=".5px" class="results">
<tr><th>Part ID</th><th>Quantity</th>
<tr>
<td id="partID">Part ID</td>
<td id="qty">Quantity</td>
</tr>
</table>
<br>
<!-- I want this f('createTable') to bring the prompt back and append to existing table onclick, if that makes sense -->
<button onclick="createTable()">Add Another Part</button>
</body>
<!-- LOCAL SCRIPTS -->
<script>
function partID(){
var partID = prompt("Enter part ID:");
var x = document.getElementById('partID');
x.innerHTML = partID;
}
function qty(){
var qty = prompt("Enter Quantity:");
var y = document.getElementById('qty');
y.innerHTML = qty;
}
</script>
</html>
I can get it to work once around but I'm not sure how to repeat it for a new row and without losing previous data.
What you want to do is append data to the table, right now you are setting the values of individual cells instead of just appending them to the already existing ones.
JavaScript has a neat little shortcut for appending (just like many other languages) which is +=, basically var myVar = 'Foo'; myVar += 'Bar'; is equal to var myVar = 'Foo'; myVar = myVar + 'Bar';
function add() {
//prompt the user with boxes for the ID and quantity
var partID = prompt("Enter part ID:");
var qty = prompt("Enter Quantity:");
//generate the HTML for a new table row and insert the given values
var table_html = "<tr><td>" + partID + "</td><td>" + qty + "</td></tr>";
//append the HTML to the already existing HTML in the table
document.getElementById('resultsTable').innerHTML += table_html;
}
/*I dont like default buttons*/
button {
background-color: lightgrey;
color: black;
padding: 8px;
border: 0px;
}
button:hover {
background-color: grey;
}
<html>
<head>
</head>
<body onload="add();">
<!-- instead of onload use a button so the user can repeat the action multiple times -->
<button onclick="add();">Add part</button>
<hr>
<table id="resultsTable" border=".5px" class="results">
<tr>
<th>Part ID</th>
<th>Quantity</th>
</tr>
</table>
<br>
</body>
</html>
I hope this helps, if you need further explanation about the code just leave a comment.
Good luck.
From what I understand, you want to be able to add a new row to the <table>. For this, you probably want to use a button.
<button onclick="addRow()">Add row</button>
Then you can add a row using insertAdjacentHTML :
function addRow() {
var table = document.getElementById('resultsTable');
var partID = prompt("Enter part ID:");
var qty = prompt("Enter Quantity:");
table.insertAdjacentHTML('beforeend', "<tr><td>" + partID + "</td><td>" + qty + "</td></tr>")
}
Using insertAdjacentHTML is safer and more efficient than replacing the whole table innerHTML.

jquery- On onchange event tab content is not getting displayed properly

Below is my HTML code:
<select id="sourceNameDropdownId" label="condition " style="width:300px;">
</select>
<div id="tabs" class="selector">
</div>
Here, is my javascript code:
$("#DropdownId").change(function () {
var sid= $("#DropdownId option:selected").text();
afterclick(sid);
});
I am calling an onchange event on dropdown list, and the selected value i am passing to function afterclick
function afterclick(sid){
var tabsContainer = document.getElementById("tabs");
var crawlTab=document.createElement("ul");
//here in my actual code i am making a ajax call to fetch values for crawlList, providing static values here
var crawlList=["name1","name2","name3","name4"];
$.each(crawlList, function( index, crawlType ) {
var crawlTabElement=document.createElement("li");
crawlTabElement.innerHTML= '' +crawlType+'';
crawlTab.appendChild(crawlTabElement);
});
tabsContainer.appendChild(crawlTab);
var count=1;var tabCount=1;
$.each(crawlList, function( index, crawlType ) {
var contentCrawlTab=document.createElement("div");
contentCrawlTab.setAttribute("id",crawlType);
var p='<p>'+crawlType+'</p>';
contentCrawlTab.innerHTML=p;
tabsContainer.appendChild(contentCrawlTab);
});
$( ".selector" ).tabs();
}
This code is working fine when for the first time page gets loaded and a value is selected from the dropdown, but when i re-select value from the dropdown tabs are not getting displayed properly.
This is when i select value for the first time after page is loaded.
And when i reselect the value from dropdown its showing like this-
Is there something like reload to reload the tabs div entirely, as it seems that its appending the previous values and next time when afterclick function is called tab elements are not getting displayed properly.
I tried clearing the "tabs" div too, using **$( "#tabs " ).empty()**But it didn't worked for me.
Please help me out.
Check this working code.
$().ready(function () {
$(".selector").tabs();
$("#DropdownId").change(function () {
var sid = $("#DropdownId option:selected").text();
afterclick(sid);
});
});
function afterclick(sid) {
var tabsContainer = document.getElementById("tabs");
tabsContainer.innerHTML = '';
var crawlTab = document.createElement("ul");
//here in my actual code i am making a ajax call to fetch values for crawlList, providing static values here
var crawlList = [sid + "1", sid + "2", sid + "3", sid + "4"];
$.each(crawlList, function (index, crawlType) {
if (crawlType != null) {
var crawlTabElement = document.createElement("li");
crawlTabElement.innerHTML = '' + crawlType + '';
crawlTab.appendChild(crawlTabElement);
}
});
tabsContainer.appendChild(crawlTab);
var count = 1; var tabCount = 1;
$.each(crawlList, function (index, crawlType) {
if (crawlType != null) {
var contentCrawlTab = document.createElement("div");
contentCrawlTab.setAttribute("id", crawlType);
var p = '<p>' + crawlType + '</p>';
contentCrawlTab.innerHTML = p;
tabsContainer.appendChild(contentCrawlTab);
}
});
$(".selector").tabs('destroy');
$(".selector").tabs();
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<select id="DropdownId" label="condition " style="width:300px;">
<option selected="selected" disabled="disabled">--Select--</option>
<option>Bilna-ID</option>
<option>IndiatimesShopping</option>
</select>
<div id="tabs" class="selector">
</div>

How to make <td> clickable

I have created a table to display my SPARQL query result in the <td>, the result does display however I want it that when the<td> (result) is clicked on it displays a message box. Right now an extra <td> is displayed at the top and it only works for that particular one. Nothing seems to happen when clicking on the actual result <td>:
My code:
<table id="results">
<td class="td" onclick="myFunction()"></td>
</table>
<body>
<script type="text/javascript">
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX type: <http://dbpedia.org/class/yago/>
PREFIX prop: <http://dbpedia.org/property/>
SELECT ?country_name
WHERE {
?country rdf:type type:Country108544813.
?country rdfs:label ?country_name.
}
"Limit 1"
].join(" ");
alert("this query: [" + query + "]");
var queryUrl = url + "?query=" + encodeURIComponent(query) + "&format=json";
</body>
The JavaScript code I got it from an online material so still getting my head around it , the main use of it is to display the query result. So yeah answers are really appreciated and thanks for reading:)
So first off, your html is a little off... Your table is outside the tag, when it should be inside it: (note a td usually would be in a too)
<body>
<table id="results">
<tr><td class="td" onclick="myFunction()"></td></tr>
</table>
<script type="text/javascript">
....
But to your question more precisely: you have created one cell, and attached an onclick event handler to it and it only. The javascript code you grabbed actually appends new rows and cells to the table, and those don't have onclick handlers assigned.
So I'd try something like this instead:
<script type="text/javascript">
var table = $("#results");
table.on("click", "td", myFunction); // <-- magic!
var url = "http://dbpedia.org/sparql";
The "magic" line is the sweet part: it attaches the handler on the whole table, but filter the events by the "td" selector. Ideal when you are adding DOM elements dynamically...
And then you don't need to set your initial td, then one that is empty at the top of your table and clickable... Instead, just place an empty table on your page:
<body>
<table id="results"></table>
<script type="text/javascript">
....
Hope this helps!
While looking over your code you seam to only have the click event on the static
<table id="results">
<td class="td" onclick="myFunction()"></td>
</table>
When you add the dynamical the is no class or onclick event. You can fix this by either adding the onclick to the td dynamically or running a script that sets all the tds in that table to have the same click event.
function getTableCell(fieldName, rowData) {
//var td = $("<td></td>");
var td = $("<td class="td" onclick="myFunction()"></td>");
var fieldData = rowData[fieldName];
//alert("fieldName = ["+fieldName +"] rowData[fieldName][value] = ["+rowData[fieldName]["value"] + "]");
td.html(fieldData["value"]);
return td;
}
or
$("#results td").click(function(){
var x;
if (confirm("Press a button!") == true) {
x = "You pressed OK!";
} else {
x = "You pressed Cancel!";
}
}

jQuery data(): can't get stored data using jQuery selectors

I want to store some information in DOM elements (rows of table). I think I can do it using jQuery's data() function. I wrote some test code and found out that I can't get the stored data from elements using jQuery selectors. Is it possible? Maybe I'm doing something wrong?
Here is the simple code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuery data() test</title>
<script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
</head>
<body>
<table id="myTable">
<tbody>
<tr id="rowPrototype" style="display:none;">
<td class="td1"></td>
<td class="td2"></td>
</tr>
</tbody>
</table>
<script>
var table = $("#myTable");
for (var i = 0; i < 5; i++) {
var newRow = $("#rowPrototype").clone();
newRow.removeAttr("style");
newRow.removeAttr("id");
$.data(newRow, "number", i);
console.log("Data added to row: " + $.data(newRow, "number"));
var tds = newRow.find("td");
tds.text("test");
table.append(newRow);
}
var trs = table.find("tr");
trs.each(function () {
var tr = $(this).text();
var data = $.data(tr, "number");
console.log("number: " + data);
});
</script>
</body>
</html>
I expect the following output:
number: undefined (row prototype)
number: 0
number: 1
number: 2
number: 3
number: 4
But actual is:
number: undefined
number: undefined
number: undefined
number: undefined
number: undefined
number: undefined
So what's wrong with this code?
UPD
You can test it here: https://jsfiddle.net/rfrz332o/3/
$.data() expects an actual DOM element as the first argument, not a jQuery object. You can $(selector).data() with jQuery objects. I'd suggest you change this:
$.data(newRow, "number", i);
console.log("Data added to row: " + $.data(newRow, "number"));
to this:
newRow.data("number", i);
console.log("Data added to row: " + newRow.data("number"));
And, then change this:
var trs = table.find("tr");
trs.each(function () {
var tr = $(this).text();
var data = $.data(tr, "number");
console.log("number: " + data);
});
to this:
table.find("tr").each(function () {
console.log("number: " + $(this).data("number"));
});
You messed with data method. You weren't applying data to dynamic created row. To see result, please check your console.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuery data() test</title>
<script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
</head>
<body>
<table id="myTable">
<tbody>
<tr id="rowPrototype" style="display:none;">
<td class="td1"></td>
<td class="td2"></td>
</tr>
</tbody>
</table>
<script>
var table = $("#myTable");
for (var i = 0; i < 5; i++) {
var newRow = $("#rowPrototype").clone();
newRow.removeAttr("style");
newRow.removeAttr("id");
newRow.data("number", i);
console.log("Data added to row: " + newRow.data("number"));
var tds = newRow.find("td");
tds.text("test");
table.append(newRow);
}
var trs = table.find("tr");
trs.each(function () {
var tr = $(this).text();
var data = $(this).data("number")
console.log("number: " + data);
});
</script>
</body>
</html>
$.data() expects DOM element, not jQuery object. Add [i] or use .get(i) at $.data(newRow[i], "number", i); and all js that follows where $.data() is used to reference DOM element.
There is also an issue with the for loop. If there is actually only one tr element and two td elements within #myTable, when i reaches 2 , if the selector included i the result would be undefined, as the maximum index of td elements would still be 1 within the cloned table ; whether $.data() or .data() is used. Similarly for the one tr element within #myTable; when i reaches 1
jQuery.data( element, key, value )
element
Type: Element
The DOM element to associate with the data.

Using a different image in a script based on the user's choice from a <select>

I'm using a script that shows an animation following the mouse cursor. I initialize it by running this code:
<SCRIPT LANGUAGE="JavaScript">
function JSFX_StartEffects()
{
JSFX.MakeMouseSquidie (15,"<img src='JSFX/ant_head.gif'>" ,"<img src='JSFX/ant_tail.gif'>"
);
}
</SCRIPT>
This is one of many functions that run onload, so I'm using jQuery's DOM ready handler:
<script language="javascript" type="text/javascript">
$(document).ready(function(){ JSFX_StartEffects() });
</SCRIPT>
This is working fine, but I'd like to add the option for the user to chose a different pair of images for the animation. I have four different pairs of options, so I added a <select> to my document:
<div>
<div class="bebete">
<div>Choisis ta Bebete ! :))))</div>
<br>
<div>
<select id="select1">
<option selected>alien_ant</option>
<option>alien_arachnid</option>
<option>cute_worm</option>
<option>alien_caterpillar</option>
</select>
</div>
<div>
<br><br>
<img id="preview1" alt="image" src="http://tip-top-torrents.net/JSFX/alien_ant.jpg"
width="180" h eight="180">
<h3 id="random1"></h3>
</div>
<br>
</div>
<script type="text/javascript">
var images = [];
var select1 = window.document.getElementById("select1");
var preview1 = window.document.getElementById("preview1");
var random1 = window.document.getElementById("random1");
var selectLength = select1.length;
images[0] = "http://tip-top-torrents.net/JSFX/alien_ant.jpg";
images[1] = "http://tip-top-torrents.net/JSFX/alien_arachnid.jpg";
images[2] = "http://tip-top-torrents.net/JSFX/cute_worm.jpg";
images[3] = "http://tip-top-torrents.net/JSFX/alien_caterpillar.jpg";
function edit_image1() {
var index = select1.selectedIndex;
if (index !== 0) {
preview1.src = images[index];
random1.style.visibility = "hidden";
} else {
preview1.src = images[Math.floor(Math.random() * selectLength)];
random1.style.visibility = "visible";
}
return true;
}
select1.onchange = edit_image1;
</script>
</div>
I'm now trying to figure out how to apply the user's choice when initializing the animation.
<SCRIPT LANGUAGE="JavaScript">
function JSFX_StartEffects()
{
var Img.src = document.getElementById('preview1.src');
Here I need to use a condition. If the user has chosen alien_ant, then it must be initialized with this pair of images:
JSFX.MakeMouseSquidie (15,"<img src='JSFX/ant_head.gif'>" ,"<img src='JSFX/ant_tail.gif'>");
If not, I need to compare the user's choice to the other options and apply the appropriate image pair.
JSFX.MakeMouseSquidie (15,"<img src='JSFX/worm_head.gif'>" ,"<img src='JSFX/worm_tail.gif'>");
JSFX.MakeMouseSquidie (15,"<img src='JSFX/spider_head.gif'>" ,"<img src='JSFX/spider_tail.gif'>");
JSFX.MakeMouseSquidie (15,"<img src='JSFX/alien_head.gif'>" ,"<img src='JSFX/alien_tail.gif'>");
}
</SCRIPT>
What is the best way to do this?
You can find the original script I'm using near the end of this page, under "MouseSquidie".
If all of your images are named systematically you could do something like this:
Set the value of your options to the variable part of the file name:
<option value="ant" selected="selected">Ant</option>
<option value="arachnid">Arachnid</option>
<option value="worm">Worm</option>
<option value="caterpillar">Caterpillar</option>
then replace all the js you got there and call the trailing mouse function with the value from that select element like this:
$(function() {
$("#select1").change(function() {
JSFX.MakeMouseSquidie (15,"<img src='JSFX/" + $(this).val() + "_head.gif'>" ,"<img src='JSFX/" + $(this).val() + "_tail.gif'>");
});
});

Categories