Scripting – Get contents from textframe

Community Beginner ,
Nov 05, 2021 Nov 05, 2021

Copy link to clipboard

Copied

Hi all!

 

What I'm trying to achieve is the following: Every page of my document has a text frame outside the document boundaries. This text frame contains the name of the product or design and it has "1" written in the script label. Now, when trying to access the contents of that frame, my code fails me.

 

Currently, it looks like this:

function main() {
    app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL;

var _doc = app.activeDocument;
var _numberOfPages = _doc.pages.count();
var _fileName;

for (var i = 0; i < _numberOfPages; i++) {
    _fileName = _doc.pages[i].textFrames.item("1");
    alert(_fileName.contents);
}
}
main();

 

All I currently want is for the script to alert the contents of all the text frames with the script label value of 1. It doesn't make sense to me that I cannot access the contents of the frames with this method but I'm clearly doing something wrong here.

 

Any help is much appreciated!

TOPICS
Scripting

Views

163

Likes

Translate

Translate

Report

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

Adobe Community Professional , Dec 22, 2021 Dec 22, 2021

You could try to move the pasteboard frames to get a page number.

 

This gets all the text frames with a null parent page, moves them to the closest page, gets the page name, and moves them back:

 

function setFileName() {
    var d = app.activeDocument
    d.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
    var pw = d.documentPreferences.pageWidth;
    
    var b, pp, tc;
    var _fileNameArr = [];
    var tf = d.textFrames;
    for (var i = 0; i < tf.length; i++){
        //gets tex
...

Likes

Translate

Translate
Adobe Community Professional ,
Nov 05, 2021 Nov 05, 2021

Copy link to clipboard

Copied

Some points for your help.

  • You mentioned that your textframe lies outside the page boundary then such textframe will not be captured in the page objects textframes collection. So you will have to traverse the textframes collection of either the document or maybe spread object.
  • The item or itemByName methods return object with the specifed name, name is a different property than label. name property is set using the layers panel. If you are really after script label then you will have to use the label property of the object. Now since there is no query method based on label property you will have to check each object of the collection.
  • If you do use the name property then you should check if _fileName is a valid object. Like below

 

if(_fileName.isValid)
	alert(_fileName.contents);

 

 -Manan

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Nov 05, 2021 Nov 05, 2021

Copy link to clipboard

Copied

Hi nna_top,

script labels refer to the label property of a frame.

item("string") or itemByName("string") refer to the name property.

This is the case for InDesign CS5 version 7 and above.

Before version 7 you could get the label's content with item("string").

 

So you have to do another loop through the frames of every page to find the ones that are labeled with the string "1".

You have ask if textFrames[n].label == "1" and then do the alert.

 

Regards,
Uwe Laubender

( ACP )

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Nov 05, 2021 Nov 05, 2021

Copy link to clipboard

Copied

I would loop through doc.spreads as Manan suggests. If you have multipage spreads, you'll have to do some work (ie by examining the frame's geometricBounds property) to know which side of the spread it's on. 

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Nov 05, 2021 Nov 05, 2021

Copy link to clipboard

Copied

Every page of my document has a text frame outside the document boundaries.

 

Also, if the text frames are completely on the pasteboard I don’t think your pages loop will get them. You could do a single loop with the code Uwe suggested if you loop thru all page items, something like this:

 

 

 

function main() {
    var api = app.activeDocument.allPageItems
    for (var i = 0; i < api.length; i++){
        if (api[i].label == "1") {
            alert(api[i].contents)
        };
    };   
}

main();

 

 

 

If you select a text frame that is completely on the pasteboard, its parentPage returns null:

 

 

var s = app.documents[0].selection[0];
$.writeln(s.parentPage)
//returns null

 

 

Likes

Translate

Translate

Report

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 Beginner ,
Dec 22, 2021 Dec 22, 2021

Copy link to clipboard

Copied

This worked really well! I just ran into a follow-up issue. The goal of this script is essentially to export pages based on an input number (single page or a range). When exporting, the text inside these textboxes outside the boundaries should be added to the file name. So I've now constructed this code:

function main() {

    function setFileName() {
        var _pages = app.activeDocument.pages.count();
        var _fileNameArr = [];
        for (var i = 0; i < _pages; i++) {
            var temp = app.activeDocument.pages[i].textFrames.lastItem().contents;
            _fileNameArr.push(temp);
        }
        return _fileNameArr;
    }

    alert(setFileName());

}

main();

 

My current issue is that for some reason the setFileName function doesn't return anything. If I set an alert inside the for loop to notify me about _fileNameArr, it works. But as soon as I leave the for loop, the alert doesn't work anymore. Any ideas?

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Dec 22, 2021 Dec 22, 2021

Copy link to clipboard

Copied

Don't complicate things with nested functions. 

function setFileName() {
        var _pages = app.activeDocument.pages.count();
        var _fileNameArr = [];
        for (var i = 0; i < _pages; i++) {
            var temp = app.activeDocument.pages[i].textFrames.lastItem().contents;
            _fileNameArr.push(temp);
        }
        return _fileNameArr;
}

function main() {
       var _arr = setFileName();
       alert(_arr);
}

main();

 

 

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Dec 22, 2021 Dec 22, 2021

Copy link to clipboard

Copied

And if there are no text frames on the page there would be no lastItem— an Object invalid error:

 

Screen Shot 27.png

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Dec 22, 2021 Dec 22, 2021

Copy link to clipboard

Copied

I think you are running into the same problem–a text frame on the pasteboard would not be included in the pages[i].textFrames collection:

 

Screen Shot 25.pngScreen Shot 26.png

Likes

Translate

Translate

Report

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
Adobe Community Professional ,
Dec 22, 2021 Dec 22, 2021

Copy link to clipboard

Copied

LATEST

You could try to move the pasteboard frames to get a page number.

 

This gets all the text frames with a null parent page, moves them to the closest page, gets the page name, and moves them back:

 

function setFileName() {
    var d = app.activeDocument
    d.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
    var pw = d.documentPreferences.pageWidth;
    
    var b, pp, tc;
    var _fileNameArr = [];
    var tf = d.textFrames;
    for (var i = 0; i < tf.length; i++){
        //gets text frames on the pasteboard
        if (tf[i].parentPage == null) {
            tc = tf[i].contents
            b=tf[i].geometricBounds;
            //moves the frame to get the parent page number
            if (b[1] < 0) {
                tf[i].move( [-1,1] );
            } else {
                 tf[i].move( [pw-1,1] );
            }
            pp = tf[i].parentPage.name;
            tf[i].geometricBounds = b;
            
            _fileNameArr.push(pp + "-" + tc)
        } 
    };
    return _fileNameArr
}


alert(setFileName())

Likes

Translate

Translate

Report

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