Assigning Event Handlers in JS-written UI
-
I'm trying to write what I thought would be an easy Ruby. It's beginning to feel otherwise. At present I'm stumped by the following.
My Ruby depends on getting a list of scenes and layers from the model. It then draws the UI, which is at heart an array of checkboxes, one for each layer/scene intersection. Hence the UI cannot be built into the HTML, it has to be generated by JavaScript.
I've distilled down to a simple HTML, .js combo. I've discovered that you can't "document.write" the same text that would work from HTML if you want to include an onclick handler. The workaround I've been fiddling with is to create the checkbox, getElementById it and attach a reference to its onclick property. The following code shows this with buttons. The problem is, this code runs fine in Opera, but not in the browser whose name must never be spoken.
<!-- a.html --> <html> <body onload='init()'> <script src='a.js'> </script> </body> </html>
// a.js var clicker = function() { alert( 'That tickles!' ); } var clicker2 = function() { alert( 'That tickles, too!' ); } function init() { document.write( '<button id=b1> Click </button>' ); document.getElementById( 'b1' ).onclick = clicker; // this doesn't work; document.write( '<button id=b2 onclick=clicker2()> Click me, too </button>' ) // unless you add; document.getElementById( 'b2' ).onclick = clicker2; }
I do not have enough hair left to continue pulling it out at the present rate. Help!
-
Could it be possible that I am the first one trying to make a UI that depends on the content of the model? Anyone?
-
Its something that I am preparing to develop in my next script. But so far I have not touched it.
Chris
-
@martinrinehart said:
Could it be possible that I am the first one trying to make a UI that depends on the content of the model? Anyone?
A while back I was working on an Area reporter. Taking all the faces in the model and building a list of the areas for each material grouyped by component/groups-
From working with website before I never use document.write, but instead add elements using the DOM functions as that always works.
var btn = document.createElement('button'); btn.appendChild( document.createTextNode('Button Text') ); btn.onclick = clicker2;
It's more code to write though - so I often write wrapper functions. Or rather - lately I've started using jQuery, even for SU webdialogs.
-
(ps. my sample code didn't display the element being added to the document.)
-
@thomthom said:
From working with website before I never use document.write, but instead add elements using the DOM functions as that always works.
Thank you.
"... always works." I pray you are right, but I'm skeptical.
Martin
-
@martinrinehart said:
but I'm skeptical
This works:
<!-- a.html --> <html> <body onload=init()> <script src='a.js'> </script> </body> </html>
Where the DOM is created this way:
// a.js var clicker = function() { alert('That tickles!'); } function clicker2() { alert('That tickles, too!'); } function init() { var d = document; var b1 = d.createElement( 'button' ); b1.innerHTML = 'Click me!'; b1.onClick = clicker; d.body.appendChild( b1 ); var b2 = d.createElement( 'button' ); b2.innerHTML = 'Me too!'; b2.onClick = clicker2; d.body.appendChild( b2 ); alert( b1.onClick + '\n\n' + b2.onClick ); }
The only problem is, nothing happens when you click the buttons. Presumably a browser bug (v8). Workaround?
-
@martinrinehart said:
The only problem is, nothing happens when you click the buttons. Presumably a browser bug (v8).
Somebody help me out here. I hate being stupid in public.
This code doesn't work:
var b2 = d.createElement( 'input' ); b2.type = 'checkbox'; b2.onclick = clicker2; d.body.appendChild( b2 );
If you reverse the last two lines, appending to body before assigning to onclick, the onclick handler starts to work. (This after many tries in Chrome, Firefox, Opera and that other browser. My Google search engine is starting to say, "Oh, please! Not again!")
I now have a JS-generated checkbox that can call an onclick handler and I am going back to work on my Ruby. Anyone have an explanation for the above "gotcha"?
-
Again - I'm not sure. As I mentioned before I now usually use the jQuery framework. And that adds event listeners. Event listeners let you add multiple functions to the same event.
http://www.howtocreate.co.uk/tutorials/javascript/domevents
Adding event listeners might need some different treatment with your favourite browser . So it can easily end up with extra code.
Den Edward got, as usual, a good cross browser wrapper that you can use without using a framework to simply code. http://dean.edwards.name/weblog/2005/10/add-event/
I'm not sure why adding the element to the document before adding events works - and not the other way around. Maybe the added element is a copy and not a reference - and copies doesn't transfer events. (guessing here - need to fresh up on this)
-
some dynamic code that works on my Windows machine and creates another checkbox when you click on existing ones:
w = UI;;WebDialog.new w.set_html("<body>hello</body><script>add();function add(){var d = document;var b2 = d.createElement( 'input' );b2.type = 'checkbox';b2.onclick = function(){add();};d.body.appendChild(b2)}</script>") w.show
-
Martin,
- I write all my code for Windows & IE
- I noticed some of your code had attributes that were not quoted. W3C says...
- Sometimes I assemble/modify the html as a string, then use set_html. All of my html is loaded as a string
- I've got 3 or 4 'dynamic' web dialogs in an extension at
http://www.ChampionEnt.net/tech/ur/
if any of it might interest you, let me know and I can post or send the code. - Due to the 'modal window' issue, some of the code only works on a PC (settings window)
- Haven't really tested it lately on an Apple...
- Wrote some C# code to change an html file into a Ruby friendly string
HTH,
Greg
Advertisement