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

How to pass a variable from js to jsx?

Explorer ,
Aug 04, 2018 Aug 04, 2018

Copy link to clipboard

Copied

Good day dear audience!

Sorry for my bad English. I ask for help in writing a script for the extension panel.

There is a script button and a slider:

<button class="tool" id="gb_3b"><div class="inst">Start</div></button>

<b>Middle radius: <span style="font-size: 1.2em" id="gb3rval"></span></b>

<div id="gblur3rad"></div>

Running the script and initializing the slider in JS:

$("#gb_3b").button().click(function(a) {

    csInterface.evalScript('$._ext.evalFile("' + extensionRoot + 'work/Smart_Frequency_3_Band_GB.jsxbin")')

});

$(function() {

            $('#gblur3rad').slider({   

                min: 0.1,

                max: 20,

                step: 0.1,

                value: 5,

                create: setInputsFromSlider1,

                slide: setInputsFromSlider1,

                stop: setInputsFromSlider3

            });           

            function setInputsFromSlider1() {

                $('#gb3rval').text($('#gblur3rad').slider("value"));

            };

            function setInputsFromSlider3() {

                var radius = $('#gblur3rad').slider("value");

                csInterface.evalScript('GBlur3S("'+radius+'")', function() {csInterface.evalScript('GBlur3S2("'+radius+'")');});

            };

};

main.jsx which is specified in the manifest:

function GBlur3S(radius) {

   

var idslct = charIDToTypeID( "slct" );

    var desc16 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref5 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        ref5.putName( idLyr, "Base Middle GB" );

    desc16.putReference( idnull, ref5 );

    var idMkVs = charIDToTypeID( "MkVs" );

    desc16.putBoolean( idMkVs, false );

    var idLyrI = charIDToTypeID( "LyrI" );

        var list3 = new ActionList();

        list3.putInteger( 3 );

    desc16.putList( idLyrI, list3 );

executeAction( idslct, desc16, DialogModes.NO );

var idsetd = charIDToTypeID( "setd" );

    var desc34236 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref236 = new ActionReference();

        var idfilterFX = stringIDToTypeID( "filterFX" );

        ref236.putIndex( idfilterFX, 1 );

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref236.putEnumerated( idLyr, idOrdn, idTrgt );

    desc34236.putReference( idnull, ref236 );

    var idfilterFX = stringIDToTypeID( "filterFX" );

        var desc34237 = new ActionDescriptor();

        var idFltr = charIDToTypeID( "Fltr" );

            var desc34238 = new ActionDescriptor();

            var idRds = charIDToTypeID( "Rds " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc34238.putUnitDouble( idRds, idPxl, radius );

        var idGsnB = charIDToTypeID( "GsnB" );

        desc34237.putObject( idFltr, idGsnB, desc34238 );

    var idfilterFX = stringIDToTypeID( "filterFX" );

    desc34236.putObject( idfilterFX, idfilterFX, desc34237 );

executeAction( idsetd, desc34236, DialogModes.NO );

};

function GBlur3S2(radius) {

   

var idslct = charIDToTypeID( "slct" );

    var desc16 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref5 = new ActionReference();

        var idLyr = charIDToTypeID( "Lyr " );

        ref5.putName( idLyr, "Base Middle GB (H)" );

    desc16.putReference( idnull, ref5 );

    var idMkVs = charIDToTypeID( "MkVs" );

    desc16.putBoolean( idMkVs, false );

    var idLyrI = charIDToTypeID( "LyrI" );

        var list3 = new ActionList();

        list3.putInteger( 3 );

    desc16.putList( idLyrI, list3 );

executeAction( idslct, desc16, DialogModes.NO );

var idsetd = charIDToTypeID( "setd" );

    var desc34236 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref236 = new ActionReference();

        var idfilterFX = stringIDToTypeID( "filterFX" );

        ref236.putIndex( idfilterFX, 1 );

        var idLyr = charIDToTypeID( "Lyr " );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref236.putEnumerated( idLyr, idOrdn, idTrgt );

    desc34236.putReference( idnull, ref236 );

    var idfilterFX = stringIDToTypeID( "filterFX" );

        var desc34237 = new ActionDescriptor();

        var idFltr = charIDToTypeID( "Fltr" );

            var desc34238 = new ActionDescriptor();

            var idRds = charIDToTypeID( "Rds " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc34238.putUnitDouble( idRds, idPxl, radius );

        var idGsnB = charIDToTypeID( "GsnB" );

        desc34237.putObject( idFltr, idGsnB, desc34238 );

    var idfilterFX = stringIDToTypeID( "filterFX" );

    desc34236.putObject( idfilterFX, idfilterFX, desc34237 );

executeAction( idsetd, desc34236, DialogModes.NO );

};

After executing the script 2 smart layers with blur are formed. When you move the slider, the blur radius changes simultaneously in both layers.

Until then, everything works. But I would like to make it possible to set the value of the radius slider and this value was transferred to the external JSX.

Here is the part of JSX code where you need to insert a variable from JS:

//

// SmartFrequency3_BandGB.jsx

//

//

// Generated Thu Aug 02 2018 01:02:07 GMT+0300

//

cTID = function(s) { return app.charIDToTypeID(s); };

sTID = function(s) { return app.stringIDToTypeID(s); };

//

//==================== Smart Frequency 3-Band GB ==============

//

function SmartFrequency3_BandGB() {

  function step1(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    var desc1 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putProperty(cTID('Prpr'), cTID('CchP'));

    ref1.putEnumerated(cTID('capp'), cTID('Ordn'), cTID('Trgt'));

    desc1.putReference(cTID('null'), ref1);

    var desc2 = new ActionDescriptor();

    desc2.putInteger(cTID('HsSt'), 1);

    desc1.putObject(cTID('T   '), cTID('CchP'), desc2);

    executeAction(sTID('set'), desc1, dialogMode);

  };

// code

   function step21(enabled, withDialog) {

    if (enabled != undefined && !enabled)

      return;

    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);

    var desc1 = new ActionDescriptor();

    desc1.putUnitDouble(cTID('Rds '), cTID('#Pxl'), radius);

    executeAction(sTID('gaussianBlur'), desc1, dialogMode);

  };

  step1();

// code

  step21();

};

//=========================================

//                    SmartFrequency3_BandGB.main

//=========================================

//

SmartFrequency3_BandGB.main = function () {

  SmartFrequency3_BandGB();

};

SmartFrequency3_BandGB.main();

// EOF

"SmartFrequency3_BandGB.jsx"

// EOF

How to pass "radius" variable from JS to JSX?

Views

3.4K

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

People's Champ , Aug 16, 2018 Aug 16, 2018

Я тоже тупой. В расширениях вообще не шарю)).

Но мне попалось одно демо-расширение.

Там был такой код на кнопку. в js-файле.

$("#rgb_c").button().click(function(a)  { csInterface.evalScript('$._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});

Я изменил его на вот такой.

$("#rgb_c").button().click(function(a)  { csInterface.evalScript('var xxx= 1; $._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});

В файле RGB.jsx воткнул такой код

alert(xxx)

Запустил фотошоп, нажал кнопку, получил правильный алерт

...

Votes

Translate

Translate
Explorer ,
Aug 10, 2018 Aug 10, 2018

Copy link to clipboard

Copied

Is that impossible? Or is my English so bad?

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
People's Champ ,
Aug 11, 2018 Aug 11, 2018

Copy link to clipboard

Copied

I do not use and do not understand anything in extensions. But try to use the search.
For example, maybe this will help

Re: How to pass information between JS Extension and JSX host

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
Advocate ,
Aug 11, 2018 Aug 11, 2018

Copy link to clipboard

Copied

Do I understand it correctly that the .js file is web browser JavaScript?

If so, I don't see why it should not be possible to pass the radius variable to the .jsx (which is Photoshop JavaScript) as an argument when you call the .jsx file.

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
Valorous Hero ,
Aug 11, 2018 Aug 11, 2018

Copy link to clipboard

Copied

You must have a function in JSX which accepts an argument.

JS:

$("#TEST").click(function(){

    var str = "Hello World";

    var myString = "runMyScript('" + str + "')";

    csInterface.evalScript(myString);

});

JSX:

function runMyScript(message){

    alert(message);

};

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
Explorer ,
Aug 12, 2018 Aug 12, 2018

Copy link to clipboard

Copied

Yes. In the example above, I did just that. And it works. The question was a bit different. How to pass a variable to any other path, not to the JSX path that is written in the manifest file.

I have a lot of JSX in the extension. Here is an example of how they are called from JS:

$("#TEST").button().click(function(a) {

    csInterface.evalScript('$._ext.evalFile("' + extensionRoot + 'jsx/test.jsx")')

});

Due to poor knowledge of scripts I can not understand how to pass a variable in such JSX

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
Valorous Hero ,
Aug 12, 2018 Aug 12, 2018

Copy link to clipboard

Copied

Oh, I see. What if you try this:

Just have your main JSX function that you pass in data into from the JS.

Except, this time, pass in your jsx path to the final jsx script you wish to run as well as the variables you with to send.

In fact, use not the evalFile but use the evalScript.

Then in your JSX that is described in the manifest that is being called, you have one 'distribution' function which reads in the target jsx path via eval and uses other pieces of your data to do things like choose which function to run and the arguments to that function.

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
Explorer ,
Aug 14, 2018 Aug 14, 2018

Copy link to clipboard

Copied

Thanks. But I know too little scripts to understand how to do it.

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
Valorous Hero ,
Aug 14, 2018 Aug 14, 2018

Copy link to clipboard

Copied

Let's pretend you have lots of jsx files, among which one is your host script:
jsx/host_script.jsx
jsx/function_1.jsx

jsx/function_2.jsx

jsx/function_3.jsx

Inside each one which is not the host_script.jsx you may have a series of functions like this:

function func_1a( inStr ){

    alert(func_1a.name + "(): " + inStr);

}

function func_1b( inStr ){

    alert(func_1b.name + "(): " + inStr);

}

You'd need an object to serve as the data-holder as well as the instructions for who will do work on this data:

var instructionObj = {

    scriptToRun : "function_1.jsx",

    functionToRun : "func_1a",

    inStr : "HEY!"

}

And in your main jsx file, the host_script.jsx you may have a controlling function whose job will be to take your CEP-js data and relay it to its proper destination:

function runMyJsx( instructionObj ){ // are these auto-parsed from JSON into objects? I don't remember..

  // setting the vars up for clarity

  var scriptToRun = instructionObj.scriptToRun; // "function_1.jsx"

  var functionToRun = instructionObj.functionToRun; // "func_1a"

  var inStr = instructionObj.inStr; // "HEY!"

  // if the 'script to run' isn't already included in the host_script.jsx via '#include function_1.jsx' then bring it in.

  // here's a way without doing a file.read(): https://forums.adobe.com/thread/2412769

  eval("#include " + scriptToRun); // now it theoretically should be available for use- let me know how it goes?

  // time to release the hounds!

  eval(functionToRun + "(" + inStr.toSource() + ")"); // func_1 : HEY!

}

Of course then you'd call your JS function with an evalScript("runMyJsx('" + JSON.stringify(instructionObj) + "')");

So there you have it, dynamic choice of an individual jsx file, a function from that file and a piece of data that is meant for that function.

I have not tested any of this with actual CEP, would like to see results either way.

Good luck! I hope this ends up working for you!

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
Explorer ,
Aug 15, 2018 Aug 15, 2018

Copy link to clipboard

Copied

I tried to do exactly as you have written. Created a separate file function_1.jsx. Which contains a single function

function func_1a( inStr ){ 

alert(func_1a.name + "(): " + inStr); 

}

In HTML add a button for this JSX

<button class="test" id="myFunct">TEST</button>

In JS wrote so

$("#myFunct").button().click(function(a) {

    var instructionObj = { 

        scriptToRun : "function_1.jsx", 

        functionToRun : "func_1a", 

        inStr : "HEY!" 

    };

    csInterface.evalScript("runMyJsx('" + JSON.stringify(instructionObj) + "')");

});

And in main jsx file main.jsx wrote so

function runMyJsx( instructionObj ){

var scriptToRun = instructionObj.scriptToRun;

  var functionToRun = instructionObj.functionToRun;

  var inStr = instructionObj.inStr;

  eval("#include " + scriptToRun);

  eval(functionToRun + "(" + inStr.toSource() + ")");

}

And nothing happens when you press the button TEST

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
Valorous Hero ,
Aug 15, 2018 Aug 15, 2018

Copy link to clipboard

Copied

Sorry, it does appear that the JSON object passed in is not auto-parsed  - maybe it was vice-versa when data goes back to the JS and I did forget.

So, now make sure to have the JSON code inside of your host script.

"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function quote(t){

  return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta;

    return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}

  function str(t,e){var n,r,o,f,u,i=gap,p=e;switch(p&&"object"==typeof p&&"function"==typeof p.toJSON&&(p=p.toJSON(t)),

    "function"==typeof rep&&(p=rep.call(e,t,p)),typeof p){case"string":return quote(p);case"number":return isFinite(p)?String(p):"null";

  case"boolean":case"null":return String(p);case"object":if(!p)return"null";if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(p)){

    for(f=p.length,n=0;f>n;n+=1)u=str(n,p)||"null";return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+i+"]":"["+u.join(",")+"]",gap=i,o}

      if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep&&(r=rep,o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));

    else for(r in p)Object.prototype.hasOwnProperty.call(p,r)&&(o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));return o=0===u.length?"{}":gap?"{\n"+gap+

    u.join(",\n"+gap)+"\n"+i+"}":"{"+u.join(",")+"}",gap=i,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){

      return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+

      f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){

        return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&

    (escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,

      meta={"\b":"\\b","  ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,n){var r;

        if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" ";else"string"==typeof n&&(indent=n);if(rep=e,

          e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),

    "function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,

      JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t;if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&

      (r=walk(o,n),void 0!==r?o=r:delete o);return reviver.call(t,e,o)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&&

        (text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),

        /^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@")

          .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]")

          .replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;

      throw new SyntaxError("JSON.parse")})}();

Then make sure to add this line into the runMyJsx function:

function runMyJsx( instructionObj ){  

instructionObj = JSON.parse(instructionObj);

...

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
Explorer ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

Thank you very much for your help. But I guess I'm too stupid. When I included the presented code in my host script, all other buttons in the panel stopped working.

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
People's Champ ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

Я тоже тупой. В расширениях вообще не шарю)).

Но мне попалось одно демо-расширение.

Там был такой код на кнопку. в js-файле.

$("#rgb_c").button().click(function(a)  { csInterface.evalScript('$._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});

Я изменил его на вот такой.

$("#rgb_c").button().click(function(a)  { csInterface.evalScript('var xxx= 1; $._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});

В файле RGB.jsx воткнул такой код

alert(xxx)

Запустил фотошоп, нажал кнопку, получил правильный алерт ))

Может это как раз то, что надо?

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
Explorer ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

This is the standard code to run the script with a button in the extension. I have all the JSX is and start. And what you offered was something I couldn't think of myself. Everything genius is simple! Thank you very much! That's exactly what I needed. Everything worked fine.

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
Valorous Hero ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

Wow that's even easier!

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
Explorer ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

LATEST

I must be really stupid. What you offered worked perfectly. But there is one unclear point.

There is such here is code

$(function() {

            $('#gblur3rad').slider({  

                min: 0.1,

                max: 20,

                step: 0.1,

                value: 5,

                create: setInputsFromSlider11,

                slide: setInputsFromSlider11,

                stop: setInputsFromSlider13

            })

          

            function setInputsFromSlider11() {

                $('#gb3rval').text($('#gblur3rad').slider("value"));

            }

            function setInputsFromSlider13() {

                var radius = $('#gblur3rad').slider("value");

                csInterface.evalScript('GBlur3S("'+radius+'")', function() {csInterface.evalScript('GBlur3S2("'+radius+'")');});

            }

              $("#gb_3b").button().click(function(a) {

                  var rds = $('#gblur3rad').slider("value");

              csInterface.evalScript('var rad = "rds"; $._ext.evalFile("' + extensionRoot + 'work/Smart_Frequency_3_Band_GB.jsx")')

              });

});

If I set the rad variable to a numeric value, everything works fine. But how can I instead of a number to substitute the variable there rds? In such look as it is written down at me var rad = "rds", it does not work. Requires a numeric value. Requires a numeric value.

P.S. I'm really stupid ))) var rad = " '+rds+' " and it worked.

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 ,
Aug 16, 2018 Aug 16, 2018

Copy link to clipboard

Copied

This thread moved from Photoshop Scripting to Extensions / Add-ons Development.

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