Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Parse Expression From Text Field

Hello, I'm trying to setup my character sheet to parse an expression from a text field on the sheet that the user fills in. It should account for both static numbers and sheet variables. Said text field might contain "@{STR-mod} + @{class-level}", or simply "12" for example. I can easily accomplish this using disabled fields, but I was wondering how one might accomplish this using the much-preferred readonly fields using sheet workers? Thanks!
Any word on this? Either my Google-fu is sorely lacking or there doesn't seem to be much documentation out there for this. I've attempted to reverse engineer the Pathfinder Community sheet, which has this feature with readonly fields, but it appears they've run their Javascript code through a minifier thus making borderline impossible to dissect.
1615952714
Kraynic
Pro
Sheet Author
Did you look at any of the sheet building wiki pages? The hub: <a href="https://wiki.roll20.net/Building_Character_Sheets" rel="nofollow">https://wiki.roll20.net/Building_Character_Sheets</a> Which has a link to an article on sheetworkers (among other things): <a href="https://wiki.roll20.net/Sheet_Worker_Scripts" rel="nofollow">https://wiki.roll20.net/Sheet_Worker_Scripts</a> Which also has a link to another examples page:&nbsp; <a href="https://wiki.roll20.net/Sheetworker_examples_for_Non-programmers" rel="nofollow">https://wiki.roll20.net/Sheetworker_examples_for_Non-programmers</a>
1616021076
GiGs
Pro
Sheet Author
API Scripter
It's generally a bad idea to use text inputs if you are going to use them for calculations. And sheet workers aren't compatible with attribute references like @{STR-mod}. There are ways to get around this, but it's not possible to give advice without a more comprehensive description of what you are trying to do.
I'm looking to have text fields on my sheet that allows a user to throw in whatever formula they wish and to have those be parsed out to separate number field. One example of this would be to calculate various energy type maximum amounts per day in Pathfinder. Because it would be nigh impossible to account for all classes and archetypes (and various homebrew), I figured it would just be easier to allow the user to supply their own formula. I've attached an image for additional clarity:&nbsp; In the text field, the user entered @{STR-mod} + 1, which gets evaluated to 3. This example was taken from the Pathfinder Community sheet.
1616120973

Edited 1616121120
Kavini
Roll20 Production Team
Marketplace Creator
Sheet Author
Compendium Curator
This might be one of the few situations in which disabled fields might be the better solution. It's possible to write a sheetworker thatdoes this, but I can't think of a use case for doing so that you're not reinventing the wheel. However, in case you can, here's an example of how you might do that: &lt;div&gt; &lt;label for="attr_test1"&gt;@{test1}&lt;/label&gt; &lt;input name="attr_test1" type="text" value="2" /&gt; &lt;/div&gt; &lt;div&gt; &lt;label for="attr_test2"&gt;@{test2}&lt;/label&gt; &lt;input name="attr_test2" type="text" value="3" /&gt; &lt;/div&gt; &lt;div&gt; &lt;label for="attr_example_input"&gt;Enter a calculation&lt;/label&gt; &lt;input name="attr_example_input" type="text" value="@{test1}+@{test2}" /&gt; &lt;/div&gt; &lt;div&gt; &lt;label for="attr_example_output"&gt;The Result&lt;/label&gt; &lt;input name="attr_example_output" type="text" /&gt; &lt;/div&gt; &lt;script type="text/worker"&gt; on("sheet:opened change:example_input", eventInfo =&gt; { getAttrs(["example_input"], values =&gt; { const calculation = values["example_input"].replace(/\s/g, ""); // remove any whitespace const matches = [...calculation.matchAll(/@\{(.*?)\}/g)]; // get any @{attr}s with regex const attrs = matches.map(([match, attr]) =&gt; attr); // get the raw variable names getAttrs(attrs, values =&gt; { let parsed = calculation; for (const [match, attr] of matches) { parsed = parsed.replace(match, values[attr] || 0); // replace @{attr} with the value, or 0 if there isn't one } parsed = parsed.replace(/[^0-9+-/%*]+/g, x =&gt; `"${x}"`) // turn anything not numbers or operators into a string setAttrs({ "example_output": eval(parsed) // eval the expression and return it }); }); }); }); &lt;/script&gt; Note: Using eval isn't ideal . There are alternatives, and I advise you explore them, but this is the simplest method.
1616190549

Edited 1616190740
GiGs
Pro
Sheet Author
API Scripter
Personally I'd recommend avoiding a text input for this, but to think of every possible form of input players will ever enter, and then build a form layout using selects&nbsp; and number inputs for players to enter the data. Then your sheet worker can take the data as provided, without having to parse the text, and can be built to work easily. But yes, as Nic says, if you really want to use free text input, a disabled autocalc field for using the string is a very practical and easy solution. You dont have to handle any complex error cases or try to figure out how to parse it - it'll just work if players enter a valid string.
I suppose I'll stick to the disabled field implementation, then. I appreciate the heck out of your input, fellas! :)