Skip to main content
Flowgun
Inspiring
August 24, 2025
Answered

How to programmatically get the list of selected layers?

  • August 24, 2025
  • 1 reply
  • 299 views

Hello everyone,
Is there a direct way to get the list of selected layers even if they are nested within groups?
Currently, I'm using this code I found on GitHub Which basically creates a new group that contains the selected layers, parses that group, and then undoes the grouping. I think that's too much of an overhead for a supposedly simple task, but I was unable to find any other better way to do it.

Correct answer Stephen Marsh

Some links to code for processing selected layers, using the same code variations from @jazz-y:

 
 
 
 
And here's some different code from @c.pfaffenbichler:
 
 
 
I also found the following examples in my archive/collection:

// Count Selected Layers - by jazz-y
// Notes: * The content of selected layer groups may also be included
//        * Depending on whether cmd or shift selected groups or select all layers menu command
//        * Selected layers will not be lost and will remain highlighted
s2t = stringIDToTypeID;
(r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
n =  executeActionGet (r).hasKey(p) ?  executeActionGet (r).getList(p).count : 0;
alert(n)

 

// Count Selected Layers - by Charu Rajput
// Notes: Selected layers will be lost

var doc = app.activeDocument;
var layers = doc.layers;

function getSelectedLayers() {
    var resultLayers = new Array();
    try {
        var idGrp = stringIDToTypeID("groupLayersEvent");
        var descGrp = new ActionDescriptor();
        var refGrp = new ActionReference();
        refGrp.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        descGrp.putReference(charIDToTypeID("null"), refGrp);
        executeAction(idGrp, descGrp, DialogModes.NO);
        for (var i = 0; i < app.activeDocument.activeLayer.layers.length; i++) {
            resultLayers.push(app.activeDocument.activeLayer.layers[i])
        }
        var id8 = charIDToTypeID("slct");
        var desc5 = new ActionDescriptor();
        var id9 = charIDToTypeID("null");
        var ref2 = new ActionReference();
        var id10 = charIDToTypeID("HstS");
        var id11 = charIDToTypeID("Ordn");
        var id12 = charIDToTypeID("Prvs");
        ref2.putEnumerated(id10, id11, id12);
        desc5.putReference(id9, ref2);
        executeAction(id8, desc5, DialogModes.NO);
        return resultLayers;
    } catch (e) {
        alert("No Layer selected or locked layer selected");
        return resultLayers;
    }
}
var selectedLayers = getSelectedLayers();
alert(selectedLayers.length);

1 reply

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
August 24, 2025

Some links to code for processing selected layers, using the same code variations from @jazz-y:

 
 
 
 
And here's some different code from @c.pfaffenbichler:
 
 
 
I also found the following examples in my archive/collection:

// Count Selected Layers - by jazz-y
// Notes: * The content of selected layer groups may also be included
//        * Depending on whether cmd or shift selected groups or select all layers menu command
//        * Selected layers will not be lost and will remain highlighted
s2t = stringIDToTypeID;
(r = new ActionReference).putProperty(s2t('property'), p = s2t('targetLayers'));
r.putEnumerated (s2t ('document'), s2t ('ordinal'), s2t ('targetEnum'));
n =  executeActionGet (r).hasKey(p) ?  executeActionGet (r).getList(p).count : 0;
alert(n)

 

// Count Selected Layers - by Charu Rajput
// Notes: Selected layers will be lost

var doc = app.activeDocument;
var layers = doc.layers;

function getSelectedLayers() {
    var resultLayers = new Array();
    try {
        var idGrp = stringIDToTypeID("groupLayersEvent");
        var descGrp = new ActionDescriptor();
        var refGrp = new ActionReference();
        refGrp.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        descGrp.putReference(charIDToTypeID("null"), refGrp);
        executeAction(idGrp, descGrp, DialogModes.NO);
        for (var i = 0; i < app.activeDocument.activeLayer.layers.length; i++) {
            resultLayers.push(app.activeDocument.activeLayer.layers[i])
        }
        var id8 = charIDToTypeID("slct");
        var desc5 = new ActionDescriptor();
        var id9 = charIDToTypeID("null");
        var ref2 = new ActionReference();
        var id10 = charIDToTypeID("HstS");
        var id11 = charIDToTypeID("Ordn");
        var id12 = charIDToTypeID("Prvs");
        ref2.putEnumerated(id10, id11, id12);
        desc5.putReference(id9, ref2);
        executeAction(id8, desc5, DialogModes.NO);
        return resultLayers;
    } catch (e) {
        alert("No Layer selected or locked layer selected");
        return resultLayers;
    }
}
var selectedLayers = getSelectedLayers();
alert(selectedLayers.length);
Flowgun
FlowgunAuthor
Inspiring
August 24, 2025

so the only way to get selected layers as objects is either to group them first like your last bit of code, or to select them one by one then restore selection? I guess getting their IDs and working with that might be more transparent as it won't add history entries or make changes to the UI or return to an unwanted state if the script crashes, but working with IDs conceals certain useful methods, that we can still get from JSON info, but that introduces more complications and slowdowns.

Flowgun
FlowgunAuthor
Inspiring
August 27, 2025

I ended up using a code that I was avoiding for speed concerns, but surprisingly, it turns out to be quite quick. we can get the IDs of selected layers using the methods above, then loop once through the whole document (recursively to get into groups) to build a map with all the layer objects, then we just compare the IDs we have with the IDs of layer objects in the map, and if they match, then we push that object into an array. Before building the map of all the layers, we can check if we have a single ID, and then we just return [doc.ActiveLayer]