Copy link to clipboard
Copied
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";
}
}
1 Correct answer
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
Explore related tutorials & articles
Copy link to clipboard
Copied
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(){...
Copy link to clipboard
Copied
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();
}
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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();
Copy link to clipboard
Copied
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. 😃
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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);
}
}

