Illustrator CEP Panel: How to pass objects/data from a form to JSX?

New Here ,
Jan 15, 2021 Jan 15, 2021

Copy link to clipboard

Copied

In short: what is the minimum required programming that needs including in you CEP package to pass information from your HTML to your JSX?

 

Being very new to scripting in general I feel a bit dense when trying to reference the CEP documentation, or even the sample excerpt from Davide Barranca's work on HTML panels. Fighting syntax to get scripts to work as needed in Illustrator has been one thing, but trying to implement that work in an HTML panel has been frustrating. Getting buttons to run the JSX files I have created was one thing, but I cannot seem to figure out how to get user input data from an html form to be passed over to the functions in my JSX.

 

It seems like there are a LOT of different ways I could approach it, but to be honest I am looking for the simplest as I am learning as I go. If anyone could suggest what a simple, novice programmer might pursue to find a solution I'd really appreciate it.

HTML SAMPLE: 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Awful Little Panel</title>
		<script src="./lib/CSInterface.js"></script>		
	</head>
	<body>
        <script type="text/javascript">
            let myIntValue = form.elements.myInt;

            function nameThatFont() {
            var cs = new CSInterface;
            cs.evalScript('$.runThoseScripts.runNameThatFont()')
			};
			
			function giveThatValue() {
            var cs = new CSInterface;
            cs.evalScript('$.runThoseScripts.takeThatValue()')
            };
        </script>
        <form id="myForm" onsubmit="return false">
            <h1>Sad Little Panel</h1>
            <label for="myInt">Input Number:</label><br><input type="number" name="myInt" placeholder="0.05" step="0.01" value="0.05" required><br>
            <input type="submit" value="Submit" onclick="giveThatValue();"> <input type="reset"> <br>
            <button id="runNameThatFont" type="run" title="Type the font you want to use, output is the actual font name." onclick="nameThatFont()">What's my font?</button><br>
        </form>
    </body>
</html>


JSX SAMPLE:

$.runThoseScripts = {
    runNameThatFont: function() {
        // type in the document using the font you'd like the name of, then run...
        var trueName = app.activeDocument.textFrames[0].textRange; 
        trueName.contents = trueName.characterAttributes.textFont;
    },
    takeThatValue: function() {
        // let's see that Int!
        try {
            alert('The value from the form is... ' + myIntValue + '!');
        } catch (dumbError) {
            alert('You didn\'t do it right! :(');
        }
    }
}

The manifest seems configured properly and the only lib file I've included is CSInterface.js. 

TOPICS
How to, Scripting

Views

147

Likes

translate

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

Engaged , Jan 15, 2021 Jan 15, 2021
On second thought, I should clarify if you're truly an absolute beginner and self-teaching through scripting / CEP (which is what I did and many others). JSON is the "proper" way to send data but only if it isn't a basic string. If you need to send a simple string, you probably don't need to worry about JSON at all:CEP: let myInt = form.elements.myInt // If this is the HTML element let myIntValue = myInt.value // Then this would be the value, like "16" function nameThatFont() { var cs = new C...

Likes

translate

Translate

Translate
Engaged ,
Jan 15, 2021 Jan 15, 2021

Copy link to clipboard

Copied

You need to use JSON between each (CEP and JSX), so you can run this script as a JSX file before your main script (or in the same file at the very top) to have access to a JSON object in scripting. You don't need to do this in the HTML/CEP side because JSON is web standard. JSON is basically a way to write Javascript so you can save an object as a file, but we can't pass anything except a string from CEP > JSX > CEP (or many other mediums in JS programming), so to get around this we have to convert it to a string (stringify) then convert it back to an object (parse) once the data is in the environment we need it to be.

 

From CEP:

 

// THIS IS HTML / CEP
function nameThatFont() {
  var cs = new CSInterface();
  var someData = {
    hello: 'world'
  }
  var someJSONString = JSON.stringify(someData)
  cs.evalScript(`someFunction('${someJSONString}')`) // note these are template literal strings
  // or:
  // cs.evalScript('someFunction("' + someJSONString + '")')
};

 

To JSX:

 

// JSX (but only when JSON2.js has been loaded before or exists above this function)
function someFunction(data) {
  data = JSON.parse(data) // The data is no longer a string. It's back to a normal Javascript object.
  alert(data.hello) // Returns 'world'

  // We can also send messages back to HTML from JSX this way
  return JSON.stringify({
    foo: "bar"
  })
}

 

Back to CEP:

 

// HTML / CEP
cs.evalScript(`someFunction('${someJSONString}')`, function(response) {
  var data = JSON.parse(response);
  console.log(data.foo) // Returns "bar"
}) 

 

Likes

translate

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
Engaged ,
Jan 15, 2021 Jan 15, 2021

Copy link to clipboard

Copied

On second thought, I should clarify if you're truly an absolute beginner and self-teaching through scripting / CEP (which is what I did and many others). JSON is the "proper" way to send data but only if it isn't a basic string. If you need to send a simple string, you probably don't need to worry about JSON at all:

CEP:

 

let myInt = form.elements.myInt // If this is the HTML element
let myIntValue = myInt.value // Then this would be the value, like "16"

function nameThatFont() {
  var cs = new CSInterface();
  cs.evalScript('someFunction("' + myIntValue + '")')
};

 

 

JSX:

 

// JSX
function someFunction(value) {
  alert(value);
  var valueAsNumberNotString = +value // I add a plus sign to a string to convert it to a number
  return valueAsNumberNotString + 5; 
  // return value + 5 // Otherwise this might return "165" ("16" + "5" == "165") instead of "21"
}

 

 

Back to CEP: 

 

// CEP:
function nameThatFont() {
  var cs = new CSInterface();
  cs.evalScript('someFunction("' + myIntValue + '")', function(response) {
    console.log(response) // Should log "21"
  })
};

 

 

 You'd want to use JSON if you have to send something complex like an object or an array, or a lot of data all at once. For a simple string the above should work iirc.

 

I'm not sure what you're doing with the $.runThisScript.functionName syntax. It's not needed -- you don't need to extend the $ object to do scripting or do anything like JQuery syntax or put your functions in objects, I'd probably advise against doing it because $ is a global and native scripting object. I suppose it doesn't hurt for Illustrator because scripts are scoped to each CEP instance, but if you did that in After Effects or Photoshop then you could be extending the $ for any other script or CEP panel that exists in the app and subsequently could cause other scripts to break (assuming they run a for...in loop on the $ object and invoke a function that doesn't exist, which is a weird bug that happens when you extend native prototypes in Adobe scripting).

Likes

translate

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
New Here ,
Jan 15, 2021 Jan 15, 2021

Copy link to clipboard

Copied

Thank you so much for the tremendous insight! I'll be giving this a go and start trying to wrap my brain around utilizing JSON.

 

As far as using the global object, I honestly can't say I had a good reason for using it (read: I had no idea what it was actually for, ha ha). You've saved me a lot of headache I think for when I start branching out to the other programs! Thank you again. 🙂

Likes

translate

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
Engaged ,
Jan 15, 2021 Jan 15, 2021

Copy link to clipboard

Copied

No problem! CEP questions are a bit rare around here but there are plenty of devs here who can help. If you have issues, replying to me here will send me an email and I can clarify.

 

Yeah I'd recommend avoiding if you can, lol. It won't be so much of a headache for you, but I've had instances where I've included it in a new Battleaxe plugin, Timelord, and we started getting emails from other devs claiming our extension was causing theirs to break. So it causes issues with other's scripts but not your own, still just as a developer courtesy (unless you're in AI) then you should probably avoid direct assignment / prototype extensions on native objects ($, app, Array, Number, etc).

 

Here's a link to what the $ object is, btw. Here's an equivalent link for online documentation to the entire Illustrator DOM, which is far superior to all Adobe's own documentation, and here's an online code editor that I made with a bunch of app-specific links for resources with intellisense and some other features which is just like VSCode (since Extendscript Toolkit is an awful, dinosaur of a program lol).

Likes

translate

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