Can i run javascript.jsx file using UXP button

can i run javascript.jsx file using UXP button

1 Like

as far as I know there’s no direct way of running JSX atm, but you can use batchplay to do so

JAVASCRIPT

const app = require("photoshop").app;
const batchPlay = require("photoshop").action.batchPlay;
async function ScriptRun(jsxFile) {
   let pluginFolder = await fs.getPluginFolder()
   try {
      let jsxFileObject = await pluginFolder.getEntry(jsxFile);
      var filetoken = await fs.createSessionToken(jsxFileObject);
   } catch (e) {
      app.showAlert("File Can't be found!");
   }
   return await batchPlay(
      [
         {
            "_obj": "AdobeScriptAutomation Scripts",
            "javaScript": {
               "_path": filetoken,
               "_kind": "local"
            },
            "javaScriptMessage": "JSM",
            "_isCommand": true,
            "_options": {

               "dialogOptions": "dontDisplay"

            }
         }
      ], {
      "synchronousExecution": false,
      "modalBehavior": "fail"
   });

}

FUNCTION CALL

ScriptRun("jsx/myScript.jsx")

where the file myScript.jsx is located inside a directory called jsx in the plugin folder

credits to @DavideBarranca

also if I may suggest using the following way to bind the event your script runners (buttons), since in my case I use the function on a lot of buttons.

HTML

<button class="sr" sr-path="jsx/script1.jsx">Script 1</button>
<button class="sr" sr-path="jsx/script2.jsx">Script 2</button>
...

and to bind all of them I use the “sr” class and the path from “sr-path” attribute like so:

JAVASCRIPT

Array.from(document.querySelectorAll(".sr")).forEach(sr => {
   sr.onclick = (e) => {
      ScriptRun(e.target.getAttribute("sr-path"))
   }
});
3 Likes

:red_circle: Do not do this if you plan on distributing your plugin to others. There is no guarantee that plugins that run JSX like this will continue to work in the future, and your plugin may be removed from the marketplace.

Convert to batchPlay and the PS DOM API instead.

Thanks
I am not familiar with modern java.
this UXP only using my works.
my old javascript are working good and I cannot re create to UXP
that is why Iam asking how to connect java script to uxp. I will try this.
Thanks for the advise.

UXP uses JavaScript just like JSX Scripts but you’ll have to relearn some stuff but the concept is the same. I recommend you port your code while you have the time since JSX is deprecated and they might stop supporting it in the future.
this is a good place to start

1 Like

Thanks for the advice.

Does this still work, i have a collection of jsx scripts which were made in 2018 - 2019 before UXP were anounced and these cannot be remade with the new system. I think its very important for the old system to be retained somehow. Many small businesses cannot afford the time or expense to remake workflow assets.
Its not like we can just not update photoshop anymore with the subscription system what it is.

I’ve tried to use the above code in a UXP panel to run an old JSX script but nothing happens

It still works. However, why not just run the scripts without UXP? If the jsx scripts themselves stop working then so would this method of running the script through UXP anyway. So I guess I’m not sure what the benefit would be by running the JSX through UXP.

I have 30 or so scripts which also have scriptUI interfaces so want to run them from a panel. I understand this will not be a forever solution but in the meantime I have work to do that requires them.

Can someone please explain how to use the code above, I’ve tried everything I can think of but the buttons I make in index.html in my UXP panel won’t launch a jsx script.

Thanks

I’m using this code to get a button to fire a JSX script that’s in the plugin folder inside a JSX folder

async function ScriptRun(jsxFile) {

   let pluginFolder = await fs.getPluginFolder()

   try {
      let jsxFileObject = await pluginFolder.getEntry(jsxFile);
      var filetoken = await fs.createSessionToken(jsxFileObject);
   } catch (e) {
      app.showAlert("Script does not exist");
   }
   return await batchPlay(
      [
         {
            "_obj": "AdobeScriptAutomation Scripts",
            "javaScript": {
               "_path": filetoken,
               "_kind": "local"
            },
            "javaScriptMessage": "JSM",
            "_isCommand": true,
            "_options": {
               "dialogOptions": "dontDisplay"
            }
         }
      ], {
      "synchronousExecution": false,
      "modalBehavior": "fail"
   });
}

document.querySelector("#button").addEventListener("click", scriptSelector);

async function scriptSelector() {

   var script = "jsx/scriptName.js" // <--- point this to your script

   await ScriptRun(script)

}
3 Likes

I assume all that goes into index.js
What goes into the html file to trigger the javascript?
I tried this but it doesn’t work
<button class="sr" sr-path="jsx/script2.jsx">Script 2</button>

just make a button and give it an id

<sp-action-button id="button">Button Name</sp-action-button>

Still doesn’t work, i don’t understand what im doing wrong.

I’ve tried it with old jsx files scripts that do and don’t have a scriptUI. Does it work with either for you?

Add this to your index.js

const app = window.require("photoshop").app;
const { entrypoints } = require("uxp");
const batchPlay = require("photoshop").action.batchPlay;
const fs = require("uxp").storage.localFileSystem;

async function ScriptRun(jsxFile) {

   let pluginFolder = await fs.getPluginFolder()

   try {
      let jsxFileObject = await pluginFolder.getEntry(jsxFile);
      var filetoken = await fs.createSessionToken(jsxFileObject);
   } catch (e) {
      app.showAlert("Script does not exist");
   }
   return await batchPlay(
      [
         {
            "_obj": "AdobeScriptAutomation Scripts",
            "javaScript": {
               "_path": filetoken,
               "_kind": "local"
            },
            "javaScriptMessage": "JSM",
            "_isCommand": true,
            "_options": {
               "dialogOptions": "dontDisplay"
            }
         }
      ], {
      "synchronousExecution": false,
      "modalBehavior": "fail"
   });
}

document.querySelector("#button").addEventListener("click", scriptSelector);

async function scriptSelector() {

   var script = "jsx/script1.jsx" 

   await ScriptRun(script)
}

add this to your HTML

<sp-action-button id="button">Button Name</sp-action-button>

Inside the plugin folder make a folder called jsx. Put your scripts inside that. Currently the above code is expecting a script to be call “script1.jsx”

The above is not the most efficient way to make the code run, Maher has a better solution but the above is reasonably simple to see how it works.

can I somehow pass the arguments to jsx script through uxp?

1 Like

Why is it i cannot use the same button id on another button?

I have a tabbed panel and want a tab that has all the buttons on it which are smaller and have less info in the name. However, if i try to assign the same button id the script won’t trigger on the second button. If i remove the first button the script triggers.

An id is supposed to have unique occurrence

That’s how it is

The id global attribute defines an identifier (ID) which must be unique in the whole document.

BatchPlay can handle layer comps. But it is not so easy to work with it with low-level code.

Unfortunately it does not work anymore for DOM API Version 2. What do I have to change to make it work with DOM API Version 2?