• Global community
    • Language:
      • Deutsch
      • English
      • EspaƱol
      • FranƧais
      • PortuguĆŖs
  • ę—„ęœ¬čŖžć‚³ćƒŸćƒ„ćƒ‹ćƒ†ć‚£
    Dedicated community for Japanese speakers
  • ķ•œźµ­ ģ»¤ė®¤ė‹ˆķ‹°
    Dedicated community for Korean speakers
Exit
0

Writing to Table Contents was working... and now it's not?

Explorer ,
Jan 24, 2022 Jan 24, 2022

Copy link to clipboard

Copied

Hello all you masters of the InDesign universe...!

I created a fairly extensive script that, in part, writes user-input data into established tables based on the TextFrame label. It was all working completely fine until I moved that "table-writing" component into a Function, and now the script just stops when it gets to this line:

globalFrames[i].contents = jobCustomerText;    

I am using the ".contents" method because I need to read and write with this data.

The jobCustomerText variable is defined outside of the Function after the user inputs that data, and right before the line in question, I can see that the variable does indeed contain the correct data, although the variable type comes in as "undefined."

When I copy this component into its own separate file to run/debug (and forcing the jobCustomerText variable to contain a specific string), it works as expected. 

Previously, I was using this line:

globalFrames[i].contents = jobCustomer.text;  

But I found with moving the component to a Function, I had to store this data differently, so now the variable gets filled as:

jobCustomerText = jobCustomer.text;

I suspect this doesn't given anyone here much to go on, unless there's some overall reason why it might not work (like .contents just doesn't execute properly within a function, or some silliness)... but I'm at a loss, and I'm really hoping to not have to go back to the bare bones of this project!

TOPICS
Scripting

Views

192

Translate

Translate

Report

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 , Jan 26, 2022 Jan 26, 2022

The correct answer of that thread is important. In Indesign, a scriptUI window is modal by default, which means in practice that you can't touch anything else until you've hit the OK button. But this can be difficult to understand due to the way scriptUI dialogs are usually implemented in our code. I recommend setting yourself the puzzle of separating the UI code from the "main engine" code. The test of success in this is if you can call your "main engine" with or without invoking the UI. This i

...

Votes

Translate

Translate
Community Expert ,
Jan 24, 2022 Jan 24, 2022

Copy link to clipboard

Copied

You haven't given us much to go on, as much depends on your wider code. However, I think you problem is that the function you've written no longer has access to the jobCustomer variable (which I suspect is a reference to a ScriptUI edit text box).

 

If you could move the new function definition into the same scope as the jobCustomer object it should work. Does that make sense?

 

Look at this:

// NOT REAL CODE!
// Just a diagram.

function makeUI {
    var w = new Window();
    var jobCustomer = w.add('edittext');

    function updateJobCustomer() {
        var jc = jobCustomer.text; // should work!
    }
}

function updateJobCustomer() {
    var jc = jobCustomer.text; // won't work!
}

 

So the problem may be that the function cannot see the jobCustomer variable. But hard to say without more info.

- Mark

Votes

Translate

Translate

Report

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 ,
Jan 24, 2022 Jan 24, 2022

Copy link to clipboard

Copied

If the data is coming from outside the function, just pass it to the function: 

function updateJobCustomer(jobCustomerText) {
    globalFrame.contents = jobCustomerText; // should work!
}

Votes

Translate

Translate

Report

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
Explorer ,
Jan 25, 2022 Jan 25, 2022

Copy link to clipboard

Copied

Thank you Mark, my script is mostly set up as your "won't work" example, but more like the following code:

// NOT REAL CODE!
// Just a diagram.

var jobCustomerText = "";
var myDocument = app.documents[0];

function mainEngine() {
    alert(jobCustomerText); // works!
    var globalFrames = myDocument.textFrames;

    for (var i=0; i< globalFrames.length ; i++) { 
        globalFrames[i].contents = jobCustomerText; // doesn't work!
    }
}

function makeUI {
    var w = new Window();
    var jobCustomer = w.add('edittext');
    var generateDocument = actionButtonGroup.add('button', undefined, 'Okay', {name:'generateDocument'});
    generateDocument.onClick = function() {  
        jobCustomerText = jobCustomer.text;
        mainEngine();
    }
}

 

When it was working, it was set up more like the following code, which is why I think you're right... I'm just not sure why it wouldn't work after shuffling things around a bit. (I had to incorporate an additional user input step earlier in the script.) I'm quite Java-new and sometimes the underlying logic of objects escapes me.

 

// NOT REAL CODE!
// Just a diagram.

var myDocument = app.documents[0];

var w = new Window();
var jobCustomer = w.add('edittext');
var generateDocument = actionButtonGroup.add('button', undefined, 'Okay', {name:'generateDocument'});
generateDocument.onClick = function() {  
    var globalFrames = myDocument.textFrames;
    for (var i=0; i< globalFrames.length ; i++) { 
       globalFrames[i].contents = jobCustomer.text;
    }
}

 

Votes

Translate

Translate

Report

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
Explorer ,
Jan 26, 2022 Jan 26, 2022

Copy link to clipboard

Copied

For anyone facing the same dilemma, however rare it might be... I realize my folly, though I don't understand it at all!

Initially, I'd been given some good advice from this thread but in all my edits and changes and revisions, I'd removed this good advice from my script. When I reinstated the good advice, everything seems to fall back into place.

I don't understand why .contents won't write to the table without this in place, but I suppose my goal is to create something that works, not understand!

Votes

Translate

Translate

Report

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 ,
Jan 26, 2022 Jan 26, 2022

Copy link to clipboard

Copied

The correct answer of that thread is important. In Indesign, a scriptUI window is modal by default, which means in practice that you can't touch anything else until you've hit the OK button. But this can be difficult to understand due to the way scriptUI dialogs are usually implemented in our code. I recommend setting yourself the puzzle of separating the UI code from the "main engine" code. The test of success in this is if you can call your "main engine" with or without invoking the UI. This is very useful anyway because it means you can re-purpose your script to run in batch mode style, performing many repetitions using parameters that are fed to it via code.

 

Here's one way to structure this:

scriptUI-diagram.png

Edit: see actual example of this structure on my answer here.

If you're like me, you'll need to experiment with it before you really understand. And I've got *a lot* still to understand.

- Mark

Votes

Translate

Translate

Report

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 ,
Jan 26, 2022 Jan 26, 2022

Copy link to clipboard

Copied

Hi @mrlagace, when I read both your code examples above, I would think that they'd *both* work. The first has access to the global var jobCustomerText and the second has access to the non-global(!) var globalFrames via the global var myDocument. Also in the second example the onClick function has access to the var JobCustomer because it is defined in the same scope (it would anyway in this case because jobCustomer in this example is a global var).

 

As an aside, just for your learning, I'd like to offer some advice about variable naming. My strong preference is to be a bit more precise about what the variable actually holds. So in your example, jobCustomer would be called jobCustomerEditText because it holds a reference to a ScriptUI Edit text object. Your naming of jobCustomerText is perfect already because it holds a text string. I might call globalFrames -> allDocumentTextFrames, or just allTextFrames. The variable generateDocument I would call generateDocumentButton.

 

- Mark

Votes

Translate

Translate

Report

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
Explorer ,
Jan 27, 2022 Jan 27, 2022

Copy link to clipboard

Copied

LATEST

Thank you Mark!

Good advice on variable naming, I'll keep that in mind.

Appreciate the explanation of structure as well; I'll start wrapping my head around it!

Thanks again.

Michael

Votes

Translate

Translate

Report

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