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

Fiddling with Action buttons in Repeating section - needs help with sheetworker

1607027476
Yui V.
Pro
Sheet Author
Hello, I'm working on a repeating section with cycling checjboxes. They're built from action buttons and work fine outside of the repeating section, but inside of it, I have trouble getting the rowIDs Here's my code:   const levelRadioValues = ["0","1","01"];   getSectionIDs(`repeating_${section}`, idArray => {     levelRadioValues.forEach(function(value) {         on(`clicked:repeating_${section}_${id}_aff4_${value}`, function() {           setAttrs({             ["level4"]: value           });         });     });   }); This code is my test subject with the getSectionIDs. But it doesn't work. I have no formal training in javascript, so I don't really know how to get this to work. Thank you.
1607040966

Edited 1607041853
Oosh
Sheet Author
API Scripter
Do you have the variable section defined somewhere? You can just put the section name directly into the function, so getSectionIDs('repeating_sectionname', ids => {}) , using a template literal is a step you don't need unless the code block is handling multiple repeating sections. Not that it's a problem, just a line you don't need. You also need to tell the script to iterate through idArray, generally with a (for) loop, or the forEach() method. Is there more than one value changing on a click? Or does a click only change the value in the repeating row where it happens? I think you probably want to use an event on just the row that's clicked, but I'm not sure. This also means you don't need getSectionIDs at all, as the event will give you the row ID of where the click happens. Once you define your section variable and iterate through idArray, it would look like this: const section = 'sectionname'; // or just put this straight into the function const levelRadioValues = ["0","1","01"]; getSectionIDs(`repeating_${section}`, idArray => { idArray.forEach(id => { levelRadioValues.forEach(function(value) { on(`clicked:repeating_${section}_${id}_aff4_${value}`, function() { setAttrs({ ["level4"]: value }); }); }); }); }); This is hard-coded to set the same Attribute through every iteration. I'm assuming that isn't the intent? The "level4" attribute is cycled through your radiovalues array, regardless of which row is being processed. I think what you probably want, is to remove the on('clicked') event from the middle of the code, and put it at the start. Something like: const levelRadioValues = ["0","1","01"]; levelRadioValues.forEach(function(value) { on(`clicked:repeating_sectionname:aff4_${value}`), function(event) { // stuff goes here }) }) But it's hard to tell without more info.
1607046487
Yui V.
Pro
Sheet Author
Thank you for replying. To clarify what this is supposed to do: I have one repeating field named repeating_affection. It is the only reap. section on the sheet that needs cycling checkboxes/this sheetworker. Each row will have 4 cycling checkboxes (hence the 4 in the attribute names, this specific function updates only the fourth box). Each cycling checkbox is in fact 3 action buttons named aff[#]_0, aff[#]_1 and aff[#]_01. When one is clicked, it sets the corresponding 'level[#]' attribute to its suffix (0 ,1 or 01). And that's all. I couldn't get your suggestions to work as is, though.
1607048871

Edited 1607050302
Oosh
Sheet Author
API Scripter
Is there anything else going on in this repeating section? It's probably easiest to make a single event handler for the whole section, if possible. Is each row just the [1]    [2]    [3]    [4] 4 checkboxes, or is there more in each row? So I found this - not sure if it's still relevant, but apparently underscores in action button names cause issues with on('clicked') detection in repeating sections. If you change the button names to aff[#]-0, aff[#]-1, aff[#]-01, you should be able to get the event to fire. Try this, and see if it logs anything: on('clicked:repeating_affection', function(event) { console.log(event.sourceAttribute) } If it doesn't, try renaming  the action buttons to hyphens instead of underscores and try again. Any luck?
1607093161
Yui V.
Pro
Sheet Author
I tried to change the names but nothing chnages. Here is the full html file: <fieldset class="repeating_affection" >     <div class="aff-con">         <input type="text" name="attr_affname" class="aff-n">              <div class="radios">           <input type="hidden" class="radio" name="attr_level" value="1" />                      <input type="checkbox" name="attr_active" class="border" value="1"/>                    <button type="action" name="act_aff-0" class="radio radio-1">             <span class="unchecked"></span>           </button>           <button type="action" name="act_aff-1" class="radio radio-2">             <span class="checked"></span>           </button>           <button type="action" name="act_aff-01" class="radio radio-3">             <span class="disabled"></span>           </button>         </div>                  <div class="radios2">           <input type="hidden" class="radio2" name="attr_level2" value="1" />                      <input type="checkbox" name="attr_active2" class="border2" value="1"/>                    <button type="action" name="act_aff2-0" class="radio2 radio-1">             <span class="unchecked2"></span>           </button>           <button type="action" name="act_aff2-1" class="radio2 radio-2">             <span class="checked2"></span>           </button>           <button type="action" name="act_aff2-01" class="radio2 radio-3">             <span class="disabled2"></span>           </button>         </div>                  <div class="radios3">           <input type="hidden" class="radio3" name="attr_level3" value="1" />                      <input type="checkbox" name="attr_active3" class="border3" value="1"/>                    <button type="action" name="act_aff3-0" class="radio3 radio-1">             <span class="unchecked3"></span>           </button>           <button type="action" name="act_aff3-1" class="radio3 radio-2">             <span class="checked3"></span>           </button>           <button type="action" name="act_aff3-01" class="radio3 radio-3">             <span class="disabled3"></span>           </button>         </div>                  <div class="radios4">           <input type="hidden" class="radio4" name="attr_level4" value="1" />                      <input type="checkbox" name="attr_active4" class="border4" value="1"/>                    <button type="action" name="act_aff4-0" class="radio4 radio-1">             <span class="unchecked4"></span>           </button>           <button type="action" name="act_aff4-1" class="radio4 radio-2">             <span class="checked4"></span>           </button>           <button type="action" name="act_aff4-01" class="radio4 radio-3">             <span class="disabled4"></span>           </button>         </div>          </div> </fieldset> <script type="text/worker">     const levelRadioValues = ["0","1","01"];     levelRadioValues.forEach(function(value) {         on(`clicked:aff-${value}`, function() {             setAttrs({                ["level"]: value             });         });     });     levelRadioValues.forEach(function(value) {         on(`clicked:aff2-${value}`, function() {             setAttrs({                ["level2"]: value             });         });     });     levelRadioValues.forEach(function(value) {         on(`clicked:aff3-${value}`, function() {             setAttrs({                ["level3"]: value             });         });     });     getSectionIDs(`repeating_affection`, idArray => {     idArray.forEach(id => {         levelRadioValues.forEach(function(value) {             on(`clicked:repeating_affection_${id}_aff4-${value}`, function() {                 setAttrs({                 ["level4"]: value                 });             });         });     });   });     const repeatingSum = (destinations, section, fields) => {         if (!Array.isArray(destinations)) destinations = [destinations.replace(/\s/g, '').split(',')];         if (!Array.isArray(fields)) fields = [fields.replace(/\s/g, '').split(',')];         getSectionIDs(`repeating_${section}`, idArray => {             const attrArray = idArray.reduce((m, id) => [...m, ...(fields.map(field => `repeating_${section}_${id}_${field}`))], []);             getAttrs([...attrArray], v => {                 const getValue = (section, id, field) => v[`repeating_${section}_${id}_${field}`] === 'on' ? 1 : parseFloat(v[`repeating_${section}_${id}_${field}`]) || 0;                 const commonMultipliers = (fields.length <= destinations.length) ? [] : fields.splice(destinations.length, fields.length - destinations.length);                 const output = {};                 destinations.forEach((destination, index) => {                     output[destination] = idArray.reduce((total, id) => total + getValue(section, id, fields[index]) * commonMultipliers.reduce((subtotal, mult) => subtotal * getValue(section, id, mult), 1), 0);                 });                 setAttrs(output);             });          });      };          on('change:repeating_affection:level remove:repeating_affection sheet:opened', function() {     repeatingSum("used","affection","level");     });     on('change:repeating_affection:level2 remove:repeating_affection sheet:opened', function() {     repeatingSum("used2","affection","level2");     });     on('change:repeating_affection:level3 remove:repeating_affection sheet:opened', function() {     repeatingSum("used3","affection","level3");     });     on('change:repeating_affection:level4 remove:repeating_affection sheet:opened', function() {     repeatingSum("used4","affection","level4");     }); </script> <input type="hidden" name="attr_used" value="0" /> <input type="hidden" name="attr_used2" value="0" /> <input type="hidden" name="attr_used3" value="0" /> <input type="hidden" name="attr_used4" value="0" /> <input type="number" name="attr_attaff" value="@{used}+@{used2}+@{used3}+@{used4}" disabled="true"/> So you can see that in the line there is a text input, and a normal check box for each cycling checkbox. But this shouldn't interfere. I'm doing my tests on aff4 only right now.
1607133748

Edited 1607133894
Oosh
Sheet Author
API Scripter
It looks like action buttons in repeating sections have caused issues for a few people, from a quick search. Hopefully one of the sheet gurus will drop in with some advice. I'd probably start by making sure the event is firing. So something basic like cycling through these and seeing which ones are generating an event: on('clicked:repeating_affection', function(event) { console.log(event.sourceAttribute) } on('clicked:aff4-1', function(event) { console.log(event.sourceAttribute) } on('clicked:repeating_affection:aff4-1', function(event) { console.log(event.sourceAttribute) } Hopefully the third one works (only for aff4-1 specifically, obviously) because you won't get the repeating row information in the (event) object if you just use 'clicked:aff-1'. Oh - I'm assuming the sheet sandbox has a console to log to, since I've seen it in other threads on sheetworkers. I've never used it though.
1607188059

Edited 1607232905
Yui V.
Pro
Sheet Author
Okay, being lost in the jungle, I decided to revert to full [Moderated] mode and found a pure html+css solution. I don't know how to use, or interpret the console. I only know of the chrome dev console (which displays lines from roll20 and the sheetworker it seems, but I can't know exactly). Sorry for this failure and Thank you for your support.
1607211978
Oosh
Sheet Author
API Scripter
Sorry I couldn't be more help, was hoping one of the proper sheet authors would have a solution!
1609048806
GiGs
Pro
Sheet Author
API Scripter
Are you still having problems with this code? i notice a fairly significant issue with the code sample earlier - you have getSectionIDs and the on(change) events nested inside it, which wont work as you need it to. It will build an array of the rows at the moment the sheet is opened, but wont update them as players add or delete rows while the sheet is open.  If you are still having issues, post back and I'll see if I can help but will probably need to ask a question or two to figure out exactly what you're trying to do.