Copy link to clipboard
Copied
Hi everybody
I have a file with a lot of texts..
I want to search for a word within the texts and choose
a textlayer to edit it by edittext or prompt Dialog ..
I tried Find and replace text, but I found it to be useless
Is there a way to do this ??
Could be more elegant, but does this help? (edited the code)
// select type layers with certain text;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
selectTypeLayersWithText ("123")
};
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(
...
var p = prompt ("type any word here", "");
if (app.documents.length > 0) {
selectTypeLayersWithText (p)
};
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// proc
...
Copy link to clipboard
Copied
What is "a lot of texts.." what is "texts.." A single text layer with a lot of text. Is is Paragraph text bounded to an Area. Is it many text layers a mixture of text layer kinds. A mixture of fonts and text sizes. Text is very complicated. It sounds like you want to find and replace text. Will the text you want to find be unique in the document or can there be several occurrences of the text you want to find and prompt with. How would you want to handle the reply from a prompt. You need to the know what you want to do and design a process that can accomplish what you want to do. Text is complex to edit particularly if you want to add more text characters. Will the added characters visibly fit in etc. You are finding that text is very complex. I would think that Find and Replace Text should work if you are not adding more text. Replacing and reducing text should work if the text you are editing is unique in the document.
Copy link to clipboard
Copied
- First, thank you JJMack
I mean that I have a file or design with many layers of text and each text layer contains sentences with many words
- I already tried Find and replce text and it searches, but when I click on Done, it does not specify the layer in which the searched word is located
- I hope you understand me
- I have attached an explanatory file to a file with many texts and with it the psd file, and I want you to search for any word within the text layers and see what happens when you click on Done
This image is for clarification
Copy link to clipboard
Copied
That image half explains things...
So after your script runs, what are you expecting? A dialog to pop-up with a list of layers that contain the word that was used for the find/search? Only the layers in the layers panel selected that contain the word? Something else?
Copy link to clipboard
Copied
That image for explains I need script search with all text array for input word on edittext and search for all text on files and select textlayer contain edittext word
Copy link to clipboard
Copied
Find and Replace Text replaces Text it is not a Layer(s) selection tool. What exactly are you trying to do. If it is select text layer that contain some text. You may need to create a script that create an array of the document text layer object then be able to parse the text layer content to create an array of layer objects that contain the text. Then select the layers in that array. You need to process all the text layer in the document and create the list of layers to target.
Copy link to clipboard
Copied
Yes I need to create a script that create an array of the document text layer object then be able to parse the text layer content to create an array of layer objects that contain the text. Then select the layers in that array. You need to process all the text layer in the document and create the list of layers to target.
How can I do it
Copy link to clipboard
Copied
Could be more elegant, but does this help? (edited the code)
// select type layers with certain text;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
selectTypeLayersWithText ("123")
};
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theText = textDesc.getString(stringIDToTypeID('textKey'));
if (theText.indexOf(theString) != -1) {
selectLayerByID(theID,theAdd);
theAdd = true;
theLayers.push([theName, theID, theText])
};
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
Copy link to clipboard
Copied
c.pfaffenbichler
I ran the code and it didn't show any results
Copy link to clipboard
Copied
How may text layer that have 123 in them were not targeted? All layer with 123 were targeted in my test. I was just a simple test with no laysets and all layer visible.
adding that complexity did not change the resilts.
Copy link to clipboard
Copied
thank you JJMack
Copy link to clipboard
Copied
c.pfaffenbichler, JJMack This is exactly what I was looking for..
Copy link to clipboard
Copied
Try this. If the text is not found the current targeted layers will not be change. It is case sensitive.
// select type layers with certain text;
// 2021, use it at your own risk;
if (app.documents.length > 0) {
selectTypeLayersWithText (prompt("What text do you want to find?",""));
};
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theText = textDesc.getString(stringIDToTypeID('textKey'));
if (theText.indexOf(theString) != -1) {
selectLayerByID(theID,theAdd);
theAdd = true;
theLayers.push([theName, theID, theText])
};
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}
catch(e){alert(e.message); }
};
Copy link to clipboard
Copied
I've already done this
thank you JJMack
I want you to know that the programming language has many secrets and many skills
Everything has solutions, but I see that you are analyzing things on the one hand that it is a complicated thing, while there are those who solve it easily
Copy link to clipboard
Copied
For me to solve it easily I would need know Javascript and Action Manager coding and be able to type. So often I can analyze problems but coding a solution is a problem for me. Particular hard for I can not type so entering the code for me is labor intensive. Users abilities vary. Still I feel my key pecking helps around here.
Everything does not haves a solution however, it may have an end. To prove me wrong prevent your death you will end.
Copy link to clipboard
Copied
Thank you c.pfaffenbichler
, I modified it and added an edittext to put the value
to be searched for and the final experiment is underway
Copy link to clipboard
Copied
The find can not handle spaces you can't find a phrase using prompt
theText.indexOf(theString) != -1
found my problem
selectTypeLayersWithText (prompt("What text do you want to find?","").toString());
Copy link to clipboard
Copied
I modified it and added an edittext to put the value
By @Mohamed Hameed
You could post your code so that others may benefit, just as you benefited from others posting code for you to build on.
Copy link to clipboard
Copied
var p = prompt ("type any word here", "");
if (app.documents.length > 0) {
selectTypeLayersWithText (p)
};
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theText = textDesc.getString(stringIDToTypeID('textKey'));
if (theText.indexOf(theString) != -1) {
selectLayerByID(theID,theAdd);
theAdd = true;
theLayers.push([theName, theID, theText])
};
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
Copy link to clipboard
Copied
Thank you for sharing.
Your code is using a "prompt" – not "edittext".
When you mentioned that you added "edittext" I was mistakenly under the impression that you had added a scriptUI interface, but that is not the case, it is just using a standard system interface.
Copy link to clipboard
Copied
If you need edittext ok I will edit code and post it again
Copy link to clipboard
Copied
No need to go to any trouble on my behalf, a prompt does the job, I was asking for you to share the "extra value" that I presumed was there.
Copy link to clipboard
Copied
dlg = new Window("dialog"); dlg.text = "Search for any Textlayer By any Word";
dlg.preferredSize = [300, 100];
var MH= dlg.add("edittext", [0,0,500,35], "", ); MH.active=true;
MH.graphics.font = ScriptUI.newFont ("Arial", "Bold", 15);
Add=dlg.add("button", undefined, "Search" );
Add.onClick = function () {
if (app.documents.length > 0) {
selectTypeLayersWithText (MH.text)
dlg.close()
};
}
////////////////////////////////////
function selectTypeLayersWithText (theString) {
var theAdd = false;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theText = textDesc.getString(stringIDToTypeID('textKey'));
if (theText.indexOf(theString) != -1) {
selectLayerByID(theID,theAdd);
theAdd = true;
theLayers.push([theName, theID, theText])
};
};
}
catch (e) {};
};
return theLayers
};
// based on code by mike hale, via paul riggott;
function selectLayerByID(id,add){
add = undefined ? add = false:add
var ref = new ActionReference();
ref.putIdentifier(charIDToTypeID("Lyr "), id);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref );
if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) );
desc.putBoolean( charIDToTypeID( "MkVs" ), false );
try{
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message);
}
};
dlg.show();
Copy link to clipboard
Copied
@Mohamed Hameed – Thank you for sharing your code and giving back to the community.