Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Assign an .onClick() function to a generic/automatically created button?

Community Expert ,
Oct 13, 2015 Oct 13, 2015

Hey Scripters.

I'm back again with another noodle scratcher. I'm attempting to write a script UI dialog with one simple checkbox at the top, then a group of buttons underneath. The number of buttons generated and their display text will vary from doc to doc, so I am creating the buttons with a loop. However, because of this i encountered an issue I hadn't anticipated.

I want to set each button to run a function that sets a couple variables and then closes the dialog window. Normally, I would use:

buttonName.onClick(){function(){

          set variables

          window.close();

     }

}

unfortunately, since I'm using a loop to create each button, i don't have a unique variable set for each button, so I don't know how to assign the .onClick().... Any thoughts on this?

here's the jumbled mess of code I'm working with as of right now.. I apologize in advance..

function placeAdditionalArt(addArtLayer){

        var addArt = addArtLayer.pageItems[0];

        var layerName = addArtLayer.name;

        var pieces = wearerLayer.layers["Prepress"].layers[0].pageItems;

       

        //begin script ui window// determine destination shirt piece and whether or not to scale

       

        var aaLoc = new Window("dialog", "Additional Artwork");

        var aaLocInfo = createAALoc();

        function createAALoc(){

            var result;

            var scale;

            var scaleGroup = aaLoc.add("group");

                var yesNoscale = scaleGroup.add("checkbox", undefined, "Scale Artwork");

            var pieceGroup = aaLoc.add("group");

                for(var a=0;a<pieces.length;a++){

                    var thisPiece = pieces;

                    var thisName = pieces.name;

                    if(thisName.indexOf("Waistband")<0 && thisName.indexOf("Cuff")<0 &&

                    thisName.indexOf("Collar")<0 && thisName.indexOf("Placard")<0){

                        pieceGroup.add("button", undefined, thisName);

                        this.onClick = function(){ //this.onClick doesn't work because i imagine this refers to pieceGroup in this context..

                            result = thisPiece;

                            if(yesNoScale){

                                scale = true;

                            }

                            aaLoc.close();

                        }  

                    }

                }

            aaLoc.show();

            return [result,scale];

        }

        var destPiece = aaLocInfo[0];

        var scaleAddArt = aaLocInfo[1];

       

        // end script ui

       

        for(var a=0;a<prepressLayer.layers.length;a++){

            var curSize = prepressLayer.layers.name;

            var dest = prepressLayer.layers.groupItems.getByName(curSize + " " + destPiece);

            var scale = (newWidth / addArt.width)*100;

            var addArtCopy = addArt.duplicate(dest);

            addArtCopy.resize(scale,scale,true,true,true,true,00);

            newWidth = newWidth + addscale;

            addArtCopy.name = curSize + " Additional Art";

        }

    }

TOPICS
Scripting
1.3K
Translate
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

Guide , Oct 13, 2015 Oct 13, 2015

I would use an array to hold the buttons.

this has not been tested at all. though it's that same concept I used in "PieMaker" if you ever saw that thread.

// replace lines 21 - 28 with this line

add_button (a, thisName);

// add this section above the for loop but still within the createAAloc function

var btn = [];

function add_button(num, thisName){

    btn[num] = pieceGroup.add("button", undefined, thisName);

    btn[num].onClick = function(){

        result = thisPiece;

        if(yesNoScale

...
Translate
Adobe
Valorous Hero ,
Oct 13, 2015 Oct 13, 2015

I would do this following stuff to get it to work.

Set a variable for the button: var btn = pieceGroup.add("button", undefined, thisName); 

Assign the click handler to the button like this: btn.onClick = function(){...

Translate
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
Guide ,
Oct 13, 2015 Oct 13, 2015

I would use an array to hold the buttons.

this has not been tested at all. though it's that same concept I used in "PieMaker" if you ever saw that thread.

// replace lines 21 - 28 with this line

add_button (a, thisName);

// add this section above the for loop but still within the createAAloc function

var btn = [];

function add_button(num, thisName){

    btn[num] = pieceGroup.add("button", undefined, thisName);

    btn[num].onClick = function(){

        result = thisPiece;

        if(yesNoScale){

            scale = true;

        }

        aaLoc.close();

    }

}

Translate
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 ,
Oct 14, 2015 Oct 14, 2015

Thanks, Silly. But I can't assign a variable to a button, unless i assign the same variable to all buttons. Since i'm creating the buttons by looping through an unknown number of group items and then assigning the name of the group item to the button text.

Qwerty, i really like that solution. simple and elegant. It took me some time to organize my thoughts and figure out the flow of control, but i got it all thanks to your snippet. I'm now generating all the right buttons and their onClick methods are working perfectly.

the next step is to build a grid of radio buttons to determine the translation point for scaling.

thanks yet again Qwerty and Silly. you have both saved me from hours or days of frustration on multiple occasions.

Translate
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
Valorous Hero ,
Oct 14, 2015 Oct 14, 2015

I also thought this in the beginning, but, you can assign the same variable to all the buttons and their handlers will work just fine. It's if you need to refer to the buttons later via that variable that you'll have a problem, but if you need to just do something from "within" the button, the 'this' keyword appears to be bound to the same element.

function test(){

    var w = new Window("dialog", "test");

    for(var i=0; i<10; i++){

        var btn = w.add("button", undefined, "Button " + (i+1));

        btn.onClick = function(){

            alert(this.text + " was clicked.");

        }

    };

    var btn_test = w.add("button", undefined, "What's in 'var btn' ?");

    btn_test.onClick = function(){

        alert(btn.text);

    };

    w.show();

}

test();

Translate
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 ,
Oct 14, 2015 Oct 14, 2015

oh, very nice. good to know. i'll keep that in the knowledge bank. People here at work are already really impressed with the super basic level of scriptUI i've done and i've only scratched the surface.

Thanks again, guys. 😃

Translate
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
Guide ,
Oct 14, 2015 Oct 14, 2015

silly is correct, you can re use the same var for all.

but to make it simple to reference later, the array is my preferred option.

glad it helps you out.

Translate
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 ,
Oct 15, 2015 Oct 15, 2015

i like that feature as well, Qwerty.

I do wonder though, once the script moves out of the context of the button creation loop, how would you know how to access a particular one? For example, if the loop created 4 buttons with the text "1", "3", "4", "2", and you later wanted to access the button with the text "3", how would you go about that? Can the button be accessed by the text it contains? or can you only access by index of the array?

If it is the latter, i wonder if you could use the loop to create an object or associative array to allow you to access the buttons by name later. i tried to write an example, but i'm not sure how to create an object like that.. perhaps an object constructer function defined elsewhere. But that's something i won't spend time trying to figure out unless i need it..

Sorry. just thinking out loud.

Translate
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
Valorous Hero ,
Oct 15, 2015 Oct 15, 2015

Qwerty used an array to hold buttons for later reference, and a function to iterate through that array to search by matching text or custom property can pull a desired button for you.

Translate
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
Guide ,
Oct 15, 2015 Oct 15, 2015
LATEST

silly has it, just use a loop to find the data you want.

ie.

for (var i = 0; i < btn.length; i++){

    if(btn.text == "cheese"){

        alert("We found cheese in button " + i);

    }

}

Translate
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