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: <div> <label for="attr_test1">@{test1}</label> <input name="attr_test1" type="text" value="2" /> </div> <div> <label for="attr_test2">@{test2}</label> <input name="attr_test2" type="text" value="3" /> </div> <div> <label for="attr_example_input">Enter a calculation</label> <input name="attr_example_input" type="text" value="@{test1}+@{test2}" /> </div> <div> <label for="attr_example_output">The Result</label> <input name="attr_example_output" type="text" /> </div> <script type="text/worker"> on("sheet:opened change:example_input", eventInfo => { getAttrs(["example_input"], values => { 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]) => attr); // get the raw variable names getAttrs(attrs, values => { 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 => `"${x}"`) // turn anything not numbers or operators into a string setAttrs({ "example_output": eval(parsed) // eval the expression and return it }); }); }); }); </script> Note: Using eval isn't ideal . There are alternatives, and I advise you explore them, but this is the simplest method.