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

Sum Total of Column in Repeating Fields

I have a sheet value that would be the sum of a column in a repeating field and have gotten as far as realizing I need to do this with a Sheet Worker Script but the wiki page and examples are leaving me kind of lost.  I'd appreciate either feedback or pointer to a simple example I could follow. What I have is the following repeating fields and I want to sum the total of the INJURY_LEVEL from the following fieldset and keep the result in an input field on the sheet called INJURY_TOTAL <fieldset class="repeating_injury"> <div> <input type="text" name="attr_INURY_LOCATION" class="sheet-skill-label"> <select name="attr_INJURY_SEVERITY" class="sheet-skill-value"> <option value="M">M</option> <option value="S">S</option> <option value="G">G</option> <option value="K">K</option> </select> <input type="number" name="attr_INJURY_LEVEL" class="sheet-skill-value"> <input type="number" name="attr_INJURY_HEALINGROLL" class="sheet-skill-value"> <div class="sheet-check-col"> <input type="checkbox" name="attr_INFECTED" value="1" checked="false"> </div> </div> </fieldset> the field I want to update is: <input type="number" name="attr_INJURY_TOTAL"> The best I can get now is knowing I should do a Sheet Worker on change and remove but how the examples I'm seeing, particularly on iterating over the IDs are really leaving me confused.   Thanks in advance for any help.
1513771422
GiGs
Pro
Sheet Author
API Scripter
Try this at the bottom of your html (you dont need the <Script > at the start and end if that already exists). <script type="text/worker"> on("change:repeating_injury:injury_level remove:repeating_injury", function() { getSectionIDs("repeating_injury", function(IDArray) { var fieldNames = [];         for (var i=0; i < IDArray.length; i++) { fieldNames.push("repeating_injury_" + IDArray[i] + "_INJURY_LEVEL"); }         var total = 0;         getAttrs(fieldNames, function(values) { for (var i=0; i < IDArray.length; i++) { total += parseInt(values["repeating_injury_" + IDArray[i] + "_INJURY_LEVEL"])||0; } setAttrs({ "INJURY_TOTAL": total });         }); }); }); </script>
Thanks again GG.  That helps a lot. So the IDArray provided in the getSectionIDs is ONLY the unique IDs, which makes sense.  I don't think I would have ever gotten that the IDs were inserted in the field name like that.   Thanks again. 
Sorry to keep coming back to the well here.  I'm trying to add another sheet worker script that is essentially the same for adding up load carried. I'm using the following fieldset and updating the total field under it: <fieldset class="repeating_load"> <div> <input type="text" name="attr_ITEM_NAME" class="sheet-skill-label"> <input type="number" name="attr_ITEM_WEIGHT"> </div> </fieldset> <div> <div class="sheet-skill-label sheet-skill-header sheet-right">Total Weight:</div> <input type="number" name="attr_LOAD_TOTAL" disabled="true"> </div> The a worker script based on the same script above which is working wonderfully: <script type="text/worker"> on("change:repeating_load:item_weight remove:repeating_load", function() { getSectionIDs("repeating_load", function(IDArray) { var fieldNames = []; for (var i=0; i < IDArray.length; i++) { fieldNames.push("repeating_load_" + IDArray[i] + "_ITEM_WEIGHT"); } var total = 0; getAttrs(fieldNames, function(values) { for (var i=0; i < IDArray.length; i++) { total += parseInt(values["repeating_load_" + IDArray[i] + "_ITEM_WEIGHT"])||0; } setAttrs({ "LOAD_TOTAL": total }); }); }); }); </script> Doesn't work and the console gives me this error: ERROR parsing formula: undefined app.js?1513621903:39 TypeError: Cannot read property 'replace' of undefined     at T.s.autoCalcFormula (app.js?1513621903:40)     at app.js?1513621903:39     at NodeList.forEach (<anonymous>)     at Function.k.each.k.forEach (base.js?1506449138:1)     at T.s._updateSheetValues (app.js?1513621903:39)     at n (base.js?1506449138:1) So I'm guessing this is a problem with the parseInt function in the loop to add totals but can't figure it out.  
I figured this out shortly after. This happens because I had the total field set to 'disabled=true' and while auto-calculate can effect those rows, Sheet Worker Scripts can't I guess? Anyway, wanted to close this loop in case it helps others.  I appreciate all the guidance.
1513790686
Lithl
Pro
Sheet Author
API Scripter
Even if there were a problem with your parseInt, the result would be NaN, and NaN||0 is equal to 0, so you'd just get a total of 0. The error may be coming from the fact that LOAD_TOTAL is a disabled field. You can't use setAttrs on disabled fields (disabled fields are used for autocalc); change it to readonly.
1513853366
Axel
Pro
Sheet Author
Thank you for this! A much more compact method for just getting a simple sum of repeating fields than using the Aaron's script, which I was using, as effective as that is. I'll have to give this a try.
1513938324
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
If I might hijack this topic...  I'm doing something similar but each repeating field has a checkbox to select whether it ought to added to total_load. Any suggestions on what that might look like? 
1513939155

Edited 1513939512
Jakob
Sheet Author
API Scripter
Richard T. said: If I might hijack this topic...  I'm doing something similar but each repeating field has a checkbox to select whether it ought to added to total_load. Any suggestions on what that might look like?  The most immediate solution is to have your checkboxes have value="1", and then you can just multiply: totalLoad = idArray.reduce((m, id) => (m + (parseInt(values[`repeating_load_${id}_check`]) || 0)*(parseInt(values[`repeating_load_${id}_weight`]) || 0)), 0); This works because the checkbox attribute will be "1" if checked, "0" if unchecked. But you could also do it with .filter(): totalLoad = idArray.filter(id => (values[`repeating_load_${id}_check`] === '1')) .reduce((m, id) => (m + (parseInt(values[`repeating_load_${id}_weight`]) || 0)), 0);
1513941803

Edited 1513945995
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Hmm, dropping in the check box seems to break it, this is what I have: getAttrs(fieldNames, function(values) {          for (var i=0; i < IDArray.length; i++) {             total += ( (parseInt(values["repeating_labspecializations_" + IDArray[i] + "_labbonus"])||0) * ( parseInt(values["repeating_labspecializations_" + IDArray[i] + "_sactive")|| 0 ),0 );          }
1513946854
Jakob
Sheet Author
API Scripter
Try total += (parseInt(values["repeating_labspecializations_" + IDArray[i] + "_labbonus"])||0) * ( parseInt(values["repeating_labspecializations_" + IDArray[i] + "_sactive"])|| 0 ); You forgot a closing "]", and had an extra ",0" at the end.
1513993574
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Looks like its almost there, it's updating now but it seems to be zeroing out the total. I wanna double check the html.  This looks right?  <input type="checkbox" name="attr_sactive" value="1" />
1513998751

Edited 1513999002
GiGs
Pro
Sheet Author
API Scripter
That looks right. I suggest posting your complete sheet worker. Also, just in case, the html of the labspecialisations repeating set.
1514001962
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
the fieldset                     <fieldset class="repeating_labSpecializations">                         <table class="sheet-table_2" style="width:400px">                             <tr>                                 <td><input type="text" class="sheet-heading_2" name="attr_LabSpecialization" style="width:300px"/></td>                                 <td><input type="text" class="sheet-number_2" name="attr_LabBonus" value="0" /></td>                                 <td><div style="width:40px;padding-left:15px;"><input type="checkbox" name="attr_sactive" value="1" /></div></th>                             </tr>                         </table>                     </fieldset> the sheet worker on("change:repeating_labspecializations:labbonus remove:repeating_labspecializations change:repeating_labspecializations:sactive", function() {    getSectionIDs("repeating_labspecializations", function(IDArray) {       var fieldNames = [];         for (var i=0; i < IDArray.length; i++) {          fieldNames.push("repeating_labspecializations_" + IDArray[i] + "_labbonus");       }         var total = 0;         getAttrs(fieldNames, function(values) {          for (var i=0; i < IDArray.length; i++) {             total += (parseInt(values["repeating_labspecializations_" + IDArray[i] + "_labbonus"])||0) * ( parseInt(values["repeating_labspecializations_" + IDArray[i] + "_sactive"])|| 0 );          }          setAttrs({             "labbonus_total": total          });         });    }); });
1514025860
Jakob
Sheet Author
API Scripter
Of course that doesn't work, your fieldNames array does not contain any of the _sactive attribute names, so they all default to 0.
1514048409
GiGs
Pro
Sheet Author
API Scripter
Change this section  for (var i=0; i < IDArray.length; i++) {          fieldNames.push("repeating_labspecializations_" + IDArray[i] + "_labbonus");       } To for (var i=0; i < IDArray.length; i++) { fieldNames.push("repeating_labspecializations_" + IDArray[i] + "_labbonus"); fieldNames.push("repeating_labspecializations_" + IDArray[i] + "_sactive"); }
1514062816
Richard T.
Pro
Marketplace Creator
Sheet Author
Compendium Curator
Victory! Thanks everyone, I've been delaying doing this script to the end but its such a sigh of relief to get over this hump.