Skip to main content
Inspiring
July 25, 2022
Answered

Run a function on each selected frame in turn

  • July 25, 2022
  • 2 replies
  • 335 views

Hi all,

I've made a script that places a text caption to either the side of a graphic frame or below it. At the moment, it only works with a single, selected graphic frame (must have an image inside it to capture the metadata). But I've hit a brick wall trying to get the script to loop when more than one frame is selected.

Here's the script before I started trying to loop it:

var doc = app.activeDocument;
var myPage = app.activeWindow.activePage;
var mySelection = app.selection[0];
var savedUnits = app.scriptPreferences.measurementUnit;
var filename = mySelection.graphics[0].itemLink.name;
var textFrameHeight = 10;
var textFrame = myPage.textFrames.add();
var captionText = filename.replace(/(.*)(\..*)/i, "$1");
var b = mySelection.geometricBounds;
var frameWidth = b[3]-b[1];
var frameHeight = b[2]-b[0];
var objectStyle = doc.objectStyles.itemByName("Photo Caption align base");

//THE DIALOG
var myList = ["Below", "Side"];
var myDialog = app.dialogs.add({name:"Credit/Caption", canCancel:true});
with (myDialog )
    with (dialogColumns.add())
        with(borderPanels.add())
            {
            staticTexts.add ({staticLabel:"Select:"});
            var myDropSelection = dropdowns.add({stringList:myList, selectedIndex:1});
            }
            
if(myDialog.show() == true){
	
	if(myDropSelection.selectedIndex == 0){
		baseCaption();
	}
	else if(myDropSelection.selectedIndex == 1){
		sideCaption();
  }
	myDialog.destroy();  
}



function baseCaption(){
// add a text frame for the caption below the graphic
textFrame.geometricBounds = [b[2], b[1], b[2] + textFrameHeight, b[3]];

//add caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
}

function sideCaption(){

// add a text frame to the right-hand side of the graphic
//[y1, x1, y2, x2] - coordinates of the top-left and bottom-right corners
//[0,  1,  2,  3] - array positions for coordinates
textFrame.geometricBounds = 
[b[2] ,b[1] + frameWidth, b[2] + textFrameHeight, b[3] + frameHeight];

textFrame.properties = {
  rotationAngle : 90
};

//fill it with the caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
  }

If some kind soul can offer any advice, that would be great.

Many thanks, J

This topic has been closed for replies.
Correct answer Manan Joshi

Hi @JustyR,

Try the following

var doc = app.activeDocument;
//THE DIALOG
var myList = ["Below", "Side"];
var myDialog = app.dialogs.add({name:"Credit/Caption", canCancel:true});
with (myDialog )
    with (dialogColumns.add())
        with(borderPanels.add())
            {
            staticTexts.add ({staticLabel:"Select:"});
            var myDropSelection = dropdowns.add({stringList:myList, selectedIndex:1});
            }
            
if(myDialog.show() == true){
	var myPage = app.activeWindow.activePage;
    for(var i = 0; i < app.selection.length; i++){
        var mySelection = app.selection[i];
        var filename = mySelection.graphics[0].itemLink.name;
        var captionText = filename.replace(/(.*)(\..*)/i, "$1");
        if(myDropSelection.selectedIndex == 0){
            baseCaption(myPage.textFrames.add());
        }
        else if(myDropSelection.selectedIndex == 1){
            sideCaption(myPage.textFrames.add());
        }
    }
	myDialog.destroy();  
}



function baseCaption(textFrame){
// add a text frame for the caption below the graphic
var textFrameHeight = 10;
var b = mySelection.geometricBounds;
var objectStyle = doc.objectStyles.itemByName("Photo Caption align base");
textFrame.geometricBounds = [b[2], b[1], b[2] + textFrameHeight, b[3]];

//add caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
}

function sideCaption(textFrame){

// add a text frame to the right-hand side of the graphic
//[y1, x1, y2, x2] - coordinates of the top-left and bottom-right corners
//[0,  1,  2,  3] - array positions for coordinates
var textFrameHeight = 10;
var b = mySelection.geometricBounds;
var frameWidth = b[3]-b[1];
var frameHeight = b[2]-b[0];
var objectStyle = doc.objectStyles.itemByName("Photo Caption align base");

textFrame.geometricBounds = [b[2] ,b[1] + frameWidth, b[2] + textFrameHeight, b[3] + frameHeight];

textFrame.properties = {
  rotationAngle : 90
};

//fill it with the caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
  }

If it works then let me know if you don't understand anything. The key is just to iterate over the selection collection and repeating the operations.

-Manan

2 replies

rob day
Community Expert
Community Expert
July 25, 2022

Hi @JustyR , Also, in your version you save the scripting measurement units, but you don’t set them, so when I ran Manan’s code with my document ruler units set to Inches the caption frame heights were 10 inches. You’ll need to set the script’s measurement units:

 

var doc = app.activeDocument;
app.scriptPreferences.measurementUnit = MeasurementUnits.MILLIMETERS;

 

I’m not sure if is necessary to save and reset the scripting preference units—like you would for ruler units— because they are set for this script.

JustyRAuthor
Inspiring
July 25, 2022

Thanks, Rob, I kept meaning to do something with that line.

Manan JoshiCommunity ExpertCorrect answer
Community Expert
July 25, 2022

Hi @JustyR,

Try the following

var doc = app.activeDocument;
//THE DIALOG
var myList = ["Below", "Side"];
var myDialog = app.dialogs.add({name:"Credit/Caption", canCancel:true});
with (myDialog )
    with (dialogColumns.add())
        with(borderPanels.add())
            {
            staticTexts.add ({staticLabel:"Select:"});
            var myDropSelection = dropdowns.add({stringList:myList, selectedIndex:1});
            }
            
if(myDialog.show() == true){
	var myPage = app.activeWindow.activePage;
    for(var i = 0; i < app.selection.length; i++){
        var mySelection = app.selection[i];
        var filename = mySelection.graphics[0].itemLink.name;
        var captionText = filename.replace(/(.*)(\..*)/i, "$1");
        if(myDropSelection.selectedIndex == 0){
            baseCaption(myPage.textFrames.add());
        }
        else if(myDropSelection.selectedIndex == 1){
            sideCaption(myPage.textFrames.add());
        }
    }
	myDialog.destroy();  
}



function baseCaption(textFrame){
// add a text frame for the caption below the graphic
var textFrameHeight = 10;
var b = mySelection.geometricBounds;
var objectStyle = doc.objectStyles.itemByName("Photo Caption align base");
textFrame.geometricBounds = [b[2], b[1], b[2] + textFrameHeight, b[3]];

//add caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
}

function sideCaption(textFrame){

// add a text frame to the right-hand side of the graphic
//[y1, x1, y2, x2] - coordinates of the top-left and bottom-right corners
//[0,  1,  2,  3] - array positions for coordinates
var textFrameHeight = 10;
var b = mySelection.geometricBounds;
var frameWidth = b[3]-b[1];
var frameHeight = b[2]-b[0];
var objectStyle = doc.objectStyles.itemByName("Photo Caption align base");

textFrame.geometricBounds = [b[2] ,b[1] + frameWidth, b[2] + textFrameHeight, b[3] + frameHeight];

textFrame.properties = {
  rotationAngle : 90
};

//fill it with the caption text
textFrame.contents = captionText;

try {
	if(objectStyle.isValid)
		textFrame.applyObjectStyle(objectStyle);

    } catch (error) {
                /* object style not found in document */
    }
  }

If it works then let me know if you don't understand anything. The key is just to iterate over the selection collection and repeating the operations.

-Manan

-Manan
JustyRAuthor
Inspiring
July 25, 2022

Thank you, Manan. That got it working perfectly. I shall study what you've done as I see there are a few subtle changes. Thanks again.