Skip to main content
matias.kiviniemi
Legend
March 31, 2018
Answered

Getting layer reference by ID

  • March 31, 2018
  • 3 replies
  • 3659 views

Seems like a really fundamental/basic question that I can't answer, but is there a way (in ESTK) to get a layer reference by (doc and) layer Id? This is mainly a problem if you are sending a script to be evaluated from outside like Generator plugin, i.e. you know the Id of the layer you want to do something and are giving it as a parameter to JSX scripts. First trivial option is to traverse the DOM and search for your layer but in the worst case this will take minutes.  Second option would be to use AM-code as everything works with layer Ids, but then you can't use the Javascript DOM API and you are really hampering your options. Third option that is closest viable would be to set the layer as active using AM-code (which might be needed in many cases anyhow) and use the Document.activeLayer. But can you use AM-code to get a DOM layer reference? Essentially I'm looking for a Document.getLayerById().

This topic has been closed for replies.
Correct answer pixxxelschubser

Hi ,

I thought published a snippet which could help you - but I can't find the old thread. Try it

function getLayerID(){ 

var ref = new ActionReference(); 

ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );  

return executeActionGet(ref).getInteger(stringIDToTypeID( "layerID" )); 

};

If so, have fun

3 replies

Legend
April 1, 2018

CC2018. It is checked on the document (not active) with approximately 500 layers among which there are many nested folders. Works very quickly.

function get_layer_by_id(id, doc_id) 

    { 

    try { 

        var doc;

        if (doc_id == undefined) doc = activeDocument;

        else for (var i = 0; i < documents.length; i++)

            {

            if (documents.id == doc_id)

                {

                doc = documents;

                break;

                }

            }           

        if (doc == undefined) { alert("Bad document " + doc_id); return null; }

        var r = new ActionReference();   

        r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("json"));

        if (doc_id == undefined) r.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));

        else                     r.putIdentifier(charIDToTypeID("Dcmn"), doc_id);

        eval("var json = " + executeActionGet(r).getString(stringIDToTypeID("json"))); 

 

        if (json == undefined) return null; 

        var set = new Array();

 

        function search_id(layers, id) 

            { 

            for (var i = 0; i < layers.length; i++) 

                {

                if (layers.id == id) { set.push(i); return true; }

                }

            for (var i = 0; i < layers.length; i++) 

                {

                if (layers.layers)  

                    { 

                    if (search_id(layers.layers, id)) { set.push(i); return true; }

                    }

                }

            } 

        if (search_id(json.layers, id))

            {

            var ret = doc.layers;

            for (var i = set.length-1; i > 0; i--) 

                {

                ret = ret[set].layers;

                }

           

            return ret[set[0]];

            }

   

        return null;

        } 

    catch (e) { alert(e); } 

    } 

Participating Frequently
November 24, 2021

This function doesn't work as advertized for me (i.e. it fails to retreive a layer by its ID), but in its shortened form it solves a completely different problem I was having for a long time.

 

If we turn a small piece of your code into its own function...

function getDocData() {
    var r = new ActionReference();
    r.putProperty(charIDToTypeID("Prpr"), stringIDToTypeID("json"));
    r.putEnumerated(charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
    
    eval("var json = " + executeActionGet(r).getString(stringIDToTypeID("json")));

    return json;
}

...it retrieves an object with data so exhaustive that traversing DOM becomes almost completely useless in a lot of cases (which is a good thing seeing how it's 3 to 4 orders of magnitude slower).

 

This is an actual mythical weapon right here. Thank you for sharing!

Legend
November 24, 2021
quote

This function doesn't work as advertized for me (i.e. it fails to retreive a layer by its ID)


By @Radiant_solution5C8C

 

"[i]" removed from the code text ... : (

 

pixxxelschubser
Community Expert
pixxxelschubserCommunity ExpertCorrect answer
Community Expert
March 31, 2018

Hi ,

I thought published a snippet which could help you - but I can't find the old thread. Try it

function getLayerID(){ 

var ref = new ActionReference(); 

ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );  

return executeActionGet(ref).getInteger(stringIDToTypeID( "layerID" )); 

};

If so, have fun

Participant
March 31, 2018

alert(app.activeDocument.layers[0]);

alert(app.activeDocument.layers[0].name);