dynamicadobe-indesignextendscriptadobe-scriptui

Indesign Script UI: Dynamic Add Text Edit Fields before OK-Cancel Buttons


I'm trying to show a script ui window that will add another group of input fields IF the user clicks an Add Another button instead of the OK or Cancel buttons...

I got it to kind of work... ie I can show a simple, two group, ui window (group 1 = 1 text edit field and one dropdown list and the Add Another button group 2 = normal OK-Cancel buttons)

If the user fills in/chooses in the first 2 input fields and then ignores the Add Another button and uses the OK-Cancel buttons the script proceeds fine. BUT if the user clicks the Add Another button, the script utilizes a call-back/event handler function (add_AnotherInputline) to first remove the OK-Cancel button group and then add (through add_inputFields function) another group of the text edit field & dropdown, and then re-adds the OK-Cancel buttons... (I could not figure out another way to get the OK-Cancel buttons to move or always stay at the bottom of the window!) BUT that removing-adding of the OK-Cancel button group is where my problem is surfacing. When I do that, those buttons no longer work after user utilizes the add_AnotherInputLine function... And this is seen in the Data Browser because at this point in the script the cancelElement and defaultElement now equal = Object is invalid

Here is the window/ui code... I hope this is enough. I've left out numerous priors (arrays, variables) used in the following code... if you need them, they're simple arrays with text items or ask and I can provide the variables/arrays containing content.

(And yes, I have the G. Singelmann script and have studied it extensively... I have yet to figure out a solution from it, for my particular need...)

var myCSdialog = new Window("dialog", "Setup Color Coding");
    dialogSetup();
    //begin building dialog box myDialog
    add_inputFields(myCSdialog);
    
    if (myCSdialog.children.length <= 1) {
        normalButtons(myCSdialog);
    };
    
if (myCSdialog.show() == 1) {
        userCancelled = false;

} else {
    exit();
}; 

//function adds criteria input collection fields (text criteria and swatch choice)

function add_inputFields(myCSdialog) {
        var myEnterCriteriaGroup = myCSdialog.add("group");
        //title for first input
        myEnterCriteriaGroup.add("statictext",undefined,"Criteria to Color Code");
        //text entry field to enter criteria term
        var myEnterCriteria = myEnterCriteriaGroup.add("edittext",undefined,"");//field for entering text criteria
            myEnterCriteria.characters = 25;
            myEnterCriteria.active = true;
                           
        var myListOfColors = myEnterCriteriaGroup.add("dropdownlist",undefined,mySwatchNames);//dropdown field for choosing swatch
                            
        //add button to add another row of fields to gather another set of user input
        var addAnother_button = myEnterCriteriaGroup.add("button", undefined, "Add Another");
        
        //event handler registered
        addAnother_button.onClick = add_AnotherInputLine; //no passing parameters here! won't show button to be clicked!

            //event handler...callback functions put input into arrays
                myEnterCriteria.onChange = function() {
                    criteriaKeys.push(myEnterCriteria.text);
                };

                myListOfColors.onChange = function() {
                    if(myListOfColors.selection === null) {
                        myListOfColors.selection=myListOfColors.prevSel;
                    } else {
                        myListOfColors.prevSel=myListOfColors.selection.index
                    criteriaValues.push(myListOfColors.selection.text);
                    };
                };
      //if you don't add another group (add_AnotherInputLine() function...text edit field & dropdown) it hangs here... Ok or Cancel button do nothing...

};


 //function adds another input row (text criteria and swatch choice) need to find a way NOT to remove OK/Cancel buttons...
function add_AnotherInputLine() {
    myCSdialog.remove(myCSdialog.children[myCSdialog.children.length - 1]);
    add_inputFields(myCSdialog);
    
    if (myCSdialog.children.length >= 1) {
    normalButtons(myCSdialog);
    };
    
    myCSdialog.layout.layout(true);  
   };

//function adds OK - Cancel buttons
function normalButtons(myCSdialog) {
        var myDialogButtons = myCSdialog.add("group");
        myDialogButtons.alignment = "right";   
        myDialogButtons.add("button", undefined, "OK");
        myDialogButtons.add("button", undefined, "Cancel");
};

Solution

  • Edit: I added comments below the lines that I added, to make it more understanable. I deleted some unnecessary lines as you can see.

    var mySwatchNames = app.activeDocument.swatches.everyItem().name
    
    var myCSdialog = new Window("dialog", "Setup Color Coding");
        // dialogSetup();
        //begin building dialog box myDialog
    
    
        var maingroup = myCSdialog.add('panel')//Added line
        // You need to put those InputFields into a container, to make sure 
    whenever you click on 'Add Another' button, the new fields will always 
    above the Yes/No button
    
        add_inputFields(maingroup);
        //So whenever you generate new fields, it will be always inside its 
    container 'maingroup', 
        //and the maingroup is the same level as YES/NO group, so YES/NO 
    will be always at the very end of the dialog.
    
        normalButtons(myCSdialog);
    
        myCSdialog.layout.layout(true)//Added line
        // Why I put this line here? Because when the script renders the add_inputFields(maingroup) 
        //in the first time, there is another myCSdialog.layout.layout(true) at the end of the function dd_inputFields(maingroup).
        // After this function, if you create OK/Cancel buttons, they won't show up, because the line myCSdialog.layout.layout(true) stop u generating those buttons.
        // You need this line to re-render the dialog, to have OK/Cancel showed up.
    
        myCSdialog.show()
    //function adds criteria input collection fields (text criteria and swatch choice)
    
    function add_inputFields(maingroup) {
            var myEnterCriteriaGroup = maingroup.add("group");
            //title for first input
            myEnterCriteriaGroup.add("statictext",undefined,"Criteria to Color Code");
            //text entry field to enter criteria term
            var myEnterCriteria = myEnterCriteriaGroup.add("edittext",undefined,"");//field for entering text criteria
                myEnterCriteria.characters = 25;
                myEnterCriteria.active = true;
                               
            var myListOfColors = myEnterCriteriaGroup.add("dropdownlist",undefined,mySwatchNames);//dropdown field for choosing swatch
                                
            //add button to add another row of fields to gather another set of user input
            var addAnother_button = myEnterCriteriaGroup.add("button", undefined, "Add Another");
            
            //event handler registered
            addAnother_button.onClick = add_AnotherInputLine; //no passing parameters here! won't show button to be clicked!
    
                //event handler...callback functions put input into arrays
                    myEnterCriteria.onChange = function() {
                        criteriaKeys.push(myEnterCriteria.text);
                    };
    
                    myListOfColors.onChange = function() {
                        if(myListOfColors.selection === null) {
                            myListOfColors.selection=myListOfColors.prevSel;
                        } else {
                            myListOfColors.prevSel=myListOfColors.selection.index
                        criteriaValues.push(myListOfColors.selection.text);
                        };
                    };
                    myCSdialog.layout.layout(true)//Added line
                    //As I explained above, this line is just like you are asking the window to re-render the dialog, whenever you click 'Add Another' button.
                    //This line will stop you generate the OK/Cancel buttons, so the dialog won't render them. That is why I added extra line at the top.
    
          //if you don't add another group (add_AnotherInputLine() function...text edit field & dropdown) it hangs here... Ok or Cancel button do nothing...
    
    };
    
    
     //function adds another input row (text criteria and swatch choice) need to find a way NOT to remove OK/Cancel buttons...
    function add_AnotherInputLine() {
        add_inputFields(maingroup);
        
       };
    
    //function adds OK - Cancel buttons
    function normalButtons(myCSdialog) {
            var myDialogButtons = myCSdialog.add("group");
            myDialogButtons.alignment = "right";   
            myDialogButtons.add("button", undefined, "OK");
            myDialogButtons.add("button", undefined, "Cancel");
    };