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 .
×

The new D&D 2024 sheet is now available!

Create a free account

Getting multiple values from selections in repeating sections?

Apologies up-front as I have seen answers for similar questions but nothing that was exactly what I'm after.  I'm trying to make sense of workers (and GiGs' page has been invaluable on helping me with less-intense functions) but the learning curve has been pretty gnarly for me, which brings me once more to all you brilliant minds out here in Greater Forumland. The Setup: In my homebrew system, spells are done through picking levels (including "0") for various aspects (size, damage, range, etc.).  Each level has a different "cost" which, when you add them together, are compared against a level-derived number to say if the spell you're making is too expensive for your low-level magician. You've played a point-buy system.  You get it. Thus: repeating fields for a mage's spells.  They can build them on their own, as customizable as the successfully-implemented equipment fields. But THEN I built a separate rolltemplate to do the equivalent of a spellcard for the spell because that's a LOT more convenient for everyone than opening the thing up and examining all the little select and checkboxes. This creates... The Problem: It's easy to just have the select box's values give the appropriate "cost" (something like <input type="number" value="(@{thing1}+@{thing2})" disabled="true">), but when trying to make some kind of rolltemplate spellcard output, I'm having some big difficulties because the spellcard should display the value of the selectbox (or a similar value) instead.  Damage level 5 costs 25 points; I'd like it to output "Damage: 5" as opposed to "Damage: 25". (Nonfunctioning) Attempted Solution: My attempted solution has been to use a sheetworker to take the level value (0-7) and output the attendant cost (0-60) into one of a series of "hidden" inputs which share the attr_ name of each aspect of the spell with "cost" appended to the end.  It feels like the thing to do, anyway.  I'm going pretty cargo cult with a lot of this, but it feels like the sort of thing that would work.  I've done a goodly amount of skimming other answers and trying to reverse-engineer the solutions suggested by the absurdly-helpful folks here on the forums and thought I had a decent worker to do it, but I'm here so I'm clearly wrong. Any assistance would be much appreciated because I can get ONE function to work (spellcard rolltemplate OR point collection/comparison), but doing both has been kicking my brain up and down the avenue. The Code: Yeah, that.  With (very) minor formatting and edits for legibility. <div class="repspellbits f-row f-center" style="display:inline;"> <span class="spelltitles">Spell Aspects</span>      <div class="repspellextras">         <div class="optblock">         <span class="spellaspects">Damage</span>         <input type="checkbox" class="repspelldmg-tog" /><span></span>         <div class="repspelldmg">                 <select name="attr_repspell01" class="selproj">                     <option value="0" selected>0</option>                     <option value="1">1</option>                     <option value="2">2</option>                     <option value="3">3</option>                     <option value="4">4</option>                     <option value="5">5</option>                     <option value="6">6</option>                     <option value="7">7</option>                 </select>         <input type="hidden" name="attr_repspell01cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Size</span>         <input type="checkbox" class="repspellsize-tog" /><span></span>         <div class="repspellsize">                 <select name="attr_repspell02" class="selproj">                     <option value="0" selected>Handful</option>                     <option value="1">All in 5ft</option>                     <option value="2">All in Near</option>                     <option value="3">All in Ranged</option>                     <option value="4">All in Distant</option>                 </select>         <a class="button" href="#ref-size">[info]</a>         <input type="hidden" name="attr_repspell02cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Distance</span>         <input type="checkbox" class="repspelldist-tog" /><span></span>         <div class="repspelldist">                 <select name="attr_repspell03" class="selproj">                     <option value="0" selected>Touch</option>                     <option value="1">Near</option>                     <option value="2">Ranged</option>                     <option value="3">Distant</option>                     <option value="4">Far</option>                 </select>         <a class="button" href="#ref-dist">[info]</a>         <input type="hidden" name="attr_repspell03cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Targets</span>         <input type="checkbox" class="repspelltarg-tog" /><span></span>         <div class="repspelltarg">                 <select name="attr_repspell04" class="selproj">                     <option value="1" selected>1</option>                     <option value="2">2</option>                     <option value="3">3</option>                     <option value="4">4</option>                     <option value="5">5</option>                 </select>         <input type="hidden" name="attr_repspell04cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Element</span>         <input type="checkbox" class="repspellelement-tog" /><span></span>         <div class="repspellelement">                 <select name="attr_repspell05" class="selproj">                     <option value="0" selected>Magic</option>                     <option value="1">Fire</option>                     <option value="1">Water</option>                     <option value="1">Air/Wind</option>                     <option value="1">Metal</option>                     <option value="1">Wood</option>                     <option value="1">Earth/Stone</option>                     <option value="1">Electricity</option>                     <option value="1">Sickness</option>                     <option value="1">Light</option>                     <option value="1">Shadow</option>                 </select>         <input type="hidden" name="attr_repspell05cost" value="0" />                         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Parts</span>         <input type="checkbox" class="repspellparts-tog" /><span></span>         <div class="repspellparts">                 <select name="attr_repspell06" class="selproj">                     <option value="0" selected>0</option>                     <option value="1">1</option>                     <option value="2">2</option>                     <option value="3">3</option>                     <option value="4">4</option>                 </select>         <input type="hidden" name="attr_repspell06cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Duration</span>         <input type="checkbox" class="repspelltime-tog" /><span></span>         <div class="repspelltime">                 <select name="attr_repspell07" class="selproj">                     <option value="0" selected>Momentary</option>                     <option value="1">Lingering</option>                     <option value="2">Solid</option>                     <option value="3">Enduring</option>                     <option value="4">Semi-Real</option>                 </select>         <a class="button" href="#ref-time">[info]</a>         <input type="hidden" name="attr_repspell07cost" value="0" />         </div>         </div>                 <div class="optblock">         <span class="spellaspects">Shield</span>         <input type="checkbox" class="repspellshield-tog" /><span></span>         <div class="repspellshield">                 <select name="attr_repspell08" class="selproj">                     <option value="0" selected>None</option>                     <option value="1">Focus*3</option>                     <option value="2">Focus*5</option>                     <option value="3">Focus*7</option>                     <option value="4">Focus*10</option>                 </select>         <a class="button" href="#ref-shield">[info]</a>         <input type="hidden" name="attr_repspell08cost" value="0" />         </div>         </div>         </div>            <div> <span class="ablname">Total: </span> <input type="number" name="attr_repspelltotal" value="(@{repspell01cost}+@{repspell02cost}+@{repspell03cost}+@{repspell04cost}+@{repspell05cost}+@{repspell06cost}+@{repspell07cost}+@{repspell08cost} )" style="background-color:#fff;color:#000;width:50px;" readonly /> </div> </div> And, because I think these things work better when html and script are broken up in the questions, here's the script attempt (shamelessly derived from an answer given elsewhere on here, but that one wasn't for a repeating section, so I attempted to adapt it, but alas). <script type="text/worker">      const aspects = ["repeating_spellbuild_repspell01", "repeating_spellbuild_repspell02", "repeating_spellbuild_repspell03", "repeating_spellbuild_repspell04", "repeating_spellbuild_repspell05", "repeating_spellbuild_repspell06", "repeating_spellbuild_repspell07", "repeating_spellbuild_repspell08"]; aspects.forEach(function (aspect) {     on("change:" + aspect + " sheet:opened", function () {         getAttrs([aspect], function (values) {             const score = parseInt(values[aspect])||0;             let cost = 0;             if(score === 0) cost = 0;             else if(score === 1) cost = 1;             else if(score === 2) cost = 3;             else if(score === 3) cost = 5;             else if(score === 4) cost = 10;             else if(score === 5) cost = 25;             else if(score === 6) cost = 40;             else if(score === 7) cost = 60;             setAttrs({                 ["repeating_spellbuild_" + aspect + "cost"]: cost             });         });     }); }); </script> Also, I know one of them has 'value="1"' for everything (maybe I could just change that particular one to a checkbox with a select for later but I left it as it is because at least now you won't wonder why the numbering jumped one), but as far as I can tell if the output is 1 (after the parseInt has done its work), the script as intended should return a cost of 1 as well, so probably not that big a deal, right? Anyway, for all I'm a bit less of a n00b now that I was when I started this journey 3 weeks ago, I'm nothing like a competent amateur yet.  Any assistance anyone can render would be most appreciated.  Especially if there's an easier way to do this or another avenue that would get me closer to my goal instead.  I know I could probably just scrap the whole idea (I am dangerously close to doing so) but this seemed like the sort of professional-adjacent flourish that players might enjoy.
1700517751

Edited 1700518013
GiGs
Pro
Sheet Author
API Scripter
It's a bit late in my day to follow a long post, but two things I notice. 1) yay, you are finding my site helpful. I'm happy to hear it. 2) Your sheet worker looks a bit faulty. aspect is going to have a value of, say, repeating_spellbuild_repspell01 , but then you have ["repeating_spellbuild_" + aspect + "cost"]: cost that would lead to saving the attribute of repeating_spellbuild_ repeating_spellbuild_repspell01 cost which cant be right (also you probably want an underscore before cost ) . You likely want to change the start to something like this: const aspects = ["repspell01", "repspell02", "repspell03", "repspell04", "repspell05", "repspell06", "repspell07", "repspell08"]; aspects.forEach(function (aspect) {     on("change:repeating_spellbuild_" + aspect + " sheet:opened", function () {         getAttrs(["repeating_spellbuild_" + aspect], function (values) {             const score = parseInt(values["repeating_spellbuild_" + aspect])||0; You might also want to change this to use getSectionIDs, but if it's responding to just one attribute change, that's not strictly necessary. This should work with an ending of setAttrs({                 ["repeating_spellbuild_" + aspect + "cost"]: cost             }); Note the underscore added to the cost. (I realised my mistake aboutthe undescore here. Hope this code works! Also in your html, this select wont work like you expect: <select name="attr_repspell05" class="selproj">                     <option value="0" selected>Magic</option>                     <option value="1">Fire</option>                     <option value="1">Water</option>                     <option value="1">Air/Wind</option>                     <option value="1">Metal</option>                     <option value="1">Wood</option>                     <option value="1">Earth/Stone</option>                     <option value="1">Electricity</option>                     <option value="1">Sickness</option>                     <option value="1">Light</option>                     <option value="1">Shadow</option>                 </select> HTML looks only at the value, so if you select Shadow, then at the next character sheet opening, it will pick Fire (the first entry with value="1"). If you want all those to be shown separately, you'll need to make values unique. One trick here is that values are strings, so "1", "01", "001", "0001" and so on are all unique as strings, but when in the sheet worker, you coerece them into numbers, they'll all have a value of 1. It would be better to make them properly unique, especially since there's a lot of them, but this is perfectly doable. That's all I can look at now - it's bed time. Good luck!
Many thanks for doing this so late into your day!  Night owl that I am, I get how doing that one last freaking thing can sometimes disrupt your ability to function the next day so I know that taking the time to debug my hacky attempts at code that quick can be a real big thing.  I hope it's not , of course (I'd like very much for you to be well-rested 'cuz at least SOMEONE should be), but I am no less appreciative for it. Am about to start implementing these but you popped in to be really helpful super-duper quick so I figure you deserve thanks super-duper quick* as well. *: well, all things being relative
After some futzing about because my incredibly dumb self managed to mess up a very simple copy/paste, I am very pleased to report that the fixes to my awful (which is saying something because something so simple shouldn't be so up-messable) code had the desired result. Once more, many many thanks, GiGs.
1700578419
GiGs
Pro
Sheet Author
API Scripter
Yay, glad you fixed it, and thanks for your understanding.