Multiple dialog scope issue on the PC
-
I turned on the script debugging, still nothing.
But I've also narrowed down to the problem, this is so strange, now I know it's something simple, must be with the HTML or something.But check this:
class Dialog1 def outbound(selected) @dialog.execute_script("alert(0)") # fires the first time, that's it puts "firing" # fires every time end # outbound def initialize() @dialog = nil begin @dialog = UI;;WebDialog.new() @dialog.show { @dialog.add_action_callback("outbound") {|d,p| outbound(p)} @dialog.execute_script("requery()") } # show rescue SystemExit # clean exit end # begin end # initialize end # Dialog1 Class def goDialog1 () $dialog1 = Dialog1.new() end # goDialog1
When a user clicks on the button, window.location=skp fires, Ruby fires back that execute_script, I get the Javascript alert... but only once! I can keep clicking that button, and Ruby Console shows "firing", but nothing to the dialog.
So somehow my connection back to the DOM is lost, right?
I upgraded to IE10, thinking that might be it. Nope.
It has to be something simple, right?--J
-
Ugh, I think I got it.
With javascript:void(0) in the web dialog, everything after that point kills the Ruby link to the DOM.
Any, uh, reason for this bug?
I'm going to be in Boulder in a couple weeks, who's desk shall I place a doggie turd on?
(kidding)
(sort of)--J
-
I am under the impression that javascript
%(#8000BF)[**alert()**]
(at least under MSIE js,) must be called from WITHIN a javascript function.So
@dialog.execute_script("alert(0)")
should not work.BUT .. if you had a javascript function in the HTML file:
<script> function mbox(arg) { alert(arg); } </script>
then from Ruby, calling:
@dialog.execute_script("mbox('Ruby method outbound called.');")
might work better.But of course you can use Ruby-side messagebox from within the
outbound()
method, thus:
UI.messagebox('Ruby method outbound called.')
-
What are you attempting to do in simple steps (psuedocode or outline form) ?
Why do you need to complicate what you are doing by creating a "wrapper" class, that wraps an
UI::WebDialog
instance inside it ?Are you trying to create a dialog singleton class ?
-
@dan rathbun said:
I am under the impression that javascript
%(#8000BF)[**alert()**]
(at least under MSIE js,) must be called from WITHIN a javascript function.I've not had problems calling alert. Don't see why it should have to be wrapped within a function.
Also, this works:
Something else seem to be amiss.
-
I got it to work, the issue is the "javascript:void(0)"
As for why I'm wrapping a dialog in a class, it's for Mac compatibility (and generally seems a good idea). But since they are modeless on the Mac, it's the only way I could come up with nicely handling the dialog box instances and communication between them. Also I generally try to Class everything, whether Ruby or PHP or Javascript.
As for the alert calls, ThomThom is right. Not only can you call "alert(0)" just about anywhere in any method, it's the fastest and easiest way I know of testing Javascript and Ruby->Javascript communication. Particularly as this is the issue at hand, thank god I don't even have to pass a string to Javascript alert, it's just totally my BFF in that manner.
But back to the issue at hand, if you have this in a WebDialog html:
<a href="javascript:void(0)" onclick="window.location='skp;done'">Click Me!</a>
That works on a Mac, but on a PC, scope returns to Ruby, but Ruby is unable to access any dialog box elements, the DOM is completely gone. The only thing I've been able to do with the dialog is to close it. You can keep clicking the link, and Ruby will still get focus, but get_element_value and execute_script fail without any error.
So then this works:<a href="#" onclick="window.location='skp;done'">Click Me!</a>
Which is bad programming form.
See, I don't know, this discussion.I did originally find this topic:
http://sketchucation.com/forums/viewtopic.php?f=180&t=25252
But I had read it wrong, I thought it was the lack of javascript:void(0) that was killing his.So to repeat my question -- why on Earth would "javascript:void(0)" kill Ruby's access to the DOM?
That just seems such an egregious bug.
I'm going to be in Boulder in 3 weeks, so I'd like to personally thank whichever programmer is responsible for this. In a friendly way of course.--J
-
Instead of returning void, what if you prevent the event from bubbling further. That's what I do.
Also, instead of a class in a class, why not subclass?
I'll look further when I get home. Not at my computer to test right now.
Sent from my LT25i using Tapatalk 2
-
Why use a <A> element ?
Just make it a <DIV> element, which can also have onclick events.
-
Yes, there's plenty of ways around it.
But there's also nothing inherently wrong with having a link with 'javascript:void(0)' as the href, is there?
At least, in the sense of best programming practices.
In fact, it is, without fail, the best recommended practice.
So, my question remains -- why is it that every Sketchup developer in the world has to be careful to not accidentally follow best HTML practices, instead of one programmer in Boulder correcting what is ostensibly a single errant line of code?--J
-
@honkinberry said:
In fact, it is, without fail, the best recommended practice.
In terms of a JS application?
It's not in terms of website development - as then the href should be a working fallback in case of JS not being enabled. Which is why the onclick event should prevent bubbling.
None the less - that's straying besides the point.
Can you provide a complete working sample where your callbacks fail?
-
@honkinberry said:
But back to the issue at hand, if you have this in a WebDialog html:
> <a href="javascript:void(0)" onclick="window.location='skp;done'">Click Me!</a> >
That works on a Mac, but on a PC, scope returns to Ruby, but Ruby is unable to access any dialog box elements, the DOM is completely gone. The only thing I've been able to do with the dialog is to close it. You can keep clicking the link, and Ruby will still get focus, but get_element_value and execute_script fail without any error.
I cannot reproduce this. (Windows 7, IE10)
wd.rb
<span class="syntaxdefault"></span><span class="syntaxcomment"># load 'c;/wd.rb'<br /># Example.test_void<br /></span><span class="syntaxdefault">module Example<br /> def self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">test_void<br /> path </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">File</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dirname</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">__FILE__</span><span class="syntaxkeyword">)<br /> @</span><span class="syntaxdefault">dialog </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">UI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">WebDialog</span><span class="syntaxkeyword">.new()<br /> @</span><span class="syntaxdefault">dialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">set_file</span><span class="syntaxkeyword">( </span><span class="syntaxdefault">File</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">join</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">path</span><span class="syntaxkeyword">, </span><span class="syntaxstring">'sample.html'</span><span class="syntaxkeyword">) )<br /> @</span><span class="syntaxdefault">dialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">show </span><span class="syntaxkeyword">{<br /> @</span><span class="syntaxdefault">dialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_action_callback</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"done"</span><span class="syntaxkeyword">) { |</span><span class="syntaxdefault">wd</span><span class="syntaxkeyword">, </span><span class="syntaxdefault">param</span><span class="syntaxkeyword">| </span><span class="syntaxdefault">p param </span><span class="syntaxkeyword">}<br /> } </span><span class="syntaxcomment"># show<br /> </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">dialog<br /> end<br />end</span>
sample.html
<span class="syntaxdefault"></span><span class="syntaxkeyword"><!</span><span class="syntaxdefault">DOCTYPE html</span><span class="syntaxkeyword">><br /><</span><span class="syntaxdefault">html</span><span class="syntaxkeyword">><br /><</span><span class="syntaxdefault">body</span><span class="syntaxkeyword">><br /><br /><</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /> <</span><span class="syntaxdefault">a href</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"javascript;void(0)" </span><span class="syntaxdefault">onclick</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"window.location='skp;done@HelloWorld'"</span><span class="syntaxkeyword">></span><span class="syntaxdefault">Click Me</span><span class="syntaxkeyword">!</</span><span class="syntaxdefault">a</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /><br /><</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /> <</span><span class="syntaxdefault">a href</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"#" </span><span class="syntaxdefault">onclick</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"alert(document.body.innerHTML)"</span><span class="syntaxkeyword">></span><span class="syntaxdefault">innerHtml</span><span class="syntaxkeyword"></</span><span class="syntaxdefault">a</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /><br /></</span><span class="syntaxdefault">body</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">html</span><span class="syntaxkeyword">> </span><span class="syntaxdefault"></span>
-
oh... wait... I didn't try
get_element_value
andexecute_script
. -
Have you considered setting and using an enduring
@@dialog
rather than the instance variable@dialog
?
Untested, just a thought... -
Ah. Now I can reproduce it.
Very strange indeed.
However, I've never seen anyone using
javascript:void(0)
instead of preventing the event from bubbling. First time I heard of this issue.If you don't use a framwork like jQuery you have to account for old IE's weirdness:
http://www.quirksmode.org/js/events_order.html#link9 -
Actually, you just need to
return false
from theonclick
event.<span class="syntaxdefault"></span><span class="syntaxkeyword"><!</span><span class="syntaxdefault">DOCTYPE html</span><span class="syntaxkeyword">><br /><</span><span class="syntaxdefault">html</span><span class="syntaxkeyword">><br /><</span><span class="syntaxdefault">body</span><span class="syntaxkeyword">><br /><br /><</span><span class="syntaxdefault">input type</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"text"</span><span class="syntaxdefault"> id</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"cheese"</span><span class="syntaxdefault"> value</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"Foo Bar"</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">><br /><br /><</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /></span><span class="syntaxdefault"> </span><span class="syntaxkeyword"><</span><span class="syntaxdefault">a<br /> href</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"javascript;void(0)"<br /></span><span class="syntaxdefault"> onclick</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"window.location='skp;done@HelloWorld'; return false;"</span><span class="syntaxkeyword">><br /></span><span class="syntaxdefault"> Click Me</span><span class="syntaxkeyword">!<br /></span><span class="syntaxdefault"> </span><span class="syntaxkeyword"></</span><span class="syntaxdefault">a</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /><br /><</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /></span><span class="syntaxdefault"> </span><span class="syntaxkeyword"><</span><span class="syntaxdefault">a href</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"#"</span><span class="syntaxdefault"> onclick</span><span class="syntaxkeyword">=</span><span class="syntaxstring">"alert(document.body.innerHTML)"</span><span class="syntaxkeyword">></span><span class="syntaxdefault">innerHtml</span><span class="syntaxkeyword"></</span><span class="syntaxdefault">a</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">p</span><span class="syntaxkeyword">><br /><br /></</span><span class="syntaxdefault">body</span><span class="syntaxkeyword">><br /></</span><span class="syntaxdefault">html</span><span class="syntaxkeyword">></span><span class="syntaxdefault"></span>
-
Back tot the side topic of best practices:
It's generally considered best practice to separate content, layout and behaviour. That means all CSS in a .css file and all JS in a .js file.And I've never heard of
void(0)
as best practice. I find it often in Bad Practices lists:
http://www.quirksmode.org/blog/archives/2005/06/three_javascrip_1.html#link3 -
Both of those links that you sent merely say it is bad form to put javascript into the href, which is true.
The javascript:void(0) is the recommended practice, indicating that the onclick handler is to take precedence.
In fact, the whole point of it is so that it onclick handler doesn't have to return false.
(See here: http://stackoverflow.com/questions/134845/href-attribute-for-javascript-links-or-javascriptvoid0)But good to know that was the issue!
Many thanks for your tireless attention to detail on every conceivable issue.--J
-
@honkinberry said:
Both of those links that you sent merely say it is bad form to put javascript into the href, which is true.
The javascript:void(0) is the recommended practice, indicating that the onclick handler is to take precedence.
In fact, the whole point of it is so that it onclick handler doesn't have to return false.
(See here: http://stackoverflow.com/questions/134845/href-attribute-for-javascript-links-or-javascriptvoid0)But when would you use void(0) in anything other than the HREF?
I still agree with with the this answer:
http://stackoverflow.com/a/134957/486990There's a lot of information floating around which is lingering around from the older days. When going through best practices guides of well known web designers it's always to avoid inline JS. Which then removes void(0) from the equation completely.
@honkinberry said:
But good to know that was the issue!
Many thanks for your tireless attention to detail on every conceivable issue.No worries. I had some spare time while I was rendering.
And the WebDialog has been a source of so much oddity that I felt a strong inclination to check it out myself. I reckon it's still worth reporting, so if you're heading into Boulder then give them a nudge. -
@honkinberry said:
The javascript:void(0) is the recommended practice, indicating that the onclick handler is to take precedence.
I disagreed 3 years ago when we discussed this issue, and still do.
Read my detailed explanation in this old thread: Webdialogs and Javascript void
Any more discussion on this offtopic, can be done in that thread, if you wish.
Advertisement