Skip to main content
M.Hasanin
Inspiring
May 27, 2022
Answered

Apply object style to text frames in Array of Pages

  • May 27, 2022
  • 3 replies
  • 1000 views

Hi Experts, I dont know what the problem of this script , when it run in document without section(s) it run correctly but when i add section it cannot identify page (1,2,3) so page (1,2,3) became (7,8,9), see the screen shot here as example :

here is the script :

 

var myDoc = app.documents[0];
var myDocPages = myDoc.pages.everyItem().getElements();
var TargetPagesArray = [1,2,3];

//Loop in Pages
for(var n =  myDocPages.length-1; n >= 0; n--){
    if (checkPage(TargetPagesArray, n+1)) {
        $.writeln(n);
        //Now Assign to Desired Frames
        var allTargeTextFrames = myDoc.pages[n].textFrames.everyItem().getElements(); 
            // Check for text frames if locked and apply Object Style:
            for( var i = 0; i<allTargeTextFrames.length; i++ ){
                 if(allTargeTextFrames[i].locked == true){//Prevent Apply to Locked TextFrames
                    var locked = "locked"; //Dont Apply to Locked TextFrames!
                    }else{
            allTargeTextFrames[i].applyObjectStyle(myDoc.objectStyles.item("Test"));
            } 
        } 
    } 
}

//First Check if Page is Existed  in the Array Function - from Rob Day
function checkPage(PagesArray, obj) {
    for (var i = 0; i < PagesArray.length; i++) {
        if (PagesArray[i] === obj) {
            return true;
        }
    }
    return false;
}

 

to check if the page is already exist before continue, i used the function of  @rob day discussed here :

https://community.adobe.com/t5/indesign-discussions/remove-pages-in-an-array/m-p/11758331#M410798

 so please help! and thanks in advance

 

This topic has been closed for replies.
Correct answer m1b

While I think of it, here's another interesting thing about the object you get back from Page.itemByRange:

It gives you an everyItem-style object—sorry don't know the technical term for this thing. But it is an interesting object—very different from a normal collection or array.

 

You can do this:

var doc = app.activeDocument;
var myPages = doc.pages.itemByRange('1', '3');
var myPageNames = myPages.name;

If you run this, the myPageNames variable is a normal ExtendScript array containing strings—one for each page collected in the myPages variable and the strings are the page names. The equivalent of typing this:

var myPageNames = [
    doc.pages.itemByName('1').name,
    doc.pages.itemByName('2').name,
    doc.pages.itemByName('3').name
];

However, it isn't always that straightforward. If you do this:

var myTextFrames = myPages.textFrames;

then you get a single TextFrames collection object, not an array of TextFrames objects (one per page). This is convenient in some cases I suppose. So we just have to learn what to expect.

- Mark

3 replies

Community Expert
May 28, 2022

To spare you some trouble, do not work with page names, but with page positions, property documentOffset of a page, in the document. As you already found out, there could be two or more pages with exactly the same name in one document.

 

Regards,
Uwe Laubender

( Adobe Community Professional )

M.Hasanin
M.HasaninAuthor
Inspiring
May 28, 2022

Thanks @Laubender , its first time to identify (documnetOffset property), please can you show me example? and what if there is a lot of Numbers as the same name? shouid i loop for them using this property? and thanks in advance

BestMohammad Hasanin
Willi Adelberger
Community Expert
May 28, 2022

If you use primary text frames, you need only to apply text frames with that primary text frame with that object style.

M.Hasanin
M.HasaninAuthor
Inspiring
May 28, 2022

@Willi Adelberger 

Thank you, but in this case i need it scripted because i will use some individual pages in the array

BestMohammad Hasanin
m1b
Community Expert
May 27, 2022

Hi @M.Hasanin, your script is looking good, but I have made a few changes:

1. I've wrapped it in a main function and doScript call. This just helps by providing a single undo for each time you run the script—otherwise to undo, you must use one undo for each setting of object style.

2. I've changed the function name of checkPages to be more general—you can use it for any case where you want to know if an object is in an array.

3. I've changed the if predicate to check the *name* of the page converted to number, rather than the index.

- Mark

 

function main() {

    var myDoc = app.documents[0];
    var myDocPages = myDoc.pages.everyItem().getElements();
    var TargetPagesArray = [1, 2, 3];

    //Loop in Pages
    for (var n = myDocPages.length - 1; n >= 0; n--) {
        if (arrayContainsObject(TargetPagesArray, Number(myDocPages[n].name))) {
            $.writeln(n);
            //Now Assign to Desired Frames
            var allTargeTextFrames = myDoc.pages[n].textFrames.everyItem().getElements();
            // Check for text frames and apply label value:
            for (var i = 0; i < allTargeTextFrames.length; i++) {
                if (allTargeTextFrames[i].locked == true) {//Prevent Apply to Locked TextFrames
                    var locked = "locked"; //Dont Apply to Locked TextFrames!
                } else {
                    allTargeTextFrames[i].applyObjectStyle(myDoc.objectStyles.item("Test"));
                }
            }
        }
    }

    //First Check if Page is Existed  in the Array Function - from Rob Day
    function arrayContainsObject(arr, obj) {
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] === obj) {
                return true;
            }
        }
        return false;
    }

}


app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Do Script');

 

M.Hasanin
M.HasaninAuthor
Inspiring
May 28, 2022

@m1b 

Thanks a lot , i learned a lot from you, have a great day

BestMohammad Hasanin