JavaScript is not calling a function when parameter is passed.
I am creating HTML dynamically.
checkbox2 = document.createElement("<input type=\"checkbox\" name=\"wdrs_contact\" checked=\"Yes\" onclick =\"setPartnersInfo('\"+id+\"');\" />");
function setPartnersInfo(ch)
{
alert(ch)
}
But when I do not have parameter in the function call, it is working.
details below:
function createPartnerTable() {
var partnerInfo = document.getElementById("partnersInfo");
var data = partnerInfo.value;
// everything was successful so now come back and update, first clear the old attributes table
var partnersBody = document.getElementById("partnersBody");
var rowCount = partnersBody.rows.length;
for( var i = 0; i < rowCount; i++ )
{
partnersBody.deleteRow(0);
}
if (data ==null || data.length==0)
return;
// now parse and insert each partner row
//alert("data : "+data);
var index = 0;
var lastIndex = 0;
while( index < data.length && index != -1 )
{
lastIndex = data.indexOf("|", index);
if( lastIndex == -1 ){
break;
}
var id = data.substring(index, lastIndex);
index = lastIndex + 1;
lastIndex = data.indexOf("|", index);
var name = data.substring(index, lastIndex);
index = lastIndex + 1;
lastIndex = data.indexOf("|", index);
var partnerType = data.substring(index, lastIndex);
index = lastIndex + 1;
lastIndex = data.indexOf("|", index);
var status = data.substring(index, lastIndex);
index = lastIndex + 1;
lastIndex = data.indexOf(";", index);
var jdeCode = data.substring(index, lastIndex);
//ganessin
index = lastIndex + 1;
lastIndex = data.indexOf("#", index);
var wdrsContact = data.substring(index, lastIndex);
row = partnersBody.insertRow(partnersBody.rows.length);
//check box with id for removal
var checkboxCell = row.insertCell(0);
checkboxCell.align="center";
var checkbox = document.createElement('<input type="checkbox" name="selectedPartnerIds" />');
//var checkbox = document.createElement("input");
//checkbox.type = 'checkbox';
//checkbox.checked=false;
//checkbox.name = 'selectedPartnerIds';
checkbox.value=id;
//checkbox.style.align = "center";
//checkbox.style.width = '40%';
checkboxCell.appendChild(checkbox);
var check = document.getElementsByName('selectedPartnerIds');
//Name
var nameCell = row.insertCell(1);
nameCell.appendChild(document.createTextNode(name));
//Partner Type
var partnerTypeCell = row.insertCell(2);
partnerTypeCell.align="center";
partnerTypeCell.appendChild(document.createTextNode(partnerType));
//Status
var statusCell = row.insertCell(3);
statusCell.align="center";
statusCell.appendChild(document.createTextNode(status));
//JDE Code
var jdeCodeCell = row.insertCell(4);
jdeCodeCell.align="center";
jdeCodeCell.appendChild(document.createTextNode(jdeCode));
//ganessin
var checkboxCell2 = row.insertCell(5);
checkboxCell2.align="center";
var checkbox2 = "";
//alert("wdrsContact "+wdrsContact);
var x = "setPartnersInfo("+id+")";
alert("x = "+x);
if(wdrsContact == "true")
{
alert("true");
//checkbox2 = document.createElement('<input type="checkbox" name="wdrs_contact" checked="Yes" onclick="+x+" onchange="+x+" />');
checkbox2 = document.createElement("<input type=\"checkbox\" name=\"wdrs_contact\" checked=\"Yes\" onclick =\"setPartnersInfo(\"+id+\");\" />");
//String(document.createElement('<input type="checkbox" name="wdrs_contact" checked="Yes" onchange="setPartnersInfo("+id+");"/>'))
}
else
{
alert("false");
//checkbox2 = document.createElement('<input type="checkbox" name="wdrs_contact" onclick="+x+" onchange="+x+" />');
checkbox2 = document.createElement("<input type=\"checkbox\" name=\"wdrs_contact\" onclick=\"setPartnersInfo(\"+id+\");\" />");
}
//alert("id "+id);
//checkbox2.value=id;
// alert("checkbox2 "+checkbox2);
checkboxCell2.appendChild(checkbox2);
// increment the index to process next
index = lastIndex + 1;
}
}
The following will generate a syntax error:
"onclick =\"setPartnersInfo('\"+id+\"');\""
You should use:
"onclick =\"setPartnersInfo(\'"+id+"\');\""
Or if your id is numeric (you don't need quotes):
"onclick =\"setPartnersInfo("+id+");\""
If you wish to use double quotes within a html attribute you have to convert them to "
So the following should work too:
"onclick =\"setPartnersInfo(""+id+"");\""
Although should isn't really the right word as generating html with event listeners like this is not the best approach.
So overall your string should be:
("<input type=\"checkbox\" name=\"wdrs_contact\" checked=\"Yes\" onclick =\"setPartnersInfo('"+id+"');\" />");
Although to get around the escaping all the time why not use:
('<input type="checkbox" name="wdrs_contact" checked="Yes" onclick ="setPartnersInfo(\''+id+'\');" />');
in the interest of improvement
The better way to achieve what you are doing is to split your code from your markup, and leave the browser to generate your markup, this is easier to read and tends to be faster - plus it means you don't have to worry so much about escaping quotes ;)
checkbox2 = document.createElement('input');
checkbox2.type = 'checkbox';
checkbox2.name = 'wdrs_contact';
checkbox2.checked = 'checked';
checkbox2.onclick = function(){
setPartnersInfo(id);
}
One major difference to be aware of in the above is that before when you placed your id var in the html string - it's current value was recorded in that string. With the above the reference to the id variable is remembered but not the value. If you change the value of id at any point after this, it will still change whereever it is referenced. To get around this you can use a closure.
This works by passing the value of id into a function, which basically changes the variable being used to store your value of id to stored_id, this function then returns a function that is used as your event handler. This event handler function has access to the stored_id var, and no matter how much you change id, stored_id wont be changed. It's a bit complicated, if you don't know about closures then it's a good topic to read up on.
checkbox2.onclick = (function(stored_id){
return function(){setPartnersInfo(stored_id);};
})(id);
To improve the above even further you should be avoiding using inline event handlers, so:
checkbox2 = document.createElement('input');
checkbox2.type = 'checkbox';
checkbox2.name = 'wdrs_contact';
checkbox2.checked = 'checked';
/// for modern browsers
if ( checkbox.addEventListener ) {
checkbox.addEventListener('click', function(){
setPartnersInfo('your id here');
});
}
/// for old ie
else {
checkbox.attachEvent('onclick', function(){
setPartnersInfo('your id here');
});
}
Related
I'm at a loss here.
I created a quick script that will add a new row to a table and also has the capability to delete a row.
jsFiddle -->http://jsfiddle.net/wLpJr/10/
What I want to achieve is this:
Display each value of each row (in the div with id='thedata')
I originally started off with adding a number at the end of each id, starting at '1', and incrementing each time the user adds a row.
//This is random code
var rowcount = parseInt($('#rowcount').val());
var newcount = rowcount + (1*1);
var x = $('#radioinput' + newcount).val('a value');
$('#rowcount').val(newcount);
The problem is that lets say you add 5 rows. Now delete row 3. When you loop through the table of data you will get an error because row "3" does not exist. You have rows 1, 2, 4, 5, 6. Specifically - the input with id = 'radioinput3' will not be present.
I then decided to do this:
$('#maintable > tbody > tr').each(function() {
radiovalue[i] = $("input[type='hidden']", this).map(function() {
var vid = 'radio' + i;
var myval = this.value;
var radioinput = document.createElement("input");
radioinput.type = "hidden";
radioinput.value = myval; // set the CSS class
radioinput.id = vid;
$('#maintable').append(radioinput);
}).get()
text1value[i] = $('td > input', this).map(function() {
var vid = 'text1pos' + i;
var myval = this.value;
var text1input = document.createElement('input');
text1input.type='hidden';
text1input.value = myval;
text1input.id = vid;
$('#maintable').append(text1input);
}).get()
text2value[i] = $('td > input', this).map(function() {
var vid = 'text2pos' + i;
var myval = this.value;
var text2input = document.createElement('input');
text2input.type='hidden';
text2input.value = myval;
text2input.id = vid;
$('#maintable').append(text2input);
}).get();
});
The problem here is that I'm getting 'undefined' values.
You are looping through a counter, which you increment everytime you add a new row, but do not take into account that a row can be deleted at any time. Instead, just use the each function to loop over the elements remaining in the DOM.
Add thead and tbody tags to your table, it will make your life easier.
I'm not sure why you have those hidden div to hold the input[type=radio] values, you don;t need them, access the values directly.
$('#showdata').click(function() {
$("#maintable tbody tr").each(function(i, v) {
var myp = "<p>Radio value is = " + $(this).find('input[type=radio]:checked').val()
+ "\nText1 value is = " + $(this).find('input[id$=text1]').val()
+ "\nText2 value is = " + $(this).find('input[id$=text2]').val() + "</p>";
$('#thedata').append(myp);
});
});
jsFiddle Demo
You could add a CSS class to the input text fields to make it easier to get, but i just used the jQuery ends with selector.
Also, you delete selector if far too high up the DOM tree on (document), instead restrict it as near as you can, in this case the #maintable.
I am trying to create a dynamic table with textboxes but I want the textboxes to be converted to upper case every time I write.
Any ideas on how to do this??
Currently this is how I am doing the dynamic table:
var n = 1;
function addRow(tableID,nroColumna) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
for(i=0;i<nroColumna;i++){
var cell = row.insertCell(i);
var element = document.createElement("input");
element.type = "text";
element.name = n+"0"+i;
element.size = "12";
element.id = n+"0"+i;
//element.onkeyup = function(){alert()};
cell.appendChild(element);
}
n++;
}
I was trying to do a document.getElementById(element.id).value.toUpperCase() but I am getting an error with a null value for the element.id
Any help is greatly appreciated!
If you're ok with a non JavaScript solution, you could apply this CSS to your inputs:
text-transform: uppercase;
That would make the text uppercase from the beginning...
Darkajax's solution, works, you can target it to inputs within a table with a specific ID
with
#tableid input
{
text-transform: uppercase;
}
I tested your code with the onkeyup function activated:
var n = 1;
function addRow(tableID,nroColumna) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
for(i=0;i<nroColumna;i++){
var cell = row.insertCell(i);
var element = document.createElement("input");
element.type = "text";
element.name = n+"0"+i;
element.size = "12";
element.id = n+"0"+i;
element.onkeyup = function(){alert(element.id);};
cell.appendChild(element);
}
n++;
}
And that worked. However, it uses the last element.id computed for every call to the function... so, when I created one row of 3 cells, every time I typed into a cell, it would alert "102" regardless of which cell I typed in.
This is because the onkeyup function is dynamic. It is called on the keyup action - not set when the object is created. So it uses the element.id value that exists at the time of the action, not what it was when you passed it in the first time. I hope that makes sense.
I had this issue myself on a recent project. One solution is to create a separate function for the inner workings of the for loop as such:
var n = 1;
function createRow (n, i) {
var element = document.createElement("input");
element.type = "text";
element.name = n+"0"+i;
element.size = "12";
element.id = n+"0"+i;
element.onkeyup = function(){alert(element.id);};
return element;
}
function addRow(tableID,nroColumna) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
for(i=0;i<nroColumna;i++){
var cell = row.insertCell(i);
element = createRow(n, i);
cell.appendChild(element);
}
n++;
}
This code alerts the correct element.id value.
EDIT: you can change the onkeyup() line to read:
element.onkeyup = function(){document.getElementById(element.id).value = document.getElementById(element.id).value.toUpperCase();};
And it should work as you want it to.
with jQuery it will be like
$('.yourClass').val($(this).val().toUpperCase());
or
$('#yourId').css({'text-transform' : 'uppercase'})
I want to pass a Javascript variable as a argument of a function called on onclick event of a checkbox, and the checkbox is created in innerHTML.
The code snippet is:
function populateValue(Result) {
var valueSet = new Array();
valueSet = Result.split("##");
for (i = 1; i < valueSet.length - 3; i++) {
var tr = document.createElement("tr");
var td = document.createElement("td");
tr.setAttribute("align", "left");
tr.className = "table_ce11";
td.setAttribute("align", "center");
var code = String(valueSet[i - 1]);
td.innerHTML = "<input type='checkbox' name='pCheckBox' value='111' id ='" + code + "' onClick=\"javascript:decide('" + code + "')\">";
tr.appendChild(td);
}
}
function decide(code) {
alert("here");
alert(document.getElementById(code).value);
if (document.getElementById(code).checked) alert("chked");
else alert("unchked");
}
while running this, neither am able to set the id nor to pass the argument of the function decide(). I get the error:
"undetermined string constraint".
But if I hardcode the values the function runs fine.
Any suggestions on this?
Just for starters
Split creates an array.
var valueSet = Result.split("##");
You need to test if there ARE at least 4 items in the array
if (valueSet.length <= 3) return
for (var i = 1; i < valueSet.length - 3; i++) {
no need to create a string when you string concatenate a string anyway
var code = valueSet[i - 1];
No need to use javascript: prefix and no need to pass the code when it is the same as the ID:
td.innerHTML = '<input type="checkbox" name="pCheckBox" value="111" id ="' + code + '" onClick="decide(this.id)">';
Also default align is left and you align center on the cell so get rid of
// tr.setAttribute("align", "left");
can you post more of the code and tell where things are going wrong exactly?
I have two working functions which I want to assign to two inputs:
<input type="text" id="start0" value="0" name="start[]" onkeyup="displayTotal();"/>
<input type="text" id="end0" value="0" name="end[]" onkeyup="displayTotal();"/>
I would like to be able to use a displayHoras(); onkeyup for those two too. (2 many 2s on this thread already). when I use displayHoras(); instead of displayTotal(); it works, but when I call both of them like this it doesnt:
<input type="text" id="start0" value="0" name="start[]" onkeyup="displayTotal();displayHoras();"/>
<input type="text" id="end0" value="0" name="end[]" onkeyup="displayTotal();displayHoras();"/>
Any help will be welcomed.
I'll share the code of both functions because...who knows? The problem might be there, right?
function displayTotal()
{
var tableRows = document.getElementById('budgetTable').getElementsByTagName('tr');
var totalDays = tableRows.length - 3; //Don't count the header rows and the Total rows
var totalPrice = 0;
var price = filterNum(document.getElementById( 'txtPrice' ).value);
var totalField = document.getElementById( 'txtTotal' );
var tempHours = 0;
var tempTotal = 0;
for(var i = 0; i < totalDays; i++)
{
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
tempTotal = tempHours * price;
document.getElementById("total" + i).innerHTML = formatCurrency(tempTotal);
totalPrice += tempTotal;
}
totalField.value = formatCurrency(totalPrice*1.21);
}
function displayHoras()
{
var tableRows = document.getElementById('budgetTable').getElementsByTagName('tr');
var totalDays = tableRows.length - 3;
var tempHours = 0;
var tempTotal = 0;
for(var i = 0; i < totalDays; i++)
{
tempHours = document.getElementById("end" + i).value - document.getElementById("start" + i).value;
document.getElementById("totalHoras" + i).innerHTML = tempHours;
}
}
EDIT: I added the functions that create the table below.
function keyUpCall() {displayHoras(); displayTotal();}
function addRowToTable()
{
var tbl = document.getElementById('budgetTable');
var lastRow = tbl.rows.length - 4;
var iteration = lastRow;
var entry = iteration - 1; //because we started with day0, etc
var row = tbl.insertRow(lastRow);
// day cell
var cellDay = row.insertCell(0);
cellDay.appendChild(createInput('text','dia' + entry, '', keyUpCall, 'dia' + entry));
// start cell
var cellStart = row.insertCell(1);
cellStart.appendChild(createInput('text','start' + entry, 0, keyUpCall, 'start' + entry));
// end cell
var cellEnd = row.insertCell(2);
cellEnd.appendChild(createInput('text','end' + entry, 0, keyUpCall, 'end' + entry));
// precio unitario
var cellPrecioUnitario = row.insertCell(3);
cellPrecioUnitario.appendChild(createInput('text', null, '$36', null, null));
// total HOras
var cellTotalHoras = row.insertCell(4);
cellTotalHoras.id = 'totalHoras' + entry;
// total cell
var cellTotal = row.insertCell(5);
cellTotal.id = 'total' + entry;
}
function createInput(type, id, value, action, name)
{
var el = document.createElement('input');
el.type = type;
el.id = id;
el.value = value;
el.onkeyup = action;
el.name = name;
return el;
}
At this point, the action is not even attached for some reason.
Edit2: I SOLVED THE PROBLEM!!! IUPI!! it was this line:
var totalDays = tableRows.length - 3;
In the previous version of this form I was using 3 extra rows, my client got me to add a couple extra ones for Tax and without Tax result. I changed it to:
var totalDays = tableRows.length - 5;
And that fixed it!
You can create a single function that calls both functions
function function1(){
displayTotal();
displayHoras();}
I'd recommend creating a function that then calls your two functions, e.g.:
function handleKeyUp() { // Or `updateDisplay` or some such
displayTotal();
displayHoras();
}
Putting too much text within the onXYZ attributes is problematic (though I'm not immediately seeing why yours isn't working).
Off-topic 1: I'd also suggest hooking up event handlers using DOM2 methods (addEventListener on standards-compliant browsers, attachEvent on IE8 and below) rather than using DOM0 mechanisms like onXYZ attributes.
Off-topic 2: A JavaScript library like jQuery, Prototype, YUI, Closure, or any of several others can help smooth over browser differences (and even bugs) like the event attachment stuff above, as well as providing lots of handy utility functionality. Totally optional, but using one helps you concentrate on what you're actually trying to do, without worrying about slightly different plumbing in various different browsers.
old school javascript ^^
try this instead of the attribute variant, and use bugzilla, or a javascript debugger
var checks_keyup = function() {
displayTotal();
displayHoras();
}
var inputs = document.getElementsByTagName('input');
for(var i=0;i<inputs.length;i++) {
if(/^(start|end)/.test(inputs[i].id))
inputs[i].onkeyup = checks_keyup;
}
Try calling second function withing the first function itself,
function displayTotal()
{
\\.....your code
displayHoras();
}
In javascript, how can we detect which row of the table is clicked? At present what i am doing is, i am binding the the method at run time like this.
onload = function() {
if (!document.getElementsByTagName || !document.createTextNode) return;
var rows = document.getElementById('my_table').getElementsByTagName('tbody')[0].getElementsByTagName('tr');
for (i = 0; i < rows.length; i++) {
rows[i].onclick = function() {
alert(this.rowIndex + 1);
}
}
}
[ copied from [ http://webdesign.maratz.com/lab/row_index/ ] ]
But i don't like this approach. Is there any alternative? My problem is just to get the index of the row which is clicked.
No jQuery please :D.
You can use event delegation for that. Basically you add one clickhandler to your table. This handler reads out the tagname of the clicked element and moves up the DOM tree until the containing row is found. If a row is found, it acts on it and returns. Something like (not tested yet, but may give you ideas):
var table = document.getElementById('my_table');
table.onclick = function(e) {
e = e || event;
var eventEl = e.srcElement || e.target,
parent = eventEl.parentNode,
isRow = function(el) {
return el.tagName.match(/tr/i));
};
//move up the DOM until tr is reached
while (parent = parent.parentNode) {
if (isRow(parent)) {
//row found, do something with it and return, e.g.
alert(parent.rowIndex + 1);
return true;
}
}
return false;
};
The this keyword can be used to get the parentNode of the cell, which is a <tr> element. The <tr> element has a property for the row number, .rowIndex.
The Event:
onclick='fncEditCell(this)'
The Function:
window.fncEditCell = function(argThis) {
alert('Row number of Row Clicked: ' + argThis.parentNode.rowIndex);
};
Full Working Example Here:
jsFiddle
Dynamically Set OnClick Event
Use .setAttribute to inject a click event:
cell2.setAttribute("onmouseup", 'editLst(this)');
Example of Dynamically Creating a Table:
for(var prprtyName in rtrnTheData) {
var subArray = JSON.parse(rtrnTheData[prprtyName]);
window.row = tblList.insertRow(-1);
window.cell1 = row.insertCell(0);
window.cell2 = row.insertCell(1);
window.cell3 = row.insertCell(2);
window.cell4 = row.insertCell(3);
window.cell5 = row.insertCell(4);
window.cell6 = row.insertCell(5);
window.cell7 = row.insertCell(6);
window.cell8 = row.insertCell(7);
window.cell9 = row.insertCell(8);
cell1.setAttribute("onmouseup", 'dletListing(this.title)');
cell1.setAttribute("title", "'" + subArray.aa + "'");
cell2.setAttribute("onmouseup", 'editLst(this)');
cell2.setAttribute("title", "'" + subArray.aa + "'");
cell1.innerHTML = "Dlet";
cell2.innerHTML = "Edit";
cell3.innerHTML = subArray.ab;
cell4.innerHTML = "$" + subArray.ac;
cell5.innerHTML = subArray.ad;
cell6.innerHTML = subArray.ae;
cell7.innerHTML = subArray.af;
cell8.innerHTML = subArray.ag;
cell9.innerHTML = subArray.meet;
};
This uses sectionRowIndex to get the index in the containing tBody.
function getRowIndex(e){
e= window.event || e;
var sib, who= e.target || e.srcElement;
while(who && who.nodeName!= 'TR') who= who.parentNode;
if(who){
alert(who.sectionRowIndex+1)
if(e.stopPropagation) e.stopPropagation();
else e.cancelBubble= true;
// do something with who...
}
}
onload= function(){
document.getElementById('my_table').onclick= getRowIndex;
}
I tried Alan Wells written answer, but it was returning, undefined.
So, I modified a little, to get the row index as follows:
argThis.rowIndex
This will return the row index for the row clicked.
modify the <tr> tag:
<tr onclick="fncEditCell(this)" >
Then, add a script tag at the bottom of the HTML:
<script>
window.fncEditCell = function(argThis) {
alert('Row number of Row Clicked: ' + argThis.rowIndex);
};
</script>
As an example, you can see this image: