Skip to main content
Known Participant
January 27, 2022
Question

Dynamic Variable Naming

  • January 27, 2022
  • 5 replies
  • 1537 views

Hey everyone,

 

I'm trying to get confirmation on whether ExtendScript supports dynamic variable naming. Everything I've read up to this point suggests that it doesn't. Sad face.

 

Basically, my goal is to create a dialog window that has a list of items (page numbers), and the total number of items will vary depending on earlier user input. Probably using radio buttons, I am hoping that users can see each item and select for it either Option A or Option B (and not both).

 

If dynamic variable naming is a possiblity, I'm hoping to be able to use variables like optionAPage1 and optionBPage1 with true/false values, wherein the integer changes based on the item/page number. (Or maybe optionsPage1 with values like A/B.)

 

If dynamic variable naming isn't supported, I'm all ears on an alternative solution! Better this than having hundreds of lines of code!

 

Thanks everyone,

 

Michael

This topic has been closed for replies.

5 replies

rob day
Community Expert
February 3, 2022

Hi @mrlagace , not sure if this helps, but could you do it with dropdowns? this uses the built in InDesign dialog class to build a dropdown from your object:

 


var signatures = [
    {
        number: 1,
        sections: [
            {
                name: 'A',
                //needs to be a string list
                pages: [ '1', '2', '3', '4', '5', '6', '7', '8' ]
            }
        ]
    }
]


makeDialog();

var sigDropdown;
var sigList;

function makeDialog(){
    var theDialog = app.dialogs.add({name:"Signatures", canCancel:true});
    with(theDialog){
        with(dialogColumns.add()){
            with(borderPanels.add()){
                with(dialogColumns.add()){
                    staticTexts.add({staticLabel:"Signature " + signatures[0].number + " Pages"});
                }
                with(dialogColumns.add()){
                    sigList =  signatures[0].sections[0].pages
                    sigDropdown = dropdowns.add({stringList:sigList, selectedIndex:0, minWidth:80});
                }
            }
        }
    }

    //the dialog results
    var res = theDialog.show();
    if(res == true){
        sigDropdown = sigList[sigDropdown.selectedIndex];
        main()
	}else{
        theDialog.destroy();
    }
}


function main(){
    alert("Chosen Page: " + sigDropdown);
    return 
}

 

Community Expert
February 3, 2022

"… but how do I drill that down to get the value for the respective Page?"

 

Hi Michael,

I'm not sure what you are asking here, but if you want to address a page where you start out with a number only, you could work like this, if the number denotes the position of the document page in the document:

var myPageNumber = 1;
var pageToAddress = app.documents[0].pages[ myPageNumber-1 ];

The numbering of the index of a page starts with 0 .

 

Now that you have the page stored in variable pageToAddress you always have access to that page even if you move it around in the document:

pageToAddress.move( LocationOptions.AT_END );
pageToAddress.rectangles.add({ geometricBounds : [0,0,"100mm","100mm"]});

 

Regards,
Uwe Laubender

( ACP )

Community Expert
January 28, 2022

Hi Michael,

dynamic variable naming?

 

Hm. Some thoughts:

One could write a script in ExtendScript that could rewrite itself because you have access to the file class.

But to what purpose? If a user should interact with a script this is not necessary at all, I think. But I can be wrong, because I do not understand your use case.

 

If no user interaction should take place one could write a startup script with some event handlers that could react to things that happen with a document. You see, I am just poking around…

 

Also note, that you can use method insertLabel() and extractLabel() to store and retrieve data or even code with page items, documents or even the application.

 

Regards,
Uwe Laubender

( ACP )

mrlagaceAuthor
Known Participant
February 2, 2022

Thanks Uwe! 

I added some more details regarding my case use in a response above. Hopefully my dilemma is clearer now.

On a related note, your assistance in other threads has been invaluable to get me to this point! I appreciate it!

m1b
Community Expert
January 28, 2022

Here's a article on dynamic variable names in javascript. At a quick glance it isn't clear to me that your use case needs any of that though.

 

Where and when does the user choose Option A or B? I'm picturing a dialog asking which option, then, after choosing that, changing to show a UI just for that chosen option. This can be done with normal variables naming.

 

You can make an object with *keys* named "optionA" and "optionB" that could be referenced dynamically.

var options = {
    A: {
        pages: [
            {
                // page 1
                something: ...
            },
            {
                // page 2
                something: ...
            }
        ]
    },
    B:         pages: [
            {
                // page 1
                something: ...
            },
            {
                // page 2
                something: ...
            }
        ]
    }
}

Then access it like this:

var currentOption = "B";
var currentPages = options[currentOption].pages;

But then again, it would be more normal to have an Array of options, each which had a "name" or "label" of "A", "B" etc. I'd have a look at the data structures you are using and see if there's a better way.

 

Or, if I'm missing your point entirely, please ignore. 🙂

- Mark

mrlagaceAuthor
Known Participant
February 2, 2022

Thanks for your time thinking this over, Mark!

I've started looking into keys as a solution, but I'm not totally sure it's going to work. I realize part of the problem is that I've been so vague, so I hope to correct that here!

Early in my script, the user will select a CSV file that contains imposition data; it contains the list of Signatures with the Pages that are contained on each Signature. The problem I'm facing is that some Signatures contain multiple Sections, and without another option at my disposal, I'm trying to have the script open a dialog window that lets the user manually select if, for example, Page 43 should be in Section A or Section B (or in some cases, there might be Section C or even D). Depending on the imposition, any given Signature could have between 2 and 64 pages.

Presently, I think my bottleneck is with the radio buttons. If I'm not mistaken, my dialog code will look something like:

var group2 = BlahBlahBlah.add("group", undefined, {name: "group2"}); 
    group2.orientation = "row"; 
var statictext2 = group2.add("statictext", undefined, undefined, {name: "statictext2"}); 
    statictext2.text = "Page 1"; 
var radiobutton1 = group2.add("radiobutton", undefined, undefined, {name: "radiobutton1"}); 
    radiobutton1.text = "Section A"; 
var radiobutton2 = group2.add("radiobutton", undefined, undefined, {name: "radiobutton2"}); 
    radiobutton2.text = "Section B"; 


var group3 = BlahBlahBlah.add("group", undefined, {name: "group3"}); 
    group3.orientation = "row"; 
var statictext3 = group3.add("statictext", undefined, undefined, {name: "statictext3"}); 
    statictext3.text = "Page 2"; 
var radiobutton3 = group3.add("radiobutton", undefined, undefined, {name: "radiobutton3"}); 
    radiobutton3.text = "Section A"; 
var radiobutton4 = group3.add("radiobutton", undefined, undefined, {name: "radiobutton4"}); 
    radiobutton4.text = "Section B"; 

My initial thought process (coming from a PHP knowledge base) was to have those radio button variables set up as...

radiobutton<page number> and containing the value of either A or B or C, etc. Something like that I know I can easily build in a loop, but in ExtendScript I'm totally unsure.

I'd love to be able to just use an Array (ie, named SectionA, containing Pages like 42, 43, 44, etc). If I had an Array like that, I don't know how to name those radio button variables so I can get the correct data from them later. Sigh.

And unless I don't understand you correctly (read: very likely!), I don't know if objects/keys will eliminate this dumbness I'm experiencing! 

m1b
Community Expert
February 2, 2022

In your code above you store the radio buttons as local variables, possibly in a "make UI" type function. If you want a handy way to link those radio buttons to some other data, just store the radio button *with* that other data in an object.

For example:

// first you I think you want to parse your csv data
// into an array of signatures something like this:

// (this is a global var so can be accessed later from makeUI function)
var signatures = [

    {
        jobName: 'my test job 1',
        sections: [
            {
                name: 'A',
                pages: [1, 2, 3, 4]
            },
            {
                name: 'B',
                pages: [5, 6, 7, 8]
            },
            {
                name: 'C',
                pages: [9, 10, 11, 12]
            }
        ]
    },
    {
        jobName: 'my test job 2',
        sections: [
            {
                name: 'Front',
                pages: [1, 2, 3, 4, 5, 6, 7, 8]
            },
            {
                name: 'Back',
                pages: [9, 10, 11, 12, 13, 14, 15, 16]
            },
        ]
    },

]

// so signatures is an array of objects
// each 'signature' object has a jobName string and sections array
// each signature's sections array contains 'section' objects
// which each have a name and a pages array


// ... later during makeUI code not in same variable scope

// this line is just to simulate an earlier choice by user to select the 2nd signature
var currentSignature = signatures[1];

// make a radio button for each section in current signature
for (var i = 0; i < currentSignature.sections.length; i++) {
    var section = currentSignature.sections[i];
    section.radioButton = myRadioButtonGroup.add("radiobutton", undefined, undefined);
    section.radioButton.text = "Section " + section.name;
}

// so, if you know what signature you're working on (currentSignature)
// and the current section you're working on (currentSection)
// you can refer to its radio buttons like this:
currentSignature.sections[currentSection].radioButton;

// or
signatures[1].sections[0].radioButton.value;

// and because it is stored in the global signatures variable
// you'll always have access to it

Of course this is all just examples and won't all match your specific needs, but I hope it might give you something to ponder.

- Mark

brian_p_dts
Community Expert
January 27, 2022

Unclear what the use case is. Have you looked into text variables to see if they can accomplish your task?  

 

https://helpx.adobe.com/indesign/using/text-variables.html