Go Back   CodingForums.com > :: Client side development > JavaScript programming > DOM and JSON scripting

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 09-13-2012, 11:38 PM   PM User | #1
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
Problem with setting onclick function using createElement

I'm not very good at Javascript, but I can usually get done what I need to get done. Today, however, I've beat my head against the wall for hours and need some help.

I've got two simple functions. One adds a dynamic textbox and button to an existing form, the other removes the box/button. Any number of box/button combinations can be added.

The add code works fine. The remove code works fine IF I STATICALLY ADD THE BOX/BUTTON AND REFERENCE THE REMOVE CODE. However, if I dynamically add the box/button, the button never calls the remove code. I've tried a bunch of different ways, but it just sits there. Here's the code:

Code:
<script type="text/javascript">
function RemoveTask(intTaskNumber)
{
	strFieldName = "txtTask" + intTaskNumber;
	strFieldName2 = "btnTask" + intTaskNumber;
	
	var objHandler = document.getElementById("lstValues");
	objHandler.removeChild(document.getElementById(strFieldName));
	objHandler.removeChild(document.getElementById(strFieldName2));
	
	alert("Delete Code Invoked");
}
</script>

<script type="text/javascript">
function formvalidation(frmValues)
{

	intCount = document.frmTestData.txtTaskCount.value;
	intCount = parseInt(intCount) + parseInt(1);
	document.frmTestData.txtTaskCount.value = intCount
	
	strFieldName = "txtTask" + intCount;
	strFieldName2 = "btnTask" + intCount;
	alert('Name: ['+strFieldName2+']');
	strSubName = "RemoveTask(" + intCount + ");"

	var element = document.createElement("input");
	element.setAttribute("type", "Textbox");
	element.setAttribute("value", document.frmValues.txtNewValue.value);
	element.setAttribute("name", strFieldName);

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(element);
    
	var button = document.createElement("button");
	button.value = "Remove Task";
	button.name = strFieldName2;
	button.onclick = function(){RemoveTask(intCount);};

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(button);
	
	document.frmValues.txtNewValue.value = "";

	return false;
}
</script>
Any ideas?
RGVBaptist is offline   Reply With Quote
Old 09-14-2012, 12:44 AM   PM User | #2
xelawho
Senior Coder

 
xelawho's Avatar
 
Join Date: Nov 2010
Posts: 2,437
Thanks: 52
Thanked 453 Times in 451 Posts
xelawho will become famous soon enoughxelawho will become famous soon enough
can you show us your html, too... it's kind of hard to guess what your form(s) look like.
xelawho is offline   Reply With Quote
Old 09-14-2012, 03:20 AM   PM User | #3
rdspoons
New Coder

 
Join Date: Jun 2009
Posts: 81
Thanks: 0
Thanked 8 Times in 8 Posts
rdspoons is on a distinguished road
This may help.
You can compare the code and comments to your original code
Code:
<script type="text/javascript">

//replaced intTaskNumber argument with a button object (n)
function RemoveTask(n)
{
	//set the intTaskNumber variable from the buttons expando intCount property
	intTaskNumber= n.intCount;
	strFieldName = "txtTask" + intTaskNumber;
	strFieldName2 = "btnTask" + intTaskNumber;

	var objHandler = document.getElementById("lstValues");
	objHandler.removeChild(document.getElementById(strFieldName));
	objHandler.removeChild(document.getElementById(strFieldName2));
	
	alert("Delete Code Invoked");
}
</script>

<script type="text/javascript">
function formvalidation(frmValues)
{

	intCount = document.frmTestData.txtTaskCount.value;
	intCount = parseInt(intCount) + parseInt(1);
	document.frmTestData.txtTaskCount.value = intCount
	
	strFieldName = "txtTask" + intCount;
	strFieldName2 = "btnTask" + intCount;
	alert('Name: ['+strFieldName2+']');
	strSubName = "RemoveTask(" + intCount + ");"

	var element = document.createElement("input");
	element.setAttribute("type", "Textbox");
	element.setAttribute("value", document.frmValues.txtNewValue.value);
	element.setAttribute("name", strFieldName);
	//you need to add an id to the element for getElementById use in RemoveTask
	element.setAttribute("id", strFieldName);

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(element);
    
	var button = document.createElement("button");
	button.value = "Remove Task";
	button.name = strFieldName2;
	//you need to add a button id for getElementById use in RemoveTask
	button.id = strFieldName2;
	//assign the current value of intCount as an expando property when the button is created
	button.intCount=intCount;
	//To removes the issue of intCount always returning its last assigned value,
	//call RemoveTask with the clicked button object.
	button.onclick = function(){RemoveTask(this)};

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(button);
	
	document.frmValues.txtNewValue.value = "";

	return false;
}
rdspoons is offline   Reply With Quote
Users who have thanked rdspoons for this post:
RGVBaptist (09-14-2012)
Old 09-14-2012, 03:37 PM   PM User | #4
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
Okay, I've cut out all non-essential code and this is what I have left. Yes, I know tables are the scourge of the earth and should be avoided at all costs. That said, they are still here. I don't think they are the issue though. My problem remains that I can't get the function to 'attach' to the button dynamically. It just does nothing. No errors....no nothing.

Code:
<head>
</head>
<body>

<table cellspacing=4 cellpadding=4 border=1 align=left>
	<tr>
		<td>
			<font class="Normal_Text">
			<a class="Link" href="<%=gstrRootPath%>/Providers/ViewCustomer.asp?CID=<%=intCID%>"><%=strName%></a>
			>
			<a class="Link" href="<%=gstrRootPath%>/Providers/ViewLocations.asp?CID=<%=intCID%>">Locations</a>
			>
			<a class="Link" href="<%=gstrRootPath%>/Providers/ViewLocation.asp?LID=<%=intLID%>"><%=strAddressLine1%></a>
		</td>
	</tr>
	<tr>
		<td colspan=100%><font class="Normal_Text"><b>Last Edited By: <i><%=strLastChangedName%> on <%=dteLastChangeDate%></td>
	</tr>
	<tr>
		<td colspan=2><font class="Page_Header">Test Tasks</font></td>
	</tr>
	<tr>
		<td colspan=100%>
			<form name="frmValues" action="" onsubmit="return formvalidation(frmValues)" method="post">
				<input type="textbox" name="txtNewValue"></input>
				<input onclick="return formvalidation(frmValues)" type="submit" name="cmdSubmit" value="Add New Task"></input>
			</form>
			<form METHOD="POST" ACTION="ViewTest.ASP" id="frmTestData" name="frmTestData">
			<input type="hidden" name="txtTaskCount" value="0"></input>
		</td>
	</tr>
	<tr>
		<td colspan=100% align=left id="lstValues" name="lstValues">
			<input type="textbox" value="0" name="txtTask0"></input>
			<input type="button" value="Remove Task" name="btnTask0" onclick="RemoveTask2(0)"></input>
		</td>
	</tr>
	</form>
</table>

</body>

<script type="text/javascript">
function RemoveTask2(intTaskNumber)
{
	strFieldName = "txtTask" + intTaskNumber;
	strFieldName2 = "btnTask" + intTaskNumber;
	
	var objHandler = document.getElementById("lstValues");
	objHandler.removeChild(document.getElementById(strFieldName));
	objHandler.removeChild(document.getElementById(strFieldName2));
	
	alert("Delete Code Invoked");
}
</script>

<script type="text/javascript">
function RemoveTask(n)
{
	intTaskNumber = n.intCount;
	strFieldName = "txtTask" + intTaskNumber;
	strFieldName2 = "btnTask" + intTaskNumber;
	
	var objHandler = document.getElementById("lstValues");
	objHandler.removeChild(document.getElementById(strFieldName));
	objHandler.removeChild(document.getElementById(strFieldName2));
	
	alert("Delete Code Invoked");
}
</script>

<script type="text/javascript">
function formvalidation(frmValues)
{

	intCount = document.frmTestData.txtTaskCount.value;
	intCount = parseInt(intCount) + parseInt(1);
	document.frmTestData.txtTaskCount.value = intCount
	
	strFieldName = "txtTask" + intCount;
	strFieldName2 = "btnTask" + intCount;
	//alert('Name: ['+strFieldName2+']');
	strSubName = "RemoveTask(" + intCount + ");"

	var element = document.createElement("input");
	element.setAttribute("type", "Textbox");
	element.setAttribute("value", document.frmValues.txtNewValue.value);
	element.setAttribute("name", strFieldName);
	element.setAttribute("id", strFieldName);

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(element);
    
	var button = document.createElement("button");
	button.value = "Remove Task";
	button.name = strFieldName2;
	button.id = strFieldName2;
	button.intCount = intCount;
	//button.onclick = function(){RemoveTask(intCount);};
	button.onclick = function(){RemoveTask(this);};

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(button);
	
	document.getElementById("lstValues").innerHTML = document.getElementById("lstValues").innerHTML + "<br>";
	document.frmValues.txtNewValue.value = "";

	return false;
}
</script>

Last edited by RGVBaptist; 09-14-2012 at 04:02 PM.. Reason: Changing included code
RGVBaptist is offline   Reply With Quote
Old 09-14-2012, 03:46 PM   PM User | #5
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
RDSpoons: Thanks for the coding suggestions. You are, of course, right, and those changes are very reasonable. However, I implemented them and am having the same problem. My issue is not so much passing the variable as it is getting the function to actually fire. It's like it is just not attached. I click the buttons and nothing happens -- no errors, nothing. The debugger just sits there too.....like I didn't click anything. It's really weird.
RGVBaptist is offline   Reply With Quote
Old 09-14-2012, 05:02 PM   PM User | #6
xelawho
Senior Coder

 
xelawho's Avatar
 
Join Date: Nov 2010
Posts: 2,437
Thanks: 52
Thanked 453 Times in 451 Posts
xelawho will become famous soon enoughxelawho will become famous soon enough
Your original code was very close to working - there only problem was that you were assigning the new elements names and then trying to delete them using IDs...

Code:
<script type="text/javascript">
function RemoveTask(intTaskNumber)
{
	strFieldName = "txtTask" + intTaskNumber;
	strFieldName2 = "btnTask" + intTaskNumber;
	
	var objHandler = document.getElementById("lstValues");
	objHandler.removeChild(document.getElementById(strFieldName));
	objHandler.removeChild(document.getElementById(strFieldName2));
	
	alert("Delete Code Invoked");
}
</script>

<script type="text/javascript">
function formvalidation(frmValues)
{

	intCount = document.frmTestData.txtTaskCount.value;
	intCount = parseInt(intCount) + parseInt(1);
	document.frmTestData.txtTaskCount.value = intCount
	
	strFieldName = "txtTask" + intCount;
	strFieldName2 = "btnTask" + intCount;
	alert('Name: ['+strFieldName2+']');
	strSubName = "RemoveTask(" + intCount + ");"

	var element = document.createElement("input");
	element.setAttribute("type", "Textbox");
	element.setAttribute("value", document.frmValues.txtNewValue.value);
	element.id= strFieldName;

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(element);
    
	var button = document.createElement("button");
	button.innerHTML = "Remove Task";
	button.id = strFieldName2;
	button.onclick = function(){RemoveTask(intCount);};

	var foo = document.getElementById("lstValues");
 
    //Append the element in page (in span).
	foo.appendChild(button);
	
	document.frmValues.txtNewValue.value = "";

	return false;
}
</script>
xelawho is offline   Reply With Quote
Users who have thanked xelawho for this post:
RGVBaptist (09-14-2012)
Old 09-14-2012, 05:18 PM   PM User | #7
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
Quote:
Originally Posted by xelawho View Post
Your original code was very close to working - there only problem was that you were assigning the new elements names and then trying to delete them using IDs...
I appreciate the thought, but that can't be it. If you will check the latest code that I put up (not the original), you will see that I am indeed using ID's now as well. The problem isn't in the delete routine -- that routine works fine. The problem is that I can't get it to actually call the delete routine. It just ignores it altogether.
RGVBaptist is offline   Reply With Quote
Old 09-14-2012, 05:23 PM   PM User | #8
xelawho
Senior Coder

 
xelawho's Avatar
 
Join Date: Nov 2010
Posts: 2,437
Thanks: 52
Thanked 453 Times in 451 Posts
xelawho will become famous soon enoughxelawho will become famous soon enough
did you try the code in my post? works ok for me...
xelawho is offline   Reply With Quote
Old 09-14-2012, 06:17 PM   PM User | #9
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
Quote:
Originally Posted by xelawho View Post
did you try the code in my post? works ok for me...
Well, I'll be. It does work (almost). Sorry about that. I actually had to include the reference to 'this' that was mentioned above, as without that it always referenced a single button, but otherwise it works great now.

REALLY appreciate the help everyone. Thanks a bunch!
RGVBaptist is offline   Reply With Quote
Old 09-14-2012, 09:55 PM   PM User | #10
rdspoons
New Coder

 
Join Date: Jun 2009
Posts: 81
Thanks: 0
Thanked 8 Times in 8 Posts
rdspoons is on a distinguished road
You need to watch out for overwriting your dynamic srcripts when you use .innerHTML.

The DOM can be used to add the break, instead of using innerHTML, and it will avoid overwrite issues:
In place of...
document.getElementById("lstValues").innerHTML = document.getElementById("lstValues").innerHTML + "<br>";
You can use...
document.getElementById("lstValues").appendChild(document.createElement("br"));
rdspoons is offline   Reply With Quote
Users who have thanked rdspoons for this post:
RGVBaptist (09-14-2012)
Old 09-14-2012, 10:15 PM   PM User | #11
RGVBaptist
New to the CF scene

 
Join Date: Sep 2012
Posts: 6
Thanks: 3
Thanked 0 Times in 0 Posts
RGVBaptist is an unknown quantity at this point
Quote:
Originally Posted by rdspoons View Post
You need to watch out for overwriting your dynamic srcripts when you use .innerHTML.

The DOM can be used to add the break, instead of using innerHTML, and it will avoid overwrite issues:
In place of...
document.getElementById("lstValues").innerHTML = document.getElementById("lstValues").innerHTML + "<br>";
You can use...
document.getElementById("lstValues").appendChild(document.createElement("br"));
lol -- well that would have certainly been easier than the workaround I put in place. Will have to change my code to use what you just gave. I've been out of the loop for many years, so some of my programming methods/styles are severely antiquated. I can make it do what I want, but it ain't pretty. Thanks for the help.
RGVBaptist is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 06:32 PM.


Advertisement
Log in to turn off these ads.