indesign-extendScript to group items by page and layer

Community Beginner ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

Hello all,

I've been working on this small script :

var docA = app.activeDocument,
lastPage = docA.pages.lastItem(),
group_it = function() {
    var group0 = [];
    for(var i = 0; i<=docA.layers.length-1; i++){
        for(var j = 0; j<=lastPage.pageItems.length-1; j++){
            if (lastPage.pageItems[j].itemLayer.id == docA.layers[i].id) {
                alert(docA.layers[i].id + " - " + lastPage.pageItems[j].id);
                group0[i] = lastPage.groups.add(lastPage.pageItems[j],docA.layers[i],LocationOptions.AT_END);
                group0[i].name = "myGroup" + i;
            }
        }
    }
};
group_it();

 I tested it with a document with 3 layers, 2 pages and 4 items... But it always seems to give me an error at the line where the grouping occurs (group0[i] = lastPage...).

If I comment that line and the one following it, the alert box shows me the correct number of items-id.

I have to say, I'm rather puzzled by the whole thing... If some kind soul could shed some light on this problem, I would be most gratefull.

Mike

TOPICS
Scripting

Views

179

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 , Apr 15, 2022 Apr 15, 2022
A few issues with your code. You want to collect the layers page item into a temp array that you then pass to the groups.add() function for each layer. You were trying to create a group for each individual page item. Check out the below and let me know if you have questions:  var docA = app.activeDocument; var lastPage = docA.pages.lastItem(); group_it = function() { var group0; for(var i = 0; i<=docA.layers.length-1; i++){ group0 = []; //reinit an empty array for each layer ...

Likes

Translate

Translate
Adobe Community Professional ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

Hi,

 

I am not sure exactly what you are trying to do but the groups property of a page is readonly, which means you would not be able to add to it this way.

BarlaeDC_0-1650015441036.png

 

If you can explain what you are trying to achieve maybe we can provide assistance as to how best to achieve this?

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

@BarlaeDC Most collections like Groups are read-only, but most (if not all) have a .add() method to create new single instances on the fly. 

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

HI,

 

Thanks for this, I did not know that, and that will teach me to rely on the docs only 😄

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

Hello BaralaeDC,

and thanks for pointing this out. I based my script on this:

https://indisnip.wordpress.com/2010/07/24/group-allselected-items-on-page/

and he uses a method like so : 

app.activeWindow.activePage.groups.add(myObj);

However I modified my script because I noticed that I was feeding an item as the first argument of the add-method and it should have been an array of items. Here is the new version :

var docA = app.activeDocument,
aPage = docA.pages.lastItem(),
group_it = function() {
    var layerGroup = [],
    layerItems = [];
    for(var i = 0; i<=docA.layers.length-1; i++){
        for(var j = 0; j<=aPage.pageItems.length-1; j++){
            if (aPage.pageItems[j].itemLayer.id == docA.layers[i].id) {
                alert(docA.layers[i].id + " - " + aPage.pageItems[j].id);
                layerItems.push(aPage.pageItems[j]);
            }
        }
        layerGroup[i] = aPage.groups.add(layerItems,docA.layers[i],LocationOptions.AT_END);
        layerGroup[i].name = "layer" + i + " group";
        layerItems.length = 0;
    }
};
group_it();

 ... which still isn't working I'm afraid.

The error seems to be the same, and happens at the line:

layerGroup[i] = aPage...
What I find odd is that the alert shows only the first item of the inner for-loop and then the script throws the error which is on a line in the outer for-loop. So it seems like only 1 iteration of the inner loop is run. But when I comment the 2 lines (layerGroup[i]) then the alert shows all 5 items.
Anyway, to answer your question: The purpose of this script is to group elements on each layer for a given page. In this case it is the last page.

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

A few issues with your code. You want to collect the layers page item into a temp array that you then pass to the groups.add() function for each layer. You were trying to create a group for each individual page item. Check out the below and let me know if you have questions: 

 

var docA = app.activeDocument;
var lastPage = docA.pages.lastItem();

group_it = function() {
    var group0;
    for(var i = 0; i<=docA.layers.length-1; i++){
        group0 = []; //reinit an empty array for each layer
        for(var j = 0; j<=lastPage.pageItems.length-1; j++){
            if (lastPage.pageItems[j].itemLayer.id == docA.layers[i].id) {
                group0.push(lastPage.pageItems[j]); //push the page item to your array
            }
        }
        //groups.add wants an array of page items, so that's what we give it
        //you can pass any number of properties at the end of the add function, including name
        //so... no need for a variable and separate property set
        lastPage.groups.add(group0,docA.layers[i],LocationOptions.AT_END,{name:"myGroup" + i});
    }
};
group_it();

 

 

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

Hey thanks for your answer Brian 🙂

I tried it but still no joy.

The error happens at :

lastPage.groups.add...

And its' funny because if you take a llok above at my answer to BarlaeDC's post I did more or less the same modifications that you suggest.

Yeah well, this one seems like a tough nut to crack.

I'll continue working on it but I wonder if I need to implement some sort of call back thingie in the inner loop. Because I'm not quite sure it traverses the whole layer of items before the add method is run.

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

I just tested again with the layers in a different order and I noticed 2 things.

1.) the first run of the inner loop is ok. it creates a group & shows all the different items in the alert.

2.) it throws an error after the second run of the inner loop at line 13 which is:

layerGroup[i] = aPage...
see attached screenShot
Snap1.jpg

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 ,
Apr 15, 2022 Apr 15, 2022

Copy link to clipboard

Copied

Well... I did some more investigations and it seems that the script works perfectly 🙂

Except that it stops and throws an error when it encounters a layer with only one object... XD.

So here is the final script:

var docA = app.activeDocument,
aPage = docA.pages.lastItem(),
group_it = function() {
    var layerGroup;
    for(var i = 0; i<=docA.layers.length-1; i++){
        layerGroup = [];
        var layerItems = [];
        for(var j = 0; j<=aPage.pageItems.length-1; j++){
            if (aPage.pageItems[j].itemLayer.id == docA.layers[i].id) layerItems.push(aPage.pageItems[j])
        }
        if (layerItems.length > 1) {
            layerGroup[i] = aPage.groups.add(layerItems,docA.layers[i],LocationOptions.AT_END);
            layerGroup[i].name = "layer" + i + " group";
            layerItems = [];
        }
    }
};
group_it();

Thanks to both of you for your help 🙂

Much appreciated!

Mike

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 ,
Apr 16, 2022 Apr 16, 2022

Copy link to clipboard

Copied

Hi truf0,

just note, that you could still add a group with one single item to the page if you must because perhaps further code expects only group items on the page. How do you do this? Just add a rectangle to the spread and group that together with the other item. Then remove the added rectangle from the group. The group lives on with just one item. Groups with zero items are not possible…

 

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
Community Beginner ,
Apr 21, 2022 Apr 21, 2022

Copy link to clipboard

Copied

LATEST

Duly noted.

Thanks man 🙂

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