glenngv 09-11-2002, 03:51 AM im creating a button dynamically on click of a button.
but the added onclick handler on the created button is not executed.
i've verified that the handler was added by looking thru the generated HTML using IE's document.documentElement.outerHTML. It's there but when the button is clicked the function showTxt() is not executed. If I save the generated code in a file and executes it, it runs OK.
What's the reason behind that?
here's the code:
function add(){
myDiv = document.getElementById("div");
obj = document.createElement("input");
obj.type = "button";
obj.name = "btnNew";
obj.id = "btn1";
obj.value = "New Row";
obj.onclick = "showTxt('test')";
myDiv.appendChild(obj);
//workaround below
//document.getElementById("btn1").onclick=function(){showTxt('test')};
}
function showTxt(txt){
alert(txt);
}
I've added a workaround which is commented above but just wondering why obj.onclick statement doesnt work.
realisis 09-11-2002, 10:56 AM try omitting the quotes:
obj.onclick = showTxt('test');
...
PLEASE NOTE: If the above still doesn't work, it's because normally when you register an event-handler this way (outside of a tag), JS syntax requires that the parentheses which normally indicate a function or a method be omitted. Example:
obj.onclick = showTxt
This would be correct and normally works, but in this particular case it raises the issue of how to pass the variable into the function then... I've wondered about this myself - hopefully somebody else here has an answer.
piglet 09-11-2002, 11:12 AM Hi,
The answer is normally to pass the data to the object on the constructor, store it in the new object, and then reference it whenever you need it:
<HTML><BODY>
<SCRIPT LANGUAGE="JavaScript">
<!--
but=0;
function add(what){
myDiv = document.getElementById("div");
obj = document.createElement("input");
obj.type = "button";
obj.name = "btnNew";
obj.id = "btn1";
obj.value = "New Row "+ ++but;
obj.text = what + but;
obj.onclick = showTxt;
myDiv.appendChild(obj);
}
function showTxt(){
alert(this.text);
}
//-->
</SCRIPT>
<A HREF="javascript:add('Text of your choice for button ')">add</A>
<div id="div"> </div>
</BODY>
</HTML>
(with java script as javascript without the space)
glenngv 09-12-2002, 06:38 AM tnx for your replies.
i just put the sample functions for the sake of simple illustration but the actual function (which has 3 arguments) to be added on the onclick handler is called by several functions and event handlers, so modifying the existing function is not the option. So maybe I'll stick with the workaround I implemented.
Tnx again, i appreciate your help :)
BrainJar 09-12-2002, 03:14 PM The problem is that .onclick and all other event handlers take a function reference ( onclick=showTxt; ) , not function call ( onclick=showTxt('abc') ). So you can't pass arguments. Event handlers always get one argument, an event object - except for in IE where there is no argument, since it has one global event object (window.event).
It's the same when you use event handlers in an HTML tag, as in
<a href="" onclick="showTxt('abc'); return false;">....</a>
What actually happens is that the browser creates an anonymous function that looks somewhat like this:
function onclick(event) {
showTxt('abc');
return false;
}
If you use a variable in the above:
<a href="" onclick="showTxt(myVar); return false;">....</a>
it looks for a global variable named "myVar."
function onclick(event) {
showTxt(myVar);
return false;
}
So if you need to pass different arguments to the event handler, you do what piglet suggested, assign them as properties to the object so you can reference them from that object using "this.myPropName".
obj.onclick = function(){showTxt('test')}
coxy :)
piglet 09-13-2002, 08:44 AM Hi coxy,
Yes - that was the workaround which they were trying not to use!
//workaround below
//document.getElementById("btn1").onclick=function(){showTxt('test')};
adios 09-14-2002, 12:39 AM Since when is wrapping an HTML event handler function call in a Function object a 'workaround'? That's what the browser does, when you do the assignment in HTML....
Guardian23 09-17-2002, 08:30 AM I have the same problem, but what I did was slightly different:
//one of two ways
//#1
obj.onclick = tmpfnc
function tmpfnc () {
realthing (par1, par2, par3)
}
//#2
obj.onclick = realthing
function realthing () {
if (arguments.length != 0) {
//act on arguments, calling them as arguments[0], [1] and [2]
//respectively
/*dostuff*/
} else {
//assume arguments and act on that
/*dostuff*/
}
}
But that's assuming that all of your links use the same stuff...
Guardian
*just a thought*
glenngv 09-17-2002, 09:54 AM it works now with this code:
function add(){
myDiv = document.getElementById("div");
obj = document.createElement("input");
obj.type = "button";
obj.name = "btnNew";
obj.value = "New Row";
obj.onclick = function(){showTxt('test')};
myDiv.appendChild(obj);
}
function showTxt(txt){
alert(txt);
}
Since when is wrapping an HTML event handler function call in a Function object a 'workaround'? That's what the browser does, when you do the assignment in HTML....
i consider
document.getElementById("btn1").onclick=function(){showTxt('test')};
as a "workaround" since instead of directly wrapping onclick handler to the object returned by document.createElement("input"), i have to put an id attribute and using
document.getElementById("btn1").onclick=function(){showTxt('test')};
ONLY after that created element has been appended to its parent element.
adios 09-17-2002, 06:25 PM glenn...
Didn't recommend:
document.getElementById("btn1").onclick=function(){showTxt('test')};
..but coxy's terse:
obj.onclick = function(){showTxt('test')}
approach. Take a look in there:
<html>
<head>
<title>untitled</title>
</head>
<body>
<a href="#" onclick="alert('is this wrapped?')">test</a>
<script type="text/javascript" language="javascript">
alert(document.links[0].onclick);
alert(typeof document.links[0].onclick);
</script>
</body>
</html>
:D
glenngv 09-18-2002, 02:28 AM didn't say you recommended it, i just explained why i called that solution a "workaround"
adios 09-18-2002, 02:48 AM Oops, confused you with piglet - who compared the correct technique with what you had already termed (accurately) as a 'workaround'. cheers ;)
adios
piglet 09-18-2002, 08:42 AM WTF are you talking about adios?
...piglet - who compared the correct technique with what you had already termed (accurately) as a 'workaround'
I was comparing this from coxy:
obj.onclick = function(){showTxt('test')}
with this from glenngv
//workaround below
//document.getElementById("btn1").onclick=function(){showTxt('test')};
I was comparing the assignment of an anonymous function to the object with the assignment of an anonymous function to the object which glenngv called his 'workaround'.
mamtakansal 03-09-2004, 10:16 PM I need to create a variable number of rows (with two data tags) in an html table, based on a variable evaluated in javascript code. The add() function given in this thread, somewhat solves this problem of mine, but not completely. As it can create a variable number of elements, but not variable number of rows in a table.
I am wondering if it is possible to create a variable number of rows with two data elements in an html table from a javascript function?
Thanks a lot in advance!
sad69 03-11-2004, 07:08 PM Of course, it is exactly the same idea -- just different code...
//tb is the tbody element of the table
//n is the number of rows
function addRows(tb, n) {
for(var i = 0; i < n; i++) {
var tr = document.createElement("<TR>");
var td1 = document.createElement("<TD>");
var td2 = document.createElement("<TD>");
//create something here to append to TD1/TD2
tr.appendChild(td1);
tr.appendChild(td2);
tb.appendChild(tr);
}
}
Hope that helps,
Sadiq.
mamtakansal 03-15-2004, 02:11 PM Thanks a lot for the response! It certainly helped. I also found a great online resource to dynamically generate an HTML form:
http://www.pageresource.com/dhtml/ryan/part4-1.html
mamtakansal 03-16-2004, 09:38 PM I am still having trouble in creating table rows dynamically. Here is the complete code:
************************************************
<HTML>
<HEAD>
</HEAD>
<BODY TOPMARGIN="1" LEFTMARGIN="1" MARGINWIDTH="0" MARGINHEIGHT="1" bgcolor="#ffffff">
<FORM NAME="MainForm" METHOD="post">
<div id="Table" style="position:absolute; left:5px; top:128px; height:20; width:964;">
<table width="964" border="0" cellpadding="10" cellspacing="1">
<table border="0" cellpadding="2" cellspacing="0">
<tr>
<td valign="top">
<span class="tabletitle">Market Briefing Mapping</span>
<table width="100%" border="0" cellpadding="4" cellspacing="1">
<TD><SELECT NAME="industryRepList" SIZE=6 multiple onChange='displayMappedTopics()'><OPTION VALUE="PTKIDFD~Baby Food" class="datacellT">001 Babyfoods</OPTION><OPTION VALUE="PTROLLS~Bakery Products" class="datacellT2">002 Baked goods/bakery products</OPTION><OPTION VALUE="PTCKEE~Cookies" class="datacellT">003 Cookies/biscuits and crackers</OPTION><OPTION VALUE="AGCEREAL~Cereals & Breakfast Food Industry" class="datacellT2">004 Breakfast cereals</OPTION><OPTION VALUE="AGDAIRY~Dairy Food Industry" class="datacellT">007 Cheese</OPTION></SELECT></TD>
</table>
</span>
</td>
<td valign="top">
<span class="tabletitle">Mapped Topics</span>
<div id="showTopics" style="position:relative; top:5px; overflow:scroll; height:100; width:464; text-align:left;">
<table id="mappedTopicsTable" width="100%" border="0" cellpadding="4" cellspacing="1" class="tableborder">
</table>
</div>
</span>
</td>
</tr>
</table>
</table>
</div>
</FORM>
</BODY>
</HTML>
<SCRIPT>
<!--
var mktBriefingsToAdd = new Array();
var repNumsToAdd = new Array();
var mktBriefingsToDelete = new Array();
function getSelectedItem(listObject) {
var obj = new Object ();
for (var j = 0; j < listObject.options.length; j++) {
if (listObject.options[j].selected == true) {
obj.text = listObject.options[j].text;
obj.value = listObject.options[j].value;
break;
}
}
return obj;
}
function displayMappedTopics() {
var retObj = getSelectedItem(document.MainForm.industryRepList);
parseTopicData (retObj.value);
}
function parseTopicData(topicData) {
var arrTokensRec = topicData.split("|");
var rowelement, datatable, colelement, text;
datatable = document.getElementById("mappedTopicsTable");
for (var i=0; i < arrTokensRec.length; i++) {
var arrTokensCol = arrTokensRec[i].split("~");
rowelement = document.createElement("tr");
colelement = document.createElement("td");
alert ("arrTokensCol[0] : " + arrTokensCol[0]);
text = document.createTextNode(arrTokensCol[0]);
colelement.appendChild(text);
rowelement.appendChild(colelement);
//rowelement.innerHTML = "<td>arrTokensCol[0]</td>";
datatable.appendChild(rowelement);
alert ("datatable last child: " + document.getElementById("mappedTopicsTable").lastChild);
}
}
-->
</SCRIPT>
**************************************************
In the above code, there is a list box on left with some items in it. On the right side, is the table that I am trying to create dynamically, by clicking on an item on the left. When I click on an item in the list box on left, nothing happens. Is it because of the nested tables?
Any help will be greatly appreciated!
sad69 03-16-2004, 09:52 PM The most frustrating part of learning to play with DOM and creating tables that nobody told me was that you need to use TBODY tags.
I didn't see any in your posted code, and that is probably the main reason you don't see anything happening.
TBODY tags must encapsulate any TR tags you want your audience to see.
For example:
<table>
<tbody>
<tr>
<td>Some data</td>
</tr>
</tbody>
</table>
If you use HTML to create the above, ommitting the TBODY tags will not affect your output. However, if you use DOM to create the above, ommitting the TBODY tags will make your output disappear!
It's sort of bizzarre, and I'm not sure why it's not stressed more either in HTML or DOM more but that's the way it's been for me. If I hadn't scanned the web for nearly a day and wondered what the heck the TBODY tags were and why I kept seeing them, I never would have figured it out.
Hope that helps,
Sadiq.
mamtakansal 03-18-2004, 02:47 PM I tried 'tbody' tag and to my astonishment, it works! Thanks so much for your help!! I wonder, why it's not in DOM documentation..
Regards,
Mamta.
mamtakansal 03-18-2004, 03:19 PM 'tbody' tag is in DOM documentation. But you are right, it's not clearly emphasized.
|
|