# How To Loop Through Layers

**URL:** <https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627>\
**Category:** UXP Plugin API\
**Created:** [September 15, 2021, 8:44pm UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627 "2021-09-15T20:44:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [September 15, 2021, 8:44pm UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/1 "2021-09-15T20:44:35Z")

</div>

From a button click I would like to loop through all layers and delete any Layer Syles which have a Color Overlay.

Can anyone suggest a way to achieve this please.

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [September 15, 2021, 10:54pm UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/2 "2021-09-15T22:54:12Z")

</div>

I think layer styles aren’t accessible via DOM yet, so you’ll have to use BatchPlay to check and delete them.

You could probably iterate the Layers collection of the DOM and get their id for further processing, or if you want to do a full BatchPlay approach you could read the `numberOfLayers` property of a document.  
Once you know how many layers exist, you can loop over them for example using a for loop like

```auto
for(let idx = 1; idx <= numberOfLayers; idx++) {
   // do stuff on each layer
}

```

To check for a color overlay style, you’ll first of all need to read the `layerEffects` property:

```auto
const fx = photoshop.action.batchPlay([
  {
    _obj: 'get',
    _target: [{ _property: 'layerEffects' }, { _ref: 'layer',_index: idx}],
  },
], { synchronousExecution: true })[0]['layerEffects']

```

If you iterate via IDs, you can also reference a layer by ID via `{ _ref: 'layer',_id: *id*}` instead.

The layer has a ColorFill, if this condition is true:  
`fx?.solidFill?.enabled || (!!fx?.solidFillMulti && fx.solidFillMulti.some(e => e.enabled))`

The questionmarks in that code probably don’t work for you if you don’t use Typescript. It’s called “optional chaining” and checks for undefined values. Without it you’d have to check if each of the objects is undefined also, to prevent errros:  
`if(fx && fx.solidFill && fx.solidFill.enabled ...)` and so on.

Once you found the relevant layers, you can delete the layer style. I’m not sure if there’s a function to delete a specific one, I think you can only do that using the setter for the layer effects in general. So you can simply [delete](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete) the `solidFill` or `solidFillMulti` property from the layerEffects object, and pass it to the setter. Here’s the descriptor for it

```auto
export function __setLayerEffects(layerEffects, idx: number) {
  return {
    _obj: 'set',
    _target: [
      {
        _ref: 'property',
        _property: 'layerEffects',
      },
      { _ref: 'layer', _index: idx}
    ],
    to: layerEffects,
  }
}

```

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [September 16, 2021, 8:03am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/3 "2021-09-16T08:03:23Z")

</div>

@simonhenke Thankyou for the explanation, this is going to be very useful in a number of ways as it explains the process nicely.

Having played around with some of your code, it reminded me that in the solid color object, green is reported from photoshop as grain.

Now I dont know if thats deliberate or a typo but lets just hope they dont decide oneday to change it to green 🙂

---

<div class="post-metadata">

**Author:** ![Karmalakas](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/karmalakas/32/1048_2.png) [@Karmalakas](https://forums.creativeclouddeveloper.com/u/Karmalakas)\
**Post date:** [September 16, 2021, 8:36am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/4 "2021-09-16T08:36:01Z")

</div>

> [@IanBarber](#):
>
> green is reported from photoshop as grain.
> 
> Now I dont know if thats deliberate or a typo but lets just hope they dont decide oneday to change it to green 🙂

IIRC, you can use `green` also. `grain` instead of `green` is a leftover from old days where it was just `GR` (I think) 🙂

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [September 16, 2021, 9:56am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/5 "2021-09-16T09:56:52Z")

</div>

Just ran a few tests and green shows undefined but grain shows the true value so it looks as though you have to use grain.

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [September 16, 2021, 10:52am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/6 "2021-09-16T10:52:48Z")

</div>

Green and grain both share the same char code `"Grn "`. BatchPlay is like a middleman doing the char code \<-\> string code conversion, as strings are more readable. So if you **get** a descriptor, you’ll have to access the property via `.grain`. If you **set** it however, it shouldn’t matter if you call the property `grain` or `green`, as both will be converted back to `"Grn "` again.

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [September 16, 2021, 11:05am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/7 "2021-09-16T11:05:14Z")

</div>

Using the code supplied from @simonhenke above, I can now loop through all layers and identify the ones which have the SolidFill enabled.

Using Alchemist, this code removes the SolidFill color, I tried to replace the \_index to idx but I get undefined returned.

Can anyone see anything obvious

```auto
batchPlay(
[
   {
      _obj: "disableSingleFX",
      _target: [
         {
            _ref: "solidFill",
            _index: 1 // tried replacing this with idx
         },
         {
            _ref: "layer",
            _enum: "ordinal",
            _value: "targetEnum"
         }
      ],
      _options: {
         dialogOptions: "dontDisplay"
      }
   }
],{
   synchronousExecution: false,
   modalBehavior: "fail"
});

```

---

<div class="post-metadata">

**Author:** ![simonhenke](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.creativeclouddeveloper.com/simonhenke/32/957_2.png) [@simonhenke](https://forums.creativeclouddeveloper.com/u/simonhenke)\
**Post date:** [September 16, 2021, 11:28am UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/8 "2021-09-16T11:28:26Z")

</div>

That’s the solidFill effect you’re referencing by index there ( a layer can have multiple ones), not the layer.  
If you want to target a specific layer by index, you’ll have to adjust the layer reference of the `_target` array:

```auto
{
  _ref: "layer",
  _index: idx
}

```

---

<div class="post-metadata">

**Author:** ![IanBarber](https://avatars.discourse-cdn.com/v4/letter/i/94ad74/32.png) [@IanBarber](https://forums.creativeclouddeveloper.com/u/IanBarber)\
**Post date:** [September 16, 2021, 12:03pm UTC](https://forums.creativeclouddeveloper.com/t/how-to-loop-through-layers/3627/9 "2021-09-16T12:03:53Z")

</div>

> [@simonhenke](#):
>
> ```auto
> {
> _ref: "layer",
> _index: idx
> }
> 
> ```

Thank You, that worked and I have now managed to condense the code a bit more to

```auto
batchPlay(
				[{
					_obj: "disableSingleFX",
					_target: [{
							_ref: "solidFill"
						},
						{
							_ref: "layer",
							_index: idx
						}
					]
				}], {
					synchronousExecution: false,
					modalBehavior: "fail"
				});

```
