Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

onclick function in dynamically created button 1

Status
Not open for further replies.

newbiescooby

Technical User
Dec 5, 2006
13
0
0
NZ
Hi

I wrote this function to create a series of buttons that relate to different elements of my array an pass the index value j a function. However all the buttons return the same j value.

function CreateButtons()
{
var container = document.getElementById("ButtonContainer");
for(var i=0; i<RowNum-5; i++)
{
var tempButton = null;
var j = i+5;
tempButton = document.createElement("button");
tempButton.Id = "btn" + j
tempButton.value = ContentArray[j][0]+"mm";
tempButton.onclick = function(){alert(j);};
container.appendChild(tempButton);
}
}

Thanks
 
This should work.
Code:
[b]var j;[/b]

function CreateButtons() {
	var container = document.getElementById("ButtonContainer");

	for (var i = 0; i < RowNum - 5; i++) {

		var tempButton = null;

		[b]j = i + 5;[/b]

		tempButton = document.createElement("button");
		tempButton.Id = "btn" + j
		tempButton.value = ContentArray[j][0] + "mm";
		tempButton.onclick = [b]function(e) { alert(j); };[/b]
		container.appendChild(tempButton);
	}
}

M. Brooks
 
[1] Just by reading the script to re-discover what context it is supposed to execute, it looks like there is some ambiguity. A button is created by createElement("button"), but somehow, .value is set. To have .value meaningful, it should be an input element of type button. Maybe that's what you mean. (I suppose so in [2].)

[2] To pass the index j to the handler, you've to do "much" more. I prefer to do it via custom attribute (x, herebelow). The method shows here retains its generic nature, though.
[tt]
function CreateButtons()
{
var container = document.getElementById("ButtonContainer");
for(var i=0; i<RowNum-5; i++)
{
var tempButton = null;
var j = i+5;
tempButton = document.createElement("[blue]input[/blue]");
tempButton.[red]i[/red]d = "btn" + j;
[green]//you should set as well the name if it is input element
tempButton.name="btn"+j;[/green]
tempButton.value = ContentArray[j][0]+"mm";
[blue]tempButton.setAttribute ("x",j);
tempButton.onclick = function(){
var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
alert(osrc.getAttribute("x"));
}[/blue]
container.appendChild(tempButton);
}
}
[/tt]
May be just try it out, because it is not at all clear under what context the function is executed from the original post.
 
Amendment
I've forgotton to add a line to specify the type.

[tt] [green]//etc etc...
tempButton = document.createElement("input");[/green]
[blue]tempButton.type="button";[/blue]
[green]tempButton.id = "btn" + j;
//etc etc...[/green]
[/tt]
 
Thanks, it seems to work using that code with buttons, but when applying it to tablecells it appears to have... erratic results. using this function below it works the first time, but after that it works sometimes, passing the row value sometimes, and null at other times seemingly at random:

function PopulateTableValue()
{
for(var row =fullRows-1; row>=5; row--)
{
var tableRef = document.getElementById("Tbody");
var newRow = tableRef.insertRow(0); //insert all new rows at index 0
newRow.rowId= "row"+row;
for(var col = 9; col >= 0; col--)
{
var Content = '';
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(Content);
newCell.innerHTML= '<center>'+ ContentArray[row][col]+ '</center>';
newCell.Id = "btn" + row + "," + col;
newCell.set="0"; //button switch
alert("tst2"+row);
newCell.setAttribute ("x",row);
newCell.onclick = function()
{var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
BiggerTxt(osrc.getAttribute("x"));
};
newCell.appendChild(newText);
}
}
}

function BiggerTxt(row)
{
alert("tst1" + row);
var tbodyrow = row-2;
var Table = document.getElementById("tbody");
table.deleteRow(tbodyrow);
var newRow = table.insertRow(tbodyrow);
newRow.rowId= "row"+row;
for(col = 9; col>=0; col--)
{
var Table = document.getElementById("tbody");
alert(row);
var Content = '';
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(Content);
newCell.innerHTML= '<center>'+ ContentArray[row][col]+ '</center>';
newCell.Id = "btn" + row + "," + col;
newCell.set="0"; //button switch
alert(row);
newCell.setAttribute ("x",row);
newCell.onclick = function()
{var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
BiggerTxt(osrc.getAttribute("x"));
};
if (newCell.set==0)
{
var NewContent = "<center><H1>"+ ContentArray[row][col] +"</H1></center>";
newCell.set = 1;
}
else
{
var NewContent = '<center>'+ ContentArray[row][col]+ '</center>';
newCell.set = 0;
}
newCell.innerHTML=NewContent;
}
}
 
hmmm.. actually after further investigation the problem is in the populatetablevalue function, where it randomly does not pass the value at times. Could someone tell me why this is happening? Thanks

function PopulateTableValue()
{
for(var row =fullRows-1; row>=5; row--)
{
var tableRef = document.getElementById("Tbody");
var newRow = tableRef.insertRow(0); //insert all new rows at index 0
newRow.rowId= "row"+row;
for(var col = 9; col >= 0; col--)
{
var Content = '';
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(Content);
newCell.innerHTML= '<center>'+ ContentArray[row][col]+ '</center>';
newCell.Id = "btn" + row + "," + col;
newCell.setAttribute ("set","0"); //button switch
newCell.setAttribute ("x",row);
newCell.onclick = function()
{var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
alert(osrc.getAttribute("x"));
};
newCell.appendChild(newText);
}
}
}

 
But you use innerHTML of newCell already, why then you need appendChild(newText) again?

If you stick to createElement and createText approach, this may be closer.
[tt]
function PopulateTableValue()
{
for(var row =fullRows-1; row>=5; row--)
{
var tableRef = document.getElementById("Tbody");
var newRow = tableRef.insertRow(0); //insert all new rows at index 0
newRow.[green]setAttribute("rowId","row"+row)[/green];
for(var col = 9; col >= 0; col--)
{
var Content = '';
var newCell = newRow.insertCell(0);
[red]//[/red]var newText = document.createTextNode(Content);
[red]//[/red]newCell.innerHTML= '<center>'+ ContentArray[row][col]+ '</center>';
[blue]var subelem=document.createElement("center");
var newText = document.createTextNode(Content);
subelem.appendChild(newText);[/blue]
newCell.[highlight]i[/highlight]d = "btn" + row + "," + col;
newCell.setAttribute ("set","0"); //button switch
newCell.setAttribute ("x",row);
newCell.onclick = function()
{var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
alert(osrc.getAttribute("x"));
};
[red]//[/red]newCell.appendChild(newText);
[blue]newCell.appendChild(subelem);[/blue]
}
}
}
[/tt]
ps: [1] You convention of brace should better be more consistent, you're going to confuse yourself. [2] Id should be id, mind you? unless you want a custom Id not a built-in id. [3] center-tag is old-school. But let us not complicate the matter further.
 
Amendment
I should beef up the Content variable! Insert the line for that purpose.

[tt] [green]//etc etc[/green]
var subelem=document.createElement("center");
[blue]Content=ContentArray[row][col];[/blue]
var newText = document.createTextNode(Content);
subelem.appendChild(newText);
[green]//etc etc[/green]
[/tt]
 
Thanks, that fixed the problem, but exposes another. When I click on the text element of the cell, it won't link to the correct function, but when i click the surrounding white area of the cell it will work perfectly. Is there any way I can mask the text element to redirect the clicks on the text to the cell behind?
 
That's the price to pay for using center tag. Change the whole thing to use inline style.
[tt]
function PopulateTableValue()
{ [blue]another version with inline style[/blue]
for(var row =fullRows-1; row>=5; row--)
{
var tableRef = document.getElementById("Tbody");
var newRow = tableRef.insertRow(0); //insert all new rows at index 0
newRow.setAttribute("rowId","row"+row);
for(var col = 9; col >= 0; col--)
{
var Content = '';
Content=ContentArray[row][col];
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(Content);
newCell.style.textAlign="center";
newCell.id = "btn" + row + "," + col;
newCell.setAttribute ("set","0"); //button switch
newCell.setAttribute ("x",row);
newCell.onclick = function()
{var osrc=(arguments[arguments.length-1])?(arguments[arguments.length-1]).target:window.event.srcElement;
alert(osrc.getAttribute("x"));
};
newCell.appendChild(newText);
}
}
}
[/tt]
But you know, there are myriade of minute features one wants to have or to get rid of. If you don't try to understand the driving idea/implementation, there is no hope to have somebody always standby. The reason I spell some cases out is not to do the work for you, but to facilitate your understanding with very concrete and working script...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top