Im kind of new on this and im trying to find a solution to "Group" all layers in INDIVIDUAL/SEPARATE GROUPS.

Have not been successful within the 1st stage of my script to work by grouping each layer individually in separate because in 2nd stage i need to tell the script not to group top level layers or third sub-level layers.


The intention is for "Scene 1" and "Scene 2" as top level should be ignored as well as 3rd level sub-objects. Only the "to group" as 2nd level should be grouped.

Edit: i've designed a new scheme that reflects what i do have and what i need to end up with (Group ALL 2nd level layers with OR without children & ignore 1st + 3rd level ones - do NOT group children of layers).

enter image description here

I thought it would be simple to implement but im having hard time to figure out how to "work individual selections/actions" and exclude 1st and 3rd level from it.

Made few more attempts since i started this post and this is what i currently have. Was trying to transform each layer into it's own group. Not working.

    everythingSelected = activeDocument.selection;
    if (everythingSelected.length>0){
        var doc = app.activeDocument; //current document
        var s    = doc.selection; //current slection
        var sl   = s.length; //number of selected objects
        var m    = app.activeDocument.groupItems; //group items
        for(var i = 0 ; i < sl; i++) s[i].transform(m); //transform each to group
        app.redraw();
    }else{
        alert("Nothing selected!")
    }
  • Please share what you have tried. – Scott Dec 6 at 22:55
  • hey scott, thanks for the recommendation. posted it above. – graphic.ninja Dec 7 at 11:19

It looks like you are trying to group the items immediately inside top-level layers which are not groups. To quickly get to the issue, your approach here is needing an instrumental overhaul which will make your future work easier and possible.

In Illustrator, there's a document pageItems collection, as well as the other 'item' collections such as groupItems. The thing is, when you go document-level, it gives you all the items in all levels of nesting - so your groupItems would get you the groups you want, but also groups you don't want.

What you want to do is go after things in specific containers if you want to do some grouping. In your case you want to go through all the top layers and group immediately-nested items which aren't groups themselves already.

To reference a top-level layer you can use the Document.layers collection - do not worry as unlike the art-items mentioned above, document.layers does not return nested layers. Just as a note, Illustrator layers have the ability to have nested sub-layers, and are also accessed via the layer.layers property.

Now, unlike the document-level art stuff when you do something like var neededGroups = doc.layers[0].groupItems then you are targeting with your script just the top-level groups in the 1st layer.

Back in the day you used to have to create new groupItems and move art into them to group art with code. In the later versions they allowed us to use app.executeMenuCommand() to make grouping a little easier, but it has to rely on the document's current selection. Therefore, first we must ensure nothing is selected in the document.

var doc = app.activeDocument;
doc.selection = null;

You will need to go through your document's layers in an outer loop:

var thisLayer;
for(var i = 0; i < doc.layers.length; i++){
  thisLayer = doc.layers[i];
}

During that, you will need to go through the current layer's art in an inner loop (notice the 'i' counter is changed to the 'j' counter to ensure nested loop does not break the parent loop):

var thisPageItem;
for(var j = 0; j < thisLayer.pageItems.length; j++){
  thisPageItem = thisLayer.pageItems[j];
}

You will then have to check each item's typename property to see what kind of item that is. (As far as I know, the .typename is same result as .constructor.name property.) The typename for a group is going to be the string "GroupItem". If it's a group then we will avoid it, but for all other ones, we're going to select them.

if(thisPageItem.typename != "GroupItem"){
    thisPageItem.selected = true;
}

Now that all non-group items are selected at the bottom of the main loop, use the menu command function. It may be good to ensure that there's a selection with a conditional statement too: if(doc.selection.length){ app.executeMenuCommand("group"); }

And after it's been grouped - de-select the document for next go-around:

doc.selection = null;

Here is the whole thing put together:

var doc = app.activeDocument;
doc.selection = null;
var thisLayer;
for(var i = 0; i < doc.layers.length; i++){
    thisLayer = doc.layers[i];
    var thisPageItem;
    for(var j = 0; j < thisLayer.pageItems.length; j++){
        thisPageItem = thisLayer.pageItems[j];
        if(thisPageItem.typename != "GroupItem"){
            thisPageItem.selected = true;
        }
    }
    if(doc.selection.length){
        app.executeMenuCommand("group");
    }
    doc.selection = null;
}
  • Hey Silly, thank you so much for the detailed reply and sample. The guidance is great and easy to follow. I've used "executeMenuCommand" in ther simpler scripts but group one never came to me. Unfortunately im afraid i did not explained myself clearly above, so i've edited the initial question and designed a more clear scheme of my intention i believe, so please check it out. I dont want to grab single layers and group them, but would like to be able to group ALL 2nd level layers with OR without children & ignore 1st + 3rd level ones (children) - should NOT group children of layers). Thanks – graphic.ninja Dec 7 at 15:08
  • Oh okay, yes the Illustrator layer panel makes it ambiguous when looking at whether it's groups or layers - but with your new screenshot we can see they are clearly layers due to the different colors. – Silly-V Dec 7 at 15:17
  • i've thought of maybe create some function to repeat layer by layer like "Select+Group" > "Select+Group" > ... , but i would still need to exclude the parent layer and level 3 children i believe. – graphic.ninja Dec 7 at 15:20
  • a little bit more thought on a possible solution and im now wondering if i should make it by bulk action instead of scripting? what do you think? – graphic.ninja Dec 8 at 10:14

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.