Search code examples
optimizationcheckboxstateadobe-indesignextendscript

Extendscript Optimization/State Toggle


I am working on an InDesign plugin using ExtendScript that uses dialog checkboxes to generate variables based on user inputs. These variables are intended to store user-selected option data to be referenced later in the script when assembling a larger document. (Option A brings in pages 5-10 of a document to a new master, Option B brings in pages 11-14, etc.) Currently, I have two main issues:

  1. When selecting an option, the readonly textbox populates with the selected option's name as intended, however ticking a checkbox off removes all of the text instead of just the option name. I realize the subtraction operator is likely at fault here. Is there a better recommendation for removing text from a string? Here is a visualization for TL;DR: 1 2 3 4 5
  2. I cannot seem to properly optimize the dynamic code. I can grab all of the checkboxes and their values and plug them into arrays after the window.show() function, however the only way I am able to dynamically change the text within the readonly text window is by initializing a function to run for each option as shown here, and doing so before window.show():
//Variable Declaration for context
var AOpt = w.tabs[0].add('edittext', [0, 0, 350, 70], 'No Options Selected', {readonly: true});
var A1 = AOps.add ('checkbox {text: "Option 1"}'); //AOps is the panel which the checkboxes populate
const origResp = 'No Options Selected'; //Original Response in textbox

//How might I optimize this for each option?
A1.onClick = function() {
 if(AOpt.text !==origResp) {        
        if (A1.value == true) {           
                    AOpt.text = AOpt.text + A1.text;                
        } else if (A1.value == false) {
                    AOpt.text = AOpt.text - A1.text;
                                      }
        }else{
                    AOpt.text = A1.text;    
             }
}

A1 is a single unit in a series of 10 options (A1-A10) for Model A, and there are at least 6 models. Incorporating functions for each option in the full project would add close to 600 lines of code alone. This snippet will not run, but I've included a codepen with the full, functional code for this section of the script.

var aArray = [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10]; grabs the checkboxes, and I can check their value if I add this code after window.show(), however I can't get the text to dynamically populate after the window is shown:

for (i=0; i<aArray.length; i++){
        alert(aArray[i].value);}

Are there better management options for state control and optimization with Extendscript?


Solution

  • As a quick dirty solution you can try to change:

    AOpt.text = AOpt.text - A1.text;
    

    with:

    AOpt.text = AOpt.text.replace(A1.text, '').replace('  ', ' ');
    

    Technically it should work. But I'm not sure if it's the best solution.

    It would be cleaner to rebuilt the string AOpt.text anew from some array every time user clicks on the checkboxes. The replace method is not exactly elegant.

    Here is the scheme how you can rebuilt the text based on checkboxes:

    // checkboxes
    var A1 = {value: false, text: 'Option 1'};
    var A2 = {value: false, text: 'Option 2'};
    var A3 = {value: false, text: 'Option 3'};
    
    // ------------------------------------------------------------------
    function update_text() {
        var boxes = [A1,A2,A3];
        var text = [];
        for (let i=0; i<boxes.length; i++)
            if (boxes[i].value) text.push(boxes[i].text);
        return text.join(', ') || 'No options selected';
    }
    
    // text area
    var AOpt = {text: update_text()};
    
    // tests ------------------------------------------------------------
    
    A1.value = true;              // set checkbox
    A3.value = true;              // set checkbox
    AOpt.text = update_text()     // update the text
    console.log(AOpt.text);       // output ---> 'Option 1, Option 3'
    
    A1.value = false;             // set checkbox
    AOpt.text = update_text();    // update the text
    console.log(AOpt.text);       // output ---> 'Option 3'
    
    A3.value = false;             // set checkbox
    AOpt.text = update_text();    // update the text
    console.log(AOpt.text);       // output ---> 'No options Selected'
    
    A2.value = true;              // set checkbox
    AOpt.text = update_text();    // update the text
    console.log(AOpt.text);       // output ---> 'Option 2'

    The final implementation for you code is here:

    // ...
    
    // Our listbox to tell us which segments will be populated into the master document
    w.tabs[0].add('statictext', undefined, 'Included options:');
    var AOpt = w.tabs[0].add('edittext', [0, 0, 350, 70], '', { readonly: true });
    
    function updateText() {
        var boxes = [A1, A2, A3, A4, A5, A6];
        var text = [];
        for (var i = 0; i < boxes.length; i++)
            if (boxes[i].value) text.push(boxes[i].text);
        AOpt.text = text.join(', ') || 'No options selected';
    }
    updateText();
    
    A1.onClick = function () { updateText() }
    A2.onClick = function () { updateText() }
    A3.onClick = function () { updateText() }
    A4.onClick = function () { updateText() }
    A5.onClick = function () { updateText() }
    A6.onClick = function () { updateText() }
    
    // User input buttons, currently non-functioning
    // the rest of your code...