Skip to main content
amberw42080715
Inspiring
January 15, 2020
Answered

Loop through Layers

  • January 15, 2020
  • 7 replies
  • 7459 views

Hello,

I'm trying to ultimately Loop through Layers to see if they are visible(false) or locked(true) and if so skip or turn visible to true or turn locked to false.

 

I managed to do this with pathItems but I can't figure out why I can't do it with layers.  Actually the check to see if it's visible isn't working either. 

 

Anyway....when I run the script below on my work that has 1,000++ of pathItem it takes forever.  So I wanted to add to the script to first loop through the layers to see if they are visible or locked to begin with.  I tried using app.activeDocument.layers, but that doesn't seem to work and I don't understand why and I can't find any good tutorials to explain it.  Any insight would be very much appreciated.  

 

var doc = app.activeDocument;
var pathName = doc.pathItems;

 

function setColor(names) {

    for (var i=0; i < pathName.length; i++) {
        var currentLayer = pathName[i];
        var pathNames = currentLayer.name;
        var searchIndex = pathNames.indexOf(names);
            if (searchIndex != -1 & currentLayer.locked == false & currentLayer.visible == true) {
                 currentLayer.selected = true;    }
    }

}

setColor("0");

This topic has been closed for replies.
Correct answer amberw42080715

OK I figured it out.  I realized I was looping through the entire document for pathItems, when I only wanted to loop through pathItems if the layer was unlocked.  

 

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

 

function pathName(nameOfPath) {

   for (var ii = 0; ii < layerName.length; ii++) { //looping through all the layers
   var currentLayer = layerName[ii];
   var layerLocked = currentLayer.locked;
           

     if(currentLayer.locked == false) {
     var currentLayerPath = currentLayer.pathItems; //getting the pathItems of the layers that are unlocked

           for (var p=0; p < currentLayerPath.length; p++) {  //looping through the pathItems in the layers that are unlocked
           var currentPath = currentLayerPath[p];
          var pathNames = currentPath.name;
          var searchIndexPath = pathNames.indexOf(nameOfPath);

             if (searchIndexPath != -1) {
            currentPath.selected = true;
            }
       }
    }
  }

}

pathName("15");

 

Thank you for all your help.

7 replies

pixxxelschubser
Community Expert
Community Expert
January 21, 2020

I dont know what your intention is. But why not select the path Item directly?

try {
    var aDoc = app.activeDocument;
    var pI = aDoc.pathItems.getByName ("10");
    pI.selected = true;
    }
catch (e) {
    alert ("Sorry, not found or invisible or locked (item or layer)");
    }
amberw42080715
amberw42080715AuthorCorrect answer
Inspiring
January 22, 2020

OK I figured it out.  I realized I was looping through the entire document for pathItems, when I only wanted to loop through pathItems if the layer was unlocked.  

 

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

 

function pathName(nameOfPath) {

   for (var ii = 0; ii < layerName.length; ii++) { //looping through all the layers
   var currentLayer = layerName[ii];
   var layerLocked = currentLayer.locked;
           

     if(currentLayer.locked == false) {
     var currentLayerPath = currentLayer.pathItems; //getting the pathItems of the layers that are unlocked

           for (var p=0; p < currentLayerPath.length; p++) {  //looping through the pathItems in the layers that are unlocked
           var currentPath = currentLayerPath[p];
          var pathNames = currentPath.name;
          var searchIndexPath = pathNames.indexOf(nameOfPath);

             if (searchIndexPath != -1) {
            currentPath.selected = true;
            }
       }
    }
  }

}

pathName("15");

 

Thank you for all your help.

pixxxelschubser
Community Expert
Community Expert
January 20, 2020

Please describe exactly what you want - completely.

amberw42080715
Inspiring
January 21, 2020

I’ve re-examined my script and tried a few different things, but I’m still running into the problem with the error. 

 

 

 

 

 

 

I would like to loop through the layers and if the layer is locked I would like the script to skip that layer and move onto the next layer.  Once it hits a layer that is not locked (Layer 5) then I would like the script to loop through the pathItems and select the pathItem with a specific name. 

 

Here is the script I’m working with right now. 

var doc = app.activeDocument;

var pathName = doc.pathItems;

var myLayer = doc.layers;

var layerCount = myLayer.length;

 

function checkLockedLayer() { 

   for (i = layerCount - 1; i >= 0; i--) {                                  

        if (myLayer[i].locked == true) {

          continue;

       } else if (myLayer[i].locked == false) {

          pathSelect(names);

      }

   }

}

 

function pathSelect(names) { 

  for (var p=0; p < pathName.length; p++)    {

     var currentLayer = pathName[p];

     var pathNames = currentLayer.name;

     var searchIndex = pathNames.indexOf(names);

          if (searchIndex != -1) {

         currentLayer.selected = true;

      }

   }

}

pathSelect("10");

 

“Layer 2” has NO pathItems named “10” so no error pops up when I lock that layer.  But if the next layer has a pathItem named “10” in it and it’s locked, the error pops up.  It’s like the layer loop isn’t doing anything at all.

 

Thank you for your help and time I really appreciate it.  

pixxxelschubser
Community Expert
Community Expert
January 20, 2020

 @amberw42080715 I'm confused now …

My code

if (myLayer[i].locked == false && myLayer[i].visible == true

does exactly what you want. Only if a layer is visible and unlocked --> select the first item of that layer.

Is the layer locked or invisible - that layer will be ignored.

amberw42080715
Inspiring
January 20, 2020

yes but I would like to lock some layers and have the next part of the code only execute on the layers that are not locked.  Right now when the loop reaches a locked layer illustrator throws up an error.

pixxxelschubser
Community Expert
Community Expert
January 20, 2020

Something like that?

var aDoc = app.activeDocument;
var myLayer = aDoc.layers;
var layerCount = myLayer.length;
var i;

for (i = layerCount - 1; i >= 0; i--) {
        if (myLayer[i].locked == false && myLayer[i].visible == true) {
            myLayer[i].pathItems[0].selected= true; // select the first path of that layer
            }
    }
amberw42080715
Inspiring
January 20, 2020

Thank you for the reply but I'm trying to do something more like this:

 

var aDoc = app.activeDocument;
var myLayer = aDoc.layers;
var layerCount = myLayer.length;
var i;

for (i = layerCount - 1; i >= 0; i--) {
if (myLayer[i].locked == true && myLayer[i].visible == false) {

continue; //skip the layer and move onto the next......

} else if (myLayer[i].locked == false && myLayer[i].visible == true) { 
myLayer[i].pathItems[0].selected= true; // select the first path of that layer
}
}

 

I'm not sure why it's not working.  It's like illustrator doesn't reconize the javacript continue.  Right now if the layer is locked or not visible, illustrator puts up an Error saying....Target lyer cannot be modified.  Any ideas on why my loop won't skip it?  Do I need to use a different kind of loop?

Disposition_Dev
Legend
January 20, 2020

Sounds like the items that the script is trying to select may be locked.. try this.

function container()
{
    var aDoc = app.activeDocument;
    var myLayer = aDoc.layers;
    var layerCount = myLayer.length;
    var firstItem;
    var i;

    for (i = layerCount - 1; i >= 0; i--)
    {
        if (myLayer[i].locked == true || myLayer[i].visible == false)
        {
            continue; //skip the layer and move onto the next......
        }
        else
        {
            if(!myLayer[i].pathItems.length)
            {
                alert("No pathItems on layer: " + myLayer[i].name);
                continue;
            }
            firstItem = myLayer[i].pathItems[0];

            if(!firstItem.locked && !firstItem.hidden)
            {
                firstItem.selected = true;
            }
            else
            {
                alert("First path item on layer: " + myLayer[i].name + "\nlocked: " + firstItem.locked + "\nhidden: " + firstItem.hidden);
            }
        }
        firstItem = undefined;
    }
}
container();
pixxxelschubser
Community Expert
Community Expert
January 17, 2020

Sorry.

The translation of your description is not clear for me.

 

Do you want:

1) if a layer is locked or invisible --> ignore that layer and go to the next layer

 OR

2) if a layer is locked or invisible --> unlock and make that layer visible - and loop through the pathItems of that layer

 

???

amberw42080715
Inspiring
January 20, 2020

1) if a layer is locked or invisible --> ignore that layer and go to the next layer

pixxxelschubser
Community Expert
Community Expert
January 16, 2020

Hi amberw42080715

do you want to set all layers to visible and unlock?

 

Hi rcraighead

Nice try. Your code works.

😉

 

But depending on the answer of the TO I would say: there is no need to check if a layer is locked or invisible.

Loop through all layers and easy set to unlocked and visible. For example

var aDoc = app.activeDocument;
var myLayer = aDoc.layers;
var layerCount = myLayer.length;
var i;

for (i = layerCount - 1; i >= 0; i--) {
        myLayer[i].locked = false;
        myLayer[i].visible = true;
    }

 

This code only works with (top level) layers and not with sublayers or groups and so on.

amberw42080715
Inspiring
January 17, 2020

My intention is to use the loop to check whether or not a layer is locked or not visible, because if it's locked or not visible then I want to skip that Layer and loop through the pathItems of a layer that is unlocked or visible.  

 

So the code below is working I get an error saying the Layer can not be modified, but it does select the the pathItem in the first layer and then throws up the error.

 

function setColor(names) {

var doc = app.activeDocument;
var pathName = doc.pathItems;
var sel = doc.selection;
var myLayer = doc.layers;
var layerCount = myLayer.length;

for (var i=layerCount - 1; i >= 0; i--) {

if (myLayer[i].locked == true || myLayer[i].visible == false) {
continue;
} else if (myLayer[i].locked == false || myLayer[i].visible == true) {

for (var i=0; i < pathName.length; i++) {
var currentLayer = pathName[i];

var pathNames = currentLayer.name;
var searchIndex = pathNames.indexOf(names);

if (searchIndex != -1) {
currentLayer.selected = true;
}}}}
}

 

I would be happy if I can get it to work with locked.  Visible I'm not too concerned with.

Disposition_Dev
Legend
January 20, 2020

You have nested for loops here that both use the variable "i". 

 

So your child for loop is overwriting the parent for loop's loop variable. So by the time the inner loop is done executing, the outer loop variable is incorrect and it's trying to access a locked layer. 

 

I'm not exactly sure what this script is trying to accomplish though? it appears the ultimate goal is to set the "selected" property of a layer to true. But there is no "selected" property of the Layer object.

 

What is the goal of the script? 

rcraighead
Legend
January 15, 2020

As @pixxxel_schubser would say "Loop backwards".

https://community.adobe.com/t5/illustrator/my-first-quot-for-loop-quot-doesn-t-work/m-p/10471308

 

 

 

var aDoc = app.activeDocument;
var myLayer = aDoc.layers;
var layerCount = myLayer.length;
var i;

for (i = layerCount - 1; i >= 0; i--){
    if (myLayer[i].locked == true){
        myLayer[i].locked = false;
        }
    }

 

 

amberw42080715
Inspiring
January 17, 2020

Thank you for the code.  I guess I thought I could check if the loop was working by having the layer selected, but after reading these replys I realized layers can't be selected.  Is that correct?