Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

ScriptUI Checkbox onClick fires differently in CS5 vs CS3?

Contributor ,
Mar 24, 2011 Mar 24, 2011

I'm developing an application consisting of a ScriptUI interface and a custom InDesign template. The ScriptUI interface contains a few checkboxes, with onClick event handlers assigned to read their value and store them to a preferences variable whenever they change. This all works perfectly in InDesign CS3 which was my primary development environment.

Now I need to get this application compatible with InDesign CS5, but the checkboxes seem to consistently be returning the wrong value. No matter whether my event handler reads this.value, event.target.value or a direct reference to the checkbox, the returned value is the opposite of the expected. If I use the direct reference to read the value from elsewhere though, the returned value is correct! It almost seems like in CS5 the onClick event handler is fired before the value is changed, while in CS3 it is fired after the value is changed. Just tried CS4 and it seems to behave the same way as CS5.

Did they actually change the checkboxes to behave this way (which makes no sense to me) or am I doing something wrong? Is there any way to get the old behavior back, or is the only solution to manually invert the value if the script detects CS4 or later as the runtime?

TOPICS
Scripting
3.9K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Guide , Mar 24, 2011 Mar 24, 2011

Mayhem SWE wrote:

I wonder how the execution order is in a web browser. The only valid reason I can come up with to justify the CS4/5 change would be if this is how a web browser would behave (perhaps in order to give you an opportunity to cancel the event before the value is changed?), but it is still quite confusing and illogical IMHO...

I totally agree with you. The reason behind this —I think— is that the ScriptUI event model has been modified in CS4 in order to enhance the compliance with the

...
Translate
Guide ,
Mar 24, 2011 Mar 24, 2011

Yep! I experienced the same —puzzling and undocumented— facts when I was designing my ScriptUI wrapper.

Here is what I noticed about chekbox events:

Order:

1) mousedown event listener
2) mouseup event listener
3) click event listener
4) onClick handler

• In CS4/CS5, the checkbox value is updated at onClick, not before

• In CS3:

— mousedown and mouseup are not supported

— the onClick handler seems equivalent to the click event listener, but the chekbox value has already changed when one handles that event.

@+

Marc

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 24, 2011 Mar 24, 2011

Aha -- so it's not the checkbox's onClick handler, it's the way different event handlers interact. Never realised that. What a mess.

Peter

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011

Huh? I'm still not following...

Peter's script works perfectly for me. What's the problem?

Harbs

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 24, 2011 Mar 24, 2011

Harbs. wrote:

Huh? I'm still not following...

Peter's script works perfectly for me. What's the problem?

I may have used the wrong terminology (apparently I do not use an event handler but an event listener) in my initial post, but Marc's reply just below sums up the situation nicely. The issue is that in CS3 listener and handler are both fired after the value is updated (as expected), but in CS4/5 any <Checkbox>.addEventListener("click", <function>) listener is actually fired before the value is updated while the <Checkbox>.onClick = <function> handler is still fired after.

I wonder how the execution order is in a web browser. The only valid reason I can come up with to justify the CS4/5 change would be if this is how a web browser would behave (perhaps in order to give you an opportunity to cancel the event before the value is changed?), but it is still quite confusing and illogical IMHO...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011

Ah. I missed that your were using addEventListener...

I agree. Bad behavior, and probably a bug.

An ugly workaround would be:

cb.function1 = function(){

     // do something

}

cb.function2 = function(){

     // do something else

}

cb.onClick = function(){

     cb.function1();

     cb.function2();

}

Did anyone file this as a bug yet?

Harbs

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 24, 2011 Mar 24, 2011

Mayhem SWE wrote:

I wonder how the execution order is in a web browser. The only valid reason I can come up with to justify the CS4/5 change would be if this is how a web browser would behave (perhaps in order to give you an opportunity to cancel the event before the value is changed?), but it is still quite confusing and illogical IMHO...

I totally agree with you. The reason behind this —I think— is that the ScriptUI event model has been modified in CS4 in order to enhance the compliance with the DOM Level 3 Events Specification — http://www.w3.org/TR/DOM-Level-3-Events — which states that the click event must be cancelable. Thus you probably can use myClickEvent.preventDefault() in CS4/CS5 while this probably has no effect in CS3 (not tested). I suppose that the checkbox value should be actually changed if and only if the event is completed and not canceled. That makes sense, but the counterpart is that there is no more equivalence between using the onClick handler and a 'pure' click event listener: myWidget.addEventListener(...)

On this subject, the specification says that using the shortcut myWidget.onEvent = myFunction to register an 'event listener' depends on the host language: "Because the details of this are often language-specific, this type of event listener registration is not defined in this specification, but in general, any event type may be used as an attribute in this way by adding the prefix on- to the event type name, and events so dispatched should behave consistently with the event registration and propagation defined in this specification, with the same interfaces, properties, and methods." —DOM Level3 Events Specification, 4.3 "Interface EventTarget", note 2.

Of course, the easiest approach is to use myCheckbox.onClick = ... since the handler is called once the value has been updated, whatever the version of ScriptUI. But I don't believe it's a good practice if you're working on a complex project —especially a library!— because the onClick handler can be easily rewritten by the client code, and because you may need to deal with event propagation/cancellation at a deeper level. For my part I always use addEventListener(...) and removeEventListener(...) in my library code, although it implies that I fit my implementation to the ScriptUI version. (In CS3, reversing the checkbox value, etc.) That way the client code cannot pollute the basic behavior of my widgets.

Hope that helps,

@+

Marc

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011

Marc Autret wrote:


...Thus you probably can use myClickEvent.preventDefault() in CS4/CS5 while this probably has no effect in CS3 (not tested)...

This looks half right, but it doesn't appear to work.

I just tried this, and the results are very odd...

w = new Window ("dialog");
   cb = w.add ("checkbox", undefined, "Not checked");
     var prevent = function (e){
       e.preventDefault();
       }
cb.addEventListener("click",prevent);
   cb.onClick = function(event){
      cb.value ? cb.text="Checked" : cb.text="Not checked";
   }
w.show();

Harbs

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011
LATEST

Yes. preventDefault() is definitely broken...

w = new Window ("dialog");
   cb = w.add ("checkbox", undefined, "Not checked");
   promptButton = w.add ("button", undefined, "Checked?");
   var status = w.add ("statictext", undefined, "Is it Checked?");
     var prevent = function (e){
       e.preventDefault();
       }
   cb.addEventListener("click",prevent);
   cb.onClick = function(event){
      cb.value ? cb.text="Checked" : cb.text="Not checked";
  }
  promptButton.onClick = function(){
    cb.value ? status.text="Checked" : status.text="Not checked";
  }
w.show();

Harbs

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 24, 2011 Mar 24, 2011

Thanks for clarifying this whole mess. I guess the conclusion for this thread is that event model behavior for checkboxes is stupid, but intended. At least I now know this is not occurring due to any fault of mine. (Changing app.scriptPreferences.version makes no difference by the way.)

The best solution IMHO would've been to have "click" listeners fire before the value is updated (to comply with W3C specifications) and "change" listeners (which does not exist for checkboxes) fire afterward. In my case I am not really interested in the click itself, only the fact that a change was made!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011

Mayhem SWE wrote:


(Changing app.scriptPreferences.version makes no difference by the way.)

Yes. That makes sense. The Script UI engine is not related to the InDesign DOM.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 24, 2011 Mar 24, 2011

Harbs. wrote:

Mayhem SWE wrote:


(Changing app.scriptPreferences.version makes no difference by the way.)

Yes. That makes sense. The Script UI engine is not related to the InDesign DOM.

Hey, Harbs, thanks for clarifying that point! This means that rather than app.version we have to check ScriptUI.version, or ScriptUI.coreVersion, in any ScriptUI related stuff. I never realized that.

@+

Marc

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 24, 2011 Mar 24, 2011

Well, if you are limiting yourself to InDesign, it probably doesn't matter which you check. On the other hand that'll make it compatible with Photoshop and Illustrator...

Harbs

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 24, 2011 Mar 24, 2011

Can you show us an example? This script:

w = new Window ("dialog");
   cb = w.add ("checkbox", undefined, "Not checked");
   cb.onClick = function(){
      cb.value ? cb.text="Checked" : cb.text="Not checked";
   }
w.show();

shows the same behaviour in CS3 and CS5, so maybe I don't understand what you're trying to do.

Peter

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines