• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Sort SELECTED layers alphabetically

Community Beginner ,
Oct 08, 2022 Oct 08, 2022

Copy link to clipboard

Copied

Hello,

I am trying to sort some layers within my document alphabetically. I have some scripts that work but they sort ALL layers and I would like to be able to sort only selected layers. Here is one of the scripts I have that work. Do you have a better code or do you know what I can add to this code to make it only work on selected layers?

 

#target photoshop

/**
 * @copyright Copyright (c) 2020 Matthew Kimber. All rights reserved.
 * @author Matthew Kimber <matthew.kimber@gmail.com>
 * @version 1.1
 * @license Apache Software License 2.0
 */

(function(app) {
	if (isDocumentOpen()) {
		main();
	} else {
		alert("Please open a document to run this script.");
	}

	/**
	 * @Desc Program entry point. Retrieves the active document, determines if layers exist, and then sorts all ArtLayer and LayerSet objects.
	 */
	function main() {
		var activeDoc = app.activeDocument;

		if (activeDoc.layers.length > 0) {
			sortLayers(activeDoc.layers);
		}
	}

	/**
	 * @Desc Sorts the layers in the current LayerSet.
	 * @Param {Layers} layers Collection of ArtLayer and LayerSet objects in the current scope.
	 */
	function sortLayers(layers) {
		var layerBuffer = new Array(),
			index = 0;
		
		for (index = 0; index < layers.length; index++) {
			if (!layers[index].isBackgroundLayer) {
				layerBuffer.push(layers[index]);
				
				// Check to see if we need to sort groups in the current layer set.
				if (typeof layers[index].layers !== "undefined" && layers[index].layers.length > 0) {
					sortLayers(layers[index].layers);
				}
			}
		}
		
		// Sort the buffer array using built-in natural sort comparer.
		layerBuffer.sort(compareWithNumbers);
		
		// Move each layer accordingly.
		for (index = 0; index < layerBuffer.length; index++) {
			layerBuffer[index].move(layers[index], ElementPlacement.PLACEBEFORE);
		}		
	}
	
	/**
	 * @Desc Checks to see if there is a document open.
	 * @Returns {Boolean}
	 */
	function isDocumentOpen() {
		return app.documents.length > 0;	
	}
}(app));

 

 

Thank you for your help!

 

TOPICS
Actions and scripting , Windows

Views

1.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Oct 09, 2022 Oct 09, 2022

Alright, it took me awhile, but here's a script that I hope works to sort just the selected layers. As you mentioned, the layers will be all together, so if the selected layers aren't contiguous, the script will just move all the other layer after where ever the first selected layer is located.

 

 

#target photoshop
var doc = activeDocument;
var bkgn = hasBackground ();
var topLayerID//To hold top selected layer ID

var lyrSelIDX = (getSelectedLayersIdx ())//indexes of selected layers
var orgLay
...

Votes

Translate

Translate
Adobe
Community Expert ,
Oct 08, 2022 Oct 08, 2022

Copy link to clipboard

Copied

Just a question, for now: if your selected layers are not contiguous, do you want the sorted layers to keep the same arrangement with non selected layers between them?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 08, 2022 Oct 08, 2022

Copy link to clipboard

Copied

Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

Slowly working on a solution, unless someone else comes up with one first. I have some old code about selecting multiple layers, just have to adapt it to this situation. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible for the state you start with and the result you want to get? 

 

Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.

It makes a difference for a Script so please make a meaningful and unequivocal decision. 

Should all the selected Layers be arranged at the Layer Stack-position the topmost selected one, the lowermost selected one, …? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

happyplant1111_0-1665344774521.png


Here is an example of what I would need. 


quote

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible for the state you start with and the result you want to get? 

 

Hey, I've only needed this feature for layers that are grouped together so I don't see that ever being important for me.

It makes a difference for a Script so please make a meaningful and unequivocal decision. 

Should all the selected Layers be arranged at the Layer Stack-position the topmost selected one, the lowermost selected one, …? 


By @c.pfaffenbichler

 

I am sorry I thought it was clear - No I do not need the script to take other layers into account. My layers will all be grouped. 

Thank you for your help!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

I should have added this to the OP for more context. 

There is this old thread that has code that is supposed to work, but I receive an error that I mentioned in the comments and I havent heard back:

https://community.adobe.com/t5/photoshop-ecosystem-discussions/sort-order-selected-layers-alphabetic...

I get some numerical value expected error. Again, more detail in the comment section on that thread. Another person commented about the same error. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

Alright, it took me awhile, but here's a script that I hope works to sort just the selected layers. As you mentioned, the layers will be all together, so if the selected layers aren't contiguous, the script will just move all the other layer after where ever the first selected layer is located.

 

 

#target photoshop
var doc = activeDocument;
var bkgn = hasBackground ();
var topLayerID//To hold top selected layer ID

var lyrSelIDX = (getSelectedLayersIdx ())//indexes of selected layers
var orgLayA = getLayerSetsData(lyrSelIDX)//array of selected layer names and IDs
multiSelectByIDs (topLayerID);
var topLayer = doc.activeLayer;//top selected layer
moveUpLayer ();
var upLayer = doc.activeLayer
var upLayerIDX = getSelectedLayersIdx ()
multiSelectByIDs (orgLayA[0][1])
var firstLayer = doc.activeLayer

if(upLayerIDX<lyrSelIDX[lyrSelIDX.length-1])
    {firstLayer.move (doc.layers[0], ElementPlacement.PLACEBEFORE)}
else 
    {firstLayer.move (topLayer, ElementPlacement.PLACEBEFORE)    }    

var lastLayer = doc.activeLayer
for(var i=1;i<orgLayA.length;i++){
    multiSelectByIDs (orgLayA[i][1]);
    nextLayer = doc.activeLayer;
    nextLayer.move (lastLayer, ElementPlacement.PLACEAFTER)
    lastLayer = doc.activeLayer
    }

    function hasBackground(){// function to check if there is a background layer
        var res = undefined;
        try{
            var ref = new ActionReference();
            ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID("Nm  "));
            ref.putIndex( charIDToTypeID("Lyr "), 0 );
            executeActionGet(ref).getString(charIDToTypeID("Nm  ") );
            res = true;
        }catch(e){ res = false}
        return res;
    }

//used in getSelectedLayersIds()
    function getSelectedLayersIdx(){// get the selected layers index( positon in layer editor)
         var selectedLayers = new Array;
         var ref = new ActionReference();
         ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
         var desc = executeActionGet(ref);
         var add = 1;
         if(hasBackground()){add = 0}
         if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
              desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
              var c = desc.count
              var selectedLayers = new Array();
              for(var i=0;i<c;i++){
                   selectedLayers.push(  (desc.getReference( i ).getIndex()) + add);
              }
         }else{
              var ref = new ActionReference();
              ref.putProperty( charIDToTypeID('Prpr') , charIDToTypeID( 'ItmI' ));
              ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              srs = hasBackground()?executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ))-1:executeActionGet(ref).getInteger(charIDToTypeID( 'ItmI' ));
              selectedLayers.push( srs);
         }
         return selectedLayers;
    }


function getLayerSetsData(layA)
{
    var lyrSetsList = []
    var lyrSets = [];
    
    for(i=0;i<layA.length;i++){
        var layerSets = layA[i]
       //var layerSets = 4

            ref = new ActionReference();
            ref.putIndex(charIDToTypeID('Lyr '), layerSets);
            var d1 = executeActionGet(ref)
            var c2t = function (s){return app.charIDToTypeID(s);};
            var s2t = function (s){return app.stringIDToTypeID(s);};
            var lyrSet = {};

            lyrSet.name = d1.getString(c2t("Nm  "));
            lyrSet.id = d1.getInteger(s2t("layerID"));
            
            lyrSetsList.push ([lyrSet.name,lyrSet.id])
    } 
    topLayerID = lyrSetsList[lyrSetsList.length -1][1]
    lyrSetsList.sort ()   
    return lyrSetsList
    

};
//=========
    function makeLayerActiveByLayerID(id){//is this needed?
        var desc = new ActionDescriptor();
            var ref = new ActionReference();
            ref.putIdentifier( charIDToTypeID( "Lyr " ), id );
        desc.putReference( charIDToTypeID( "null" ), ref );
        desc.putBoolean( charIDToTypeID( "MkVs" ), false );
    executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
    };

//used in multiSelectByIDs(ids)
    function doesIdExists( id ){// function to check if the id exists
       var res = true;
       var ref = new ActionReference();
       ref.putIdentifier(charIDToTypeID('Lyr '), id);
        try{var desc = executeActionGet(ref)}catch(err){res = false};
        return res;
    }

//uses doesIdExists(id)
    function multiSelectByIDs(ids) {
      if( ids.constructor != Array ) ids = [ ids ];
        var layers = new Array();
        var id54 = charIDToTypeID( "slct" );
        var desc12 = new ActionDescriptor();
        var id55 = charIDToTypeID( "null" );
        var ref9 = new ActionReference();
        for (var i = 0; i < ids.length; i++) {
           if(doesIdExists(ids[i]) == true){// a check to see if the id stil exists
               layers[i] = charIDToTypeID( "Lyr " );
               ref9.putIdentifier(layers[i], ids[i]);
           }
        }
        desc12.putReference( id55, ref9 );
        var id58 = charIDToTypeID( "MkVs" );
        desc12.putBoolean( id58, false );
        executeAction( id54, desc12, DialogModes.NO );
    }

//=======================
function moveUpLayer(){
     var idslct = charIDToTypeID( "slct" );
        var desc3 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idLyr = charIDToTypeID( "Lyr " );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrwr = charIDToTypeID( "Frwr" );
            ref1.putEnumerated( idLyr, idOrdn, idFrwr );
        desc3.putReference( idnull, ref1 );
        var idMkVs = charIDToTypeID( "MkVs" );
        desc3.putBoolean( idMkVs, false );
        var idLyrI = charIDToTypeID( "LyrI" );
            var list1 = new ActionList();
            list1.putInteger( 3 );
        desc3.putList( idLyrI, list1 );
    executeAction( idslct, desc3, DialogModes.NO );   
    }

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 09, 2022 Oct 09, 2022

Copy link to clipboard

Copied

You rock Chuck! I'll give it a try tomorrow and post back. Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Oct 20, 2022 Oct 20, 2022

Copy link to clipboard

Copied

Just wanted to say this script works perfectly, thank you so much!!

I was just trying to use the ones from the older thread mentioned earlier and was getting the same error as OP (on PS 23.3.1), since that thread was so old I wasn't sure if it would be possible to find one that worked. This made my day!!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 20, 2022 Oct 20, 2022

Copy link to clipboard

Copied

LATEST

Glad it's working for you, as well.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines