Skip to main content
Participating Frequently
January 13, 2024
Answered

Automatic "Save" and "Close" when using "afterOpen" eventListener?

  • January 13, 2024
  • 3 replies
  • 427 views

Hi,

Anyone so kind as to help me out with this problem, please?

I wish to launch Indesign and open a specific file externally. 

I have a startup script :

#targetengine "onAfterOpen"
main();
function main(){
var myListener=app.eventListeners.add("afterOpen", myfunc);
}
function myfunc(myEvent){
var doc=myEvent.parent;
if (doc.name=="theProject.indd"){
myEvent.target.windows.add();
var myFile = new File('C:/script_to_run.jsx');
app.doScript(myFile);

doc.save(); //does not work

doc.close(); //does not work
}
}

After the file is open the startup script triggers another script to run and after that I would like to "Save" and "Close" the file automatically but I get a warning message saying: "Cannot save/close document because there are open transactions in process on the database."

Any help would be appreciated

Correct answer rob day

You should be able to do a save via an idle task that waits for the document to be open and ready to save.

 

This example adds a rectangle to page 1, and saves after the idle task’s 100ms sleep time.

 

app.eventListeners.add("afterOpen", documentOpen);
var it;

/**
* after open handler
* @ param e the afterOpen event
* 
*/
function documentOpen(e){
    if (e.parent.constructor.name == "Document" && e.parent.name == "theProject.indd"){
        //make a new idle task with a sleep time of 100ms
        it = makeIdleTask("ReadyToSave", 100)
        it.addEventListener(IdleEvent.ON_IDLE, saveDoc);

        //do something to the document e.g., add a rectangle to page 1...
        //replace with your doScript command
        e.parent.pages.item(0).rectangles.add();
    }
}


/**
* idle event handler 
* @ param e the idletask event
* 
*/
function saveDoc(e){
    var doc = app.activeDocument;
    doc.save();
    doc.close();
    it.remove();
}


/**
* Makes a new named idleTask 
* @ param the task name 
* @ param the sleep time 
* @ return the named idleTask
*/
function makeIdleTask(n, s){
    if (app.idleTasks.itemByName(n).isValid) {
        return app.idleTasks.itemByName(n);
    } else {
        return app.idleTasks.add({name:n, sleep:s});
    }
}

3 replies

rob day
Community Expert
rob dayCommunity ExpertCorrect answer
Community Expert
January 14, 2024

You should be able to do a save via an idle task that waits for the document to be open and ready to save.

 

This example adds a rectangle to page 1, and saves after the idle task’s 100ms sleep time.

 

app.eventListeners.add("afterOpen", documentOpen);
var it;

/**
* after open handler
* @ param e the afterOpen event
* 
*/
function documentOpen(e){
    if (e.parent.constructor.name == "Document" && e.parent.name == "theProject.indd"){
        //make a new idle task with a sleep time of 100ms
        it = makeIdleTask("ReadyToSave", 100)
        it.addEventListener(IdleEvent.ON_IDLE, saveDoc);

        //do something to the document e.g., add a rectangle to page 1...
        //replace with your doScript command
        e.parent.pages.item(0).rectangles.add();
    }
}


/**
* idle event handler 
* @ param e the idletask event
* 
*/
function saveDoc(e){
    var doc = app.activeDocument;
    doc.save();
    doc.close();
    it.remove();
}


/**
* Makes a new named idleTask 
* @ param the task name 
* @ param the sleep time 
* @ return the named idleTask
*/
function makeIdleTask(n, s){
    if (app.idleTasks.itemByName(n).isValid) {
        return app.idleTasks.itemByName(n);
    } else {
        return app.idleTasks.add({name:n, sleep:s});
    }
}
no.9366Author
Participating Frequently
January 15, 2024

yep! that's the way to go!

thank you so much, @rob day!

rob day
Community Expert
Community Expert
January 14, 2024

Hi @no.9366 , I had a chance to test the #include version, and it still doesn’t work—the error is happening because the document’s layout window is not open yet when you do the save.

no.9366Author
Participating Frequently
January 15, 2024

hi rob day,

it could have been an elegant solution but it does not work for me either for the reason you mentioned.

but thanks anyway!

rob day
Community Expert
Community Expert
January 14, 2024

Hi @no.9366 , I think you will need to use a preprocessor directive at the top of your script rather than the doScript() function. This might help:

 

https://extendscript.docsforadobe.dev/extendscript-tools-features/preprocessor-directives.html

 

Here’s an example where the script to include is in the same directory as the running script (the convention is .jsxinc, but .jsx should also work):

 

 

 

 

 

#include "HelloWorld.jsxinc";

alert("Message from HelloWorld.jsinc:\r" + getWorldString("Hi There!") + "\rThe magic number is: "+ MAGIC_NUMBER)

 

 

 

 

 

The HelloWorld.jsxinc code:

 

 

 

 

 

/**
* External function example saved with .jsxinc in the same directory as script 
* @ param s string
* @ return new string 
*/

function getWorldString(s){
  return "From Hello World: " + s
}

/**
* A read only constant
*/
const MAGIC_NUMBER = 1.045;


/**
* A read write variable
*/
var vNum = 5

 

 

 

 

The result: