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

Script Up - Close other palettes before opening new palette

Engaged ,
May 15, 2025 May 15, 2025

This is for FrameMaker, not InDesign, but it's basically a ScriptUI question.

 

It's also somewhat related to: https://community.adobe.com/t5/indesign-discussions/can-i-pass-arguments-to-include-script/td-p/1528...

 

Consider this simple code:

ShowWindow1();
ShowWindow2();


function ShowWindow1(){
    var w = new Window ("palette", "Window 1");
    btn1 = w.add ("button", undefined, "OK");
    ckbx1 = w.add("checkbox", undefined,"Check Box");
    w.add ("button", undefined, "Cancel");
    btn1.onClick=function(){
        alert("You clicked OK on Window 1");
    }
    w.show ();
}

function ShowWindow2(){
    //w.close;    
    var w = new Window ("palette", "Window 2");
    btn1 = w.add ("button", undefined, "OK");
    w.add ("button", undefined, "Cancel");
    btn1.onClick=function(){
        alert("You clicked OK on Window 2");
        alert(ckbx1.value);
    }
    w.show ();
}

I'm having a hard time understanding the following issues:

  • ckbx1 seems to be "global" - i.e. I don't have to pass it as an argument to ShowWindow2.
  • w and btn1 do not appear to be global - the script interprets them correctly, even though they have identical names?
  • w.close gives me an error, even though w should already be defined as window 1.

 

I actually have several scripts all using "win" as the name of the window and I want the scripts to close any open windows before opening the new one called out in the current script. I thought I would have an issue if the window had been closed previously, but it looks like I have an issue even closing the window if it is still open.

TOPICS
Scripting
626
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

Community Expert , May 16, 2025 May 16, 2025

I also want to avoid launching two identical windows if the script were run twice.

 

Check whether the window exists. If it doesn't, create it:

var w = Window.find ('palette', "Window 1");
if (!w) {
  w = new Window ("palette", "Window 1");
  ...
  ...
}
w.show();

Similarly, to close an existing window, do this:

var w = Window.find ('palette', "Window 1");
if (w) {
  w.close();
}
Translate
Community Expert ,
May 15, 2025 May 15, 2025

> ckbx1 seems to be "global" - i.e. I don't have to pass it as an argument to ShowWindow2.

 

That's because it's not declared as a variable.


> w and btn1 do not appear to be global - the script interprets them correctly, even though they have identical names?

 

That's because they are declared as variables.

 

> w.close gives me an error, even though w should already be defined as window 1.

 

The two instances of w are local in their functions. That's why w.close() in ShowWindow2 causes an error.

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
Engaged ,
May 15, 2025 May 15, 2025

Okay - if I remove var from in from of w in ShowWindow1, I still get a "w is undefined" on the w.close (probably should be w.close() in ShowWindow2.

 

More to the point: I have Script1.jsx, that opens a palette named "win."  I have Script2.jsx, that also opens a palete named "win" (with different controls).

 

What commands can I add to each script to close any open "win" palettes, but not give an error if the palettes were previously closed. (I also want to avoid launching two identical windows if the script were run twice.)

 

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 ,
May 15, 2025 May 15, 2025

@Marshall_Brooks

 

Workaround - you can add a hidden label to the document or application that will tell you if window is open.

 

And maybe even "a reference" - but I'm not JS guy so just brainstorming. 

 

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 ,
May 16, 2025 May 16, 2025

I also want to avoid launching two identical windows if the script were run twice.

 

Check whether the window exists. If it doesn't, create it:

var w = Window.find ('palette', "Window 1");
if (!w) {
  w = new Window ("palette", "Window 1");
  ...
  ...
}
w.show();

Similarly, to close an existing window, do this:

var w = Window.find ('palette', "Window 1");
if (w) {
  w.close();
}
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 ,
May 15, 2025 May 15, 2025

Scope is a complex topic, but does this pattern help?

(function () {

    // make `settings` a global property so
    // everyone can see it (be careful with naming!)
    $.global.settings = {
        checkBoxValue: undefined,
    };

    ShowWindow1();
    ShowWindow2();

    function ShowWindow1() {

        var w = new Window("dialog", "Window 1"),
            btn1 = w.add("button", undefined, "OK"),
            ckbx1 = w.add("checkbox", undefined, "Check Box"),
            cancelButton = w.add("button", undefined, "Cancel");

        ckbx1.onClick = function () {
            settings.checkBoxValue = this.value;
        };

        btn1.onClick = function () {
            alert("You clicked OK on Window 1");
            w.close(1);
        }

        w.show();

    }

    function ShowWindow2() {

        var w = new Window("dialog", "Window 2"),
            btn1 = w.add("button", undefined, "OK"),
            cancelButton = w.add("button", undefined, "Cancel");

        btn1.onClick = function () {
            alert("You clicked OK on Window 2");
            alert('checkBoxValue = ' + settings.checkBoxValue);
            w.close(1);
        }

        w.show();

    }

})();
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 ,
May 16, 2025 May 16, 2025

[removed]

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 ,
May 16, 2025 May 16, 2025

@Marshall_Brooks -- If you want to address some button or other control in a different window, you shouldn't use global variables. Better to name the control and use X.find() to pick them up. See https://creativepro.com/files/kahrel/indesign/scriptui.html for details.

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
Engaged ,
May 19, 2025 May 19, 2025

@Peter Kahrel -- Is there a way to close all open windows with one script? For example, if there were 20 open windows, your script would require:

var w = Window.find ('palette', "Window 1");
if (w) {
  w.close();
}
w = Window.find ('palette', "Window 2");
if (w) {
  w.close();
}
// ...
w = Window.find ('palette', "Window 20");
if (w) {
  w.close();
}

Is there a way to do:

var w = Window.find ('palette', "*"); // Any title ???
while (w) {
  w.close();
}

I came up with a crude way to do it over the weekend before I read your reply. Each window has a Btn_Close on it which should be visible to any script, so if I named all the buttons Btn_Close, I could execute Btn_Close.onClick() and close the window - assuming I could verify Btn_Close was valid and I named all the buttons identically.

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 ,
May 19, 2025 May 19, 2025

@Marshall_Brooks

 

I'm not JS guy - but according to this: 

 

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#WindowSUI.html#d1e10891 

 

Title can be an empty string - so maybe it will return list / array / collection / whatever of ALL user created Windows? 

 

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
Engaged ,
May 19, 2025 May 19, 2025

I think that would only close windows with no defined title and leave other windows open, but I didn't test.

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 ,
May 19, 2025 May 19, 2025

Window.find (''); finds any window, but closing a window doesn't destroy it, so Window.find('') always finds the same window. There is no way to collect all windows and close them.

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
Engaged ,
May 19, 2025 May 19, 2025

Just thinking out loud, but what about:

var w = Window.find ('palette', "");
while (w) {
  w.close();
  w=null;
}

 Also - if I keep closing the any of the windows and opening the same ones, I guess I'd eventually have 20-30 windows in memory, but 28 of them closed, correct?

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 ,
May 19, 2025 May 19, 2025

That code won't work, try it.

 

>if I keep closing the any of the windows and opening the same ones, I guess I'd eventually have 20-30 windows in memory, but 28 of them closed, correct?

 

I think so, yes.

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
Engaged ,
May 20, 2025 May 20, 2025

It took me a while to get my head around this, but I figured it out now:

  • From @Peter Kahrel guide (Page 77), there is not way to get rid of a palette window, once opened, other than closing the target engine (FrameMaker, in my case).
  • If you have more than one window with the same name open, you won't be able to close the active window. Window.find will find one of the closed ones and close it again, so the open one will never be affected.
  • I had to re-write my code to only open one window (again - Page 77 of the guide). Some tips for this:
    • Originally (probably per the Adobe Javascript Tool Guide CS6.pdf file), I was setting up the window, initializing the buttons, and then showing the window. I found it easier to keep track of if I moved the win.show() command immediately after the last control is added to the window, and moving the button initialization steps after the win.show() command.
    • I found I had to account for both conditions when I did this. For example, let's say I have a checkbox to turn on or off automatic change bars and show the current state. With the original method, I only had to change the checkbox to "true" if they were enabled - the checkbox is "false" by default. WIth the new method, I had to set the checkbox to "true" if enabled or "false" if disabled. (The checkbox could have been in either state when the pallette was last closed.)

Thank you so much for your patience and guidance!

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
Engaged ,
Jun 11, 2025 Jun 11, 2025
LATEST

I'm having two new issues and hope you can help me with them:

***

Background:

  • I am using this with FrameMaker, but it is esssentially a ScriptUI question.
  • As I now understand it, palette windows remain open until I exit FrameMaker, they can be hidden, but they still exist in memory.
  • Many of my windows use the same names for buttons/controls, which doesn't seem (read on) to cause any issues.
  • We have about 10 document templates.
  • I created essentially two palette dialogs for each template. One turns on and off conditional text (among other features) and one updates variables. The scripts are revised as above to only create one window - if it doesn't exist, it creates it. If it does exist, it re-opens it.
  • I have a separate script that checks for any of the windows and closes the window if it is open, then reads a variable in the document and opens the correct conditional text palette.
  • Each conditional text palette has a panel with checkboxes. These panels have a button labelled "Select All" and "Single Select." Neither of these are radio buttons, but they act like it - i.e. if I click "Select All", it deselects "Single Select" and either selects or deselects all the other buttons in the panel. If I click SingleSelect, it deselects SelectAll and each button acts like a radio button.

***
Issues:

  • I open DocA and the ShowConditonal text window works fine and the Select All and Single Select buttons work fine. I open DocB and the ShowCondiitional Text Window for DocB works fine and the Select All and Single Select buttons work fine. I switch back to DocA and re-open the ShowConditional Text window and the Select All and Single Select buttons no longer work. I can click Select All and nothing changes, I click Single Select and everything is deselected, but SelectAll remains Selected. Closing and re-opening the pallete doesn't resolve the issue. Essentially it doesn't work again until I close and re-open FrameMaker. DocB still works correctly. (If I swap the order, it swaps, i.e. if I open DocB first and then open DocA, DocB stops working, but DocA still works).
  • Issue2: Less common, but the scripts check the active document - i.e. if I am working on a DocA template document and have the DocB show Conditional text window open, the script should pop-up "The active document is not using the Doc B template" and does not perform the action. Sometimes, I will be working on DocA, have the DocA Show Conditional text window open, and will still get the "Active Document is not using Doc B" message. This seems to only happen when I have opened several different documents in FrameMaker. Again, closing FM and re-opening it seems to be the only way to get things working properly again.

***

UPDATE: I did a test and found that if I change the DocB script and re-name Ckbx_SelectAll as CkBx_SelectAll_DocB througout, (and Ckbx_SingleSelect to Ckbx_SingleSelect_DocB) the issue is resolved (the first issue). So the questions now become:

  • Why was this required for these checkboxes?
  • Ideally, do I need to go through each of the scripts and make sure ALL the butttons and checkboxes use unique names?
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