Search code examples
javascriptphotoshopphotoshop-script

Photoshop scripting - trying to reference an UI element created in a funtion that is in a different file


I'm creating a script where a user must select from several dropdown lists in order to name their image. Since each row in the ui is the same and function the same (It contains a dropdown list, a selection box to enable editing the list, an edit text box and add/edit/remove buttons), I've created a function to add these ui elements instead of writing each one out. This function is also in a separate file. Everything works up until this point. What I now need to do is take whatever the user selected in the dropdown lists and create a file name from it. However, I cannot access the list. I guess because the function is last bit that is called.

I created a function that constructs the file name. I then tried to call the dropdown list in different locations and in different ways.

var dlg = new Window('dialog', 'Material to Library');

    //Material category panel, used to select which material dialogue option appears
    dlg.grp0 = dlg.add('group');
        dlg.grp0.addCatPnl = dlg.grp0.add('panel', [10, 110, 705, 170], 'Assign a type of material');
            panelOption(0, dlg.grp0.addCatPnl.matCatTitle, 'Material Category:', dlg.grp0.addCatPnl.matCat, dlg.grp0.addCatPnl.matCatAddBox, dlg.grp0.addCatPnl.matCatNew, dlg.grp0.addCatPnl.matCatEditText, dlg.grp0.addCatPnl.matCatAddButt, dlg.grp0.addCatPnl.matCatEdtButt, dlg.grp0.addCatPnl.matCatRmvButt, dlg.grp0.addCatPnl, 15, 40, false);

    //2)Create a panel for the option
    dlg.swap = dlg.add ('group');
    dlg.swap.visible = true;
    dlg.swap.orientation = 'stack';

        //panel swaps in
        dlg.swap.asgnPnlV = dlg.swap.add('panel', [10, 200, 705, 450], 'Assign material name');
            dlg.swap.asgnPnlV.visible = false;
            var ddlName = dlg.swap.asgnPnlV.veneerMfg;
            panelOption(1, dlg.swap.asgnPnlV.veneerMfgTitle, 'Manufacturer:', dlg.swap.asgnPnlV.veneerMfg, dlg.swap.asgnPnlV.veneerMfgAddBox, dlg.swap.asgnPnlV.veneerMfgNew, dlg.swap.asgnPnlV.veneerMfgEditText, dlg.swap.asgnPnlV.veneerMfgAddButt, dlg.swap.asgnPnlV.veneerMfgEdtButt, dlg.swap.asgnPnlV.veneerMfgRmvButt, dlg.swap.asgnPnlV, 15, 40, true);
            panelOption(1, dlg.swap.asgnPnlV.veneerSpeciesTitle, 'Species', dlg.swap.asgnPnlV.veneerSpecies, dlg.swap.asgnPnlV.veneerSpeciesAddBox, dlg.swap.asgnPnlV.veneerSpeciesNew, dlg.swap.asgnPnlV.veneerSpeciesEditText, dlg.swap.asgnPnlV.veneerSpeciesAddButt, dlg.swap.asgnPnlV.veneerSpeciesEdtButt, dlg.swap.asgnPnlV.veneerSpeciesRmvButt, dlg.swap.asgnPnlV, 50, 75, true);
            panelOption(1, dlg.swap.asgnPnlV.veneerCutTitle, 'Cut', dlg.swap.asgnPnlV.veneerCut, dlg.swap.asgnPnlV.veneerCutsAddBox, dlg.swap.asgnPnlV.veneerCutNew, dlg.swap.asgnPnlV.veneerCutEditText, dlg.swap.asgnPnlV.veneerCutAddButt, dlg.swap.asgnPnlV.veneerCutEdtButt, dlg.swap.asgnPnlV.veneerCutRmvButt, dlg.swap.asgnPnlV, 85, 110, true);
            panelOption(1, dlg.swap.asgnPnlV.veneerStainTitle, 'Stain', dlg.swap.asgnPnlV.veneerStain, dlg.swap.asgnPnlV.veneerStainAddBox, dlg.swap.asgnPnlV.veneerStainNew, dlg.swap.asgnPnlV.veneerStainEditText, dlg.swap.asgnPnlV.veneerStainAddButt, dlg.swap.asgnPnlV.veneerStainEdtButt, dlg.swap.asgnPnlV.veneerStainRmvButt, dlg.swap.asgnPnlV, 120, 145, false);
            panelOption(1, dlg.swap.asgnPnlV.veneerMapTitle, 'Map', dlg.swap.asgnPnlV.veneerMap, dlg.swap.asgnPnlV.veneerMapAddBox, dlg.swap.asgnPnlV.veneerMapNew, dlg.swap.asgnPnlV.veneerMapEditText, dlg.swap.asgnPnlV.veneerMapAddButt, dlg.swap.asgnPnlV.veneerMapEdtButt, dlg.swap.asgnPnlV.veneerMapRmvButt, dlg.swap.asgnPnlV, 155, 180, false);
            //This one works(below), but this is not what I want
            //materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, 'sel1', 'sel2', 'sel3', 'sel4', 'sel5');
            //This one (below) is what I actually want Error 21, undefined is not an object line 25....
            materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.veneerMfg.selection, dlg.swap.asgnPnlV.veneerSpecies.selection, dlg.swap.asgnPnlV.veneerCut.selection, dlg.swap.asgnPnlV.veneerStain.selection, dlg.swap.asgnPnlV.veneerMap.selection);  

        //Other panels to swap in

    ////

dlg.show();

    ////

    function panelOption(panelPosition, title, titleText, name, nameAddbox, nameNew, nameEditText, nameAddButt, nameEdtButt, nameRmvButt, pnlNm, x1, x2, isUpperCase){
        var listArray = ['test1', 'test2', 'test3', 'veneer'];
        title = pnlNm.add('StaticText', [15, x1, 110, x2], titleText.toString());
        name = pnlNm.add('DropDownList', [120, x1, 230, x2], listArray);
        nameAddbox = pnlNm.add('checkbox', [240, x1, 260, x2], 'Edit List');
            nameAddbox.value = false;           
        nameNew = pnlNm.add('StaticText', [330, x1, 360, x2], 'New:');
        nameEditText = pnlNm.add('EditText', [360, x1, 480, x2],);
            nameEditText.enabled = false;
        nameAddButt = pnlNm.add('button', [490, x1, 545, x2], ' add ');
            nameAddButt.enabled = false;
        nameEdtButt = pnlNm.add('button', [555, x1, 610, x2], 'edit');
            nameEdtButt.enabled = false;
        nameRmvButt = pnlNm.add('button', [620, x1, 675, x2], 'remove');
            nameRmvButt.enabled = false;

        if (panelPosition == 0){
            name.onChange = function(){
                var x = name.selection;
                switch (x.toString()){
                case 'veneer':
                    dlg.swap.asgnPnlV.visible = true;
                    dlg.swap.asgnPnlSS.visible = false;
                    break;

                default:
                    dlg.swap.asgnPnlV.visible = false;  
                }
            }
        }
    }

function materialName(matName, pnlNm, nom1, nom2, nom3, nom4, nom5){
    var temp = 'material name here build as it goes';
    var nomenclature1 = nom1;
    var nomenclature2 = nom2;
    var nomenclature3 = nom3;
    var nomenclature4 = nom4;
    var nomenclature5 = nom5;

    var temp = nomenclature1 + '_' + nomenclature2 + '_' + nomenclature3 + '_' + nomenclature4 + '_' + nomenclature5;
    matName = pnlNm.add('StaticText', [15, 205, 310, 230], temp);

    if (pnlNm.visible == true){
        dlg.findElement ('veneerMfg').onChange = function() {
            //var nomenclature1 = Nom1.selection;
            //return nomenclature1;
            alert ('found element');
        }
    }
}

What I need is the the name.selection to be one of the values in the dropdown list that was selected by the user. Whenever I call the name.selection element that was created with the function it gives be 'undefined'. I tried dlg.findElement ('veneerMfg') this gave me 'null', which I am guessing it means it found the element, but I need to be able to find it when the user changes the selection in the dropdown box.


Solution

  • I think the easiest way to access the dropdowns would be via children of your dlg.swap.asgnPnlV panel, something like this:

    var myButton = dlg.add('button',undefined,'Test');
    
    myButton.onClick = function() {
        var k = 1; // there're 40 children, each 8th is the dropdown, starting from index 1
        var names = [];
        for (var i = 0; i < dlg.swap.asgnPnlV.children.length; i++) {
         // add only every 8th element
         if ((i-k)%8 == 0) { 
            names.push(dlg.swap.asgnPnlV.children[i].selection)
         }
        }
        alert(names);
    }
    

    enter image description here

    So your function would look something like this:

    materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.children[1].selection, dlg.swap.asgnPnlV.children[9].selection, dlg.swap.asgnPnlV.children[17].selection, dlg.swap.asgnPnlV.children[25].selection, dlg.swap.asgnPnlV.children[33].selection);  
    

    This is however not very versatile. Even better would be adding all those panel in a loop, this way it's possible to modify my names object on the fly without asking for all the children. Note the closure I used to make sure that all dropdowns will change names properly.

    var panelData = [
    {
        name: 'Manufacturer',
        list: ['m1', 'm2', 'm3'],
        coords: [15, 40]
    },
    {
        name: 'Species',
        list: ['s1', 's2'],
        coords: [50, 75]
    },
    {
        name: 'Cut',
        list: ['cut1', 'cut2', 'cut3', 'cut4', 'cut5'],
        coords: [85, 110]
    },
    {
        name: 'Stain',
        list: ['stain1', 'stain2', 'stain3', 'stain4'],
        coords: [120, 145]
    },
    {
        name: 'Map',
        list: ['map1', 'map2', 'map3', 'map4', 'map5', 'map6'],
        coords: [155, 180]
    }];
    
    var mygroup;
    var names = {};
    
    for (var i = 0; i < panelData.length; i++)
    {
        (function(item)
        {
            var mygroup = dlg.swap.asgnPnlV.add('group', [15, item.coords[0], 410, item.coords[1]]);
            mygroup.add('statictext', [0, 0, 110, 20], item.name);
            var myDropDown = mygroup.add('DropDownList', [110, 0, 230, 20], item.list);
            myDropDown.onChange = function()
            {
                names[item.name] = String(this.selection)
            }
        })(panelData[i])
    }
    
    var myB = dlg.add('button', undefined, 'Test');
    
    myB.onClick = function()
    {
        alert(JSON.stringify(names));
    }
    

    enter image description here

    so your function would look like this:

    materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, names['Manufacturer'], names['Species'], names['Cut'], names['Stain'], names['Map']);