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

[Sheet Worker] Which sheets have clear inventory examples?

1538624940

Edited 1538627832
Leothedino
Sheet Author
Hey guys, Looking to start work on an inventory section for my sheet, there's going to be two or three different repeating sections/lists, so a Sheet Worker is going to be a must to calculate the weights as a total! I learn best by reading and recreating, so I checked out the 5e roll20 sheet to see how they did it (as I know, from experience, that sheet does something similar with its inventory) only, being it such a flawless high quality sheet, it was super confusing and intense. Are there any other games/sheets on here that might have easier examples of weight managing inventories? 
I -think- I found something to build off of and in the interest of sharing knowledge, and should somebody come along this (albeit small) thread looking for the same, play around and practice with this code from The Aaron.
1538629994

Edited 1538630110
GiGs
Pro
Sheet Author
API Scripter
That looks like the origin of aaron's massive TAS function, which i've never been able to fully grasp. It's not hard to use it for simple sums, but you do need to add a huge multi-thousand line function to your code, and if all you are using it for is adding one field of a repeating section, its a bit overkill. It's here:&nbsp; <a href="https://github.com/shdwjk/TheAaronSheet" rel="nofollow">https://github.com/shdwjk/TheAaronSheet</a> . If you get that code snippet you found working, or use the full TheAaronSheet excellent. If they dont work for you, let us know and I'll post a function i use for this in the next day or two. It's a lot less elegant, and not as well-written, but easier to understand.
GG, i'll no doubt be battling this one for a day or two. Giving it a quick glance study I -think- I get how the Sheet Worker is functioning, but the first part might need some careful attention. Any and all help is seriously appreciated though and I won't say no to your offer as long as it doesn't eat into your own time. I'm on the final part of my sheet now, been at it a little bit every day for 6 weeks... never thought i'd have gotten this far. The support on these forums from you guys has made the whole learning experience possible and I owe you all a serious beer (or juice, hey, I don't judge :P). So thanks.
1538665125
Pat S.
Forum Champion
Sheet Author
Not sure if this would help you but my sheet is rather simple in code for it's inventory ( Basic Fantasy RPG ) and the sheetworker code for the inventory starts on line 653 &lt;!--inventory weight calculation--&gt; // Equipment Carried Section // <a href="https://app.roll20.net/users/877778/sfx" rel="nofollow">https://app.roll20.net/users/877778/sfx</a> helped me with the following two sheet workers on('change:repeating_inventtab1', function(){ &nbsp; &nbsp; TAS.repeating('inventtab1') &nbsp; &nbsp; .attrs('tempweight') &nbsp; &nbsp; .fields('itemwornenc', 'itemquantity') &nbsp; &nbsp; .reduce(function(m,r){ &nbsp; &nbsp; &nbsp; &nbsp; m.itemwornenc+=(r.F.itemwornenc*r.I.itemquantity); &nbsp; &nbsp; &nbsp; &nbsp; r.D[0].tempweight=(r.F.itemwornenc*r.I.itemquantity); &nbsp; &nbsp; &nbsp; &nbsp; return m; &nbsp; &nbsp; },{itemwornenc:0,itemquantity:0, desc: []}, function (m,r,a){ &nbsp; &nbsp; a.tempweight=m.itemwornenc; &nbsp; &nbsp; }) &nbsp; &nbsp; .execute(); }) on('sheet:opened', function(){ &nbsp; &nbsp; TAS.repeating('inventtab1') &nbsp; &nbsp; .attrs('tempweight') &nbsp; &nbsp; .fields('itemwornenc', 'itemquantity') &nbsp; &nbsp; .reduce(function(m,r){ &nbsp; &nbsp; &nbsp; &nbsp; m.itemwornenc+=(r.F.itemwornenc*r.I.itemquantity); &nbsp; &nbsp; &nbsp; &nbsp; r.D[0].tempweight=(r.F.itemwornenc*r.I.itemquantity); &nbsp; &nbsp; &nbsp; &nbsp; return m; &nbsp; &nbsp; },{itemwornenc:0,itemquantity:0, desc: []}, function (m,r,a){ &nbsp; &nbsp; a.tempweight=m.itemwornenc; &nbsp; &nbsp; }) &nbsp; &nbsp; .execute(); }) while the html code starts on line 2711 &lt;!--Inventory --&gt; &lt;div class="sheet-section-inventory"&gt; &lt;div class="sheet-row "&gt; &lt;!-- Loot--&gt; &lt;div class="sheet-col-1-2 sheet-padr"&gt; &lt;h4 class="sheet-center"&gt;Coin Carried &lt;/h4&gt; &lt;div class="sheet-row sheet-sub-header sheet-center"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;CP&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;SP&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;GP&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;Total Value(GP)&lt;/div&gt; &lt;/div&gt; &lt;div class="sheet-row sheet-center"&gt; &lt;div class="sheet-col-1-4" title="Copper Pieces"&gt;&lt;input type="number" name="attr_cp" value="0" min="0" step="1"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4" title="Silver Pieces"&gt;&lt;input type="number" name="attr_sp" value="0" min="0" step="1"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4" title="Gold Pieces"&gt;&lt;input type="number" name="attr_gp" value="0" min="0" step="1"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4" title="Total (in Gold Pieces)"&gt;&lt;input type="number" name="attr_money_total_gp" value="(@{cp} / 100) + (@{sp} / 10) +&nbsp; @{gp} " disabled="disabled"&gt;&lt;/div&gt; &lt;/div&gt; &lt;h4 class="sheet-center"&gt;Weight&lt;/h4&gt; &lt;div class="sheet-row sheet-sub-header sheet-center"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;Equipment&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;Coin&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label"&gt;Other&lt;/div&gt; &lt;/div&gt; &lt;div class="sheet-row sheet-center"&gt; &lt;div class="sheet-col-1-4 sheet-center"&gt;&lt;input style="display: none;" type="text" name="attr_tempweight" value="0"&gt;&lt;input type="number" name="attr_inventory_weight" title="Total of your equipment Worn and Carried" value="@{tempweight}" disabled="disabled"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center"&gt;&lt;input type="number" name="attr_coin_weight" title="This entry rounds to the nearest whole value" value="round(((@{CP} + @{SP} + @{GP})/10))" disabled="disabled"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-center"&gt;&lt;input type="number" name="attr_other_weight" value="0" min="0"&gt;&lt;/div&gt; &lt;/div&gt; &lt;h4 class="sheet-center"&gt;Carry Capacity&lt;/h4&gt; &lt;div class="sheet-row sheet-sub-header sheet-center"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label sheet-padr"&gt;Current Load&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-left sheet-small-label"&gt;Light Load Limit&lt;/div&gt; &nbsp; &nbsp; &lt;div class="sheet-col-1-4 sheet-right sheet-small-label"&gt;Heavy Load Limit&lt;/div&gt; &lt;/div&gt; &lt;div class="sheet-row sheet-center"&gt; &lt;div class="sheet-col-1-4 sheet-left" title="Current Load"&gt;&lt;input type="number" name="attr_total_weight" value="@{inventory_weight} + @{coin_weight} + @{other_weight}" disabled="disabled"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-right"&nbsp; title="Light Load"&gt;&lt;input type="number" name="attr_lightload" value="0" min="0" step="1"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-4 sheet-right" title="Heavy Load"&gt;&lt;input type="number" name="attr_heavyload" value="0" min="0" step="1"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;!-- Inventory tab --&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="sheet-col-1-2"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h4 class="sheet-center"&gt;Treasure Notes &lt;/h4&gt; &lt;textarea name="attr_lootnotes"&gt;&lt;/textarea&gt; &lt;/div&gt; &lt;/div&gt; &lt;h4 class="sheet-center"&gt;Equipment &lt;/h4&gt; &lt;input type="radio" name="attr_inventorytab" class="sheet-inventorytab sheet-inventorytab1" value="1" title="Page 1" checked="checked" /&gt; &lt;span class="sheet-inventorytab sheet-inventorytab1"&gt;On Person&lt;/span&gt; &lt;input type="radio" name="attr_inventorytab" class="sheet-inventorytab sheet-inventorytab3" value="3" title="Page 3" /&gt; &lt;span class="sheet-inventorytab sheet-inventorytab3"&gt;Transportation&lt;/span&gt; &lt;input type="radio" name="attr_inventorytab" class="sheet-inventorytab sheet-inventorytab4" value="4" title="Page 4" /&gt; &lt;span class="sheet-inventorytab sheet-inventorytab4"&gt;Elsewhere&lt;/span&gt; &lt;input type="radio" name="attr_inventorytab" class="sheet-inventorytab sheet-inventorytab99" value="99" title="Show All" /&gt; &lt;span class="sheet-inventorytab sheet-inventorytab99"&gt;Show All&lt;/span&gt; &lt;span class="sheet-spacer"&gt;&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &lt;!-- Inventory Page 1--&gt; &lt;div class="sheet-inventory-page1"&gt; &lt;input type="text" class="sheet-center sheet-sub-header" name="attr_tabinvtitle1" value="What is being worn or carried on person " disabled="disabled"&gt; &lt;div class="sheet-row sheet-sub-header"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label sheet-padl"&gt;Name&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-center sheet-small-label"&gt;Qty&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-center sheet-small-label"&gt;Weight&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-center sheet-small-label sheet-padl"&gt;Notes&lt;/div&gt; &lt;/div&gt; &lt;fieldset class="repeating_inventtab1"&gt; &lt;div class="sheet-row"&gt; &lt;div class="sheet-col-1-4 sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemname"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-padl sheet-center"&gt;&lt;input type="number" name="attr_itemquantity"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-padl sheet-center"&gt;&lt;input type="number" name="attr_itemwornenc"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-padl sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemdesc"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/fieldset&gt; &lt;/div&gt; &lt;!-- Inventory Page 3--&gt; &lt;div class="sheet-inventory-page3"&gt; &lt;input type="text" class="sheet-center sheet-sub-header" name="attr_tabinvtitle3" value="What is carried by your horse or wagon" disabled="disabled"&gt; &lt;div class="sheet-row sheet-sub-header"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label sheet-padl"&gt;Name&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-center sheet-small-label"&gt;Qty&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-center sheet-small-label"&gt;Weight&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-center sheet-small-label sheet-padl"&gt;Notes&lt;/div&gt; &lt;/div&gt; &lt;fieldset class="repeating_inventtab3"&gt; &lt;div class="sheet-row"&gt; &lt;div class="sheet-col-1-4 sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemname"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-padl sheet-center"&gt;&lt;input type="number" name="attr_itemquantity"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-padl sheet-center"&gt;&lt;input type="number" name="attr_itemtransportationenc"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-padl sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemdesc"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/fieldset&gt; &lt;/div&gt; &lt;!-- Inventory Page 4--&gt; &lt;div class="sheet-inventory-page4"&gt; &lt;input type="text" class="sheet-center sheet-sub-header" name="attr_tabinvtitle4" value="What is stored elsewhere such as in a vault or stronghold" disabled="disabled"&gt; &lt;div class="sheet-row sheet-sub-header"&gt; &lt;div class="sheet-col-1-4 sheet-center sheet-small-label sheet-padl"&gt;Name&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-center sheet-small-label"&gt;Qty&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-center sheet-small-label sheet-padl"&gt;Notes&lt;/div&gt; &lt;/div&gt; &lt;fieldset class="repeating_inventtab4"&gt; &lt;div class="sheet-row"&gt; &lt;div class="sheet-col-1-4 sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemname"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-12 sheet-padl sheet-center"&gt;&lt;input type="number" name="attr_itemquantity"&gt;&lt;/div&gt; &lt;div class="sheet-col-1-2 sheet-padl sheet-small-label sheet-left"&gt;&lt;input type="text" name="attr_itemdesc"&gt;&lt;/div&gt; &lt;/div&gt; &lt;/fieldset&gt; &lt;/div&gt; &lt;/div&gt;
Pat, hey! I've read, I think, all of your forum posts about this (they come up when you google the issue haha) :D I didn't want to necro them, but I think you did what I am still trying to do and I am glad you commented here. I'll check this code out and get back to you, thanks a ton!
1538668954

Edited 1538669022
Pat S.
Forum Champion
Sheet Author
I beat my head against the wall for long time, even with some people putting pillows in the way (thanks to those that helped me) and I was able to make it very simple inventory tab. The sheetworker code deals specifically with gathering up my inventory weight and displaying it in the carry capacity section. I have it setup to take the number of individual items times their individual weight then combine all entries into a sum. Example: Item amount weight Torch 1 1 Leather Armor 1 30 Would just show the sum of 31lbs in the equipment field in the weight section.
1538676864
GiGs
Pro
Sheet Author
API Scripter
bear in mind, Pats code does also need TheAaronSheet script to be installed - see the github link I gave earlier.
1538679349

Edited 1538679387
Pat S.
Forum Champion
Sheet Author
Yes it does. Sorry forgot to mention that. I thought the TAS was required part of making the sheetworkers work and it a simple cut/paste to the sheet then create sheetworker that you need for the function.
1538680914

Edited 1538680978
Leothedino
Sheet Author
So, stupid question, this TAS script... does it go in the HTML section of the sheet, within the 'Text/Script' as if it was any normal Sheet Worker along with my code, or is it put elsewhere? Also, how does TAS differ from the base Sheet Worker, not sure yet I understand the difference between the two.
1538685681

Edited 1538687263
GiGs
Pro
Sheet Author
API Scripter
TAS goes in the script block. Pat, it isn't a necessary part of sheet workers, it's only needed because you use that TAS function in your inventory calculator. If none of your sheet workers had lines like this: TAS. repeating('inventtab1') you could safely remove it. The TAS part is calling that function. Leo, TAS is a function, which is called by sheet workers. In coding, you often need to do the same thing over and over. You can create functions to do that. A simple example might be to roll some dice. You could create a function like this (this is not a good function, it's meant to be a simple illustrative example): function sumDice(numDice,dieSides) { &nbsp; &nbsp; &nbsp; // roll a number (numDice) of dice of (DieSides) sides, and add them up &nbsp; &nbsp; &nbsp; let sum = 0; &nbsp; &nbsp; &nbsp; for(var x = 0; x &lt; numDice; x++) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sum = sum + (Math.random() * dieSides) +1; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; return sum; } Then in your various sheet workers, you could simply call this any time you needed to roll a bunch of dice. let newRoll = sumDice(3,6) // an example of rolling 3 6-sided dice and adding them .TAS is a much more advanced and powerful function, but the principle is the same.
1538686286
Finderski
Pro
Sheet Author
Compendium Curator
Here's a shorter function that sums stuff up--I use this one calc the weight of various sections (armor, melee, ranged, etc) // Simple Sum function for Repeating Sections function repeatingSimpleSum (section, field, destination){ var repSection = "repeating_"+section; getSectionIDs(repSection, function(idArray) { //Construct Array of fields to get attributes for... var sumFields = []; for (var a=0; a&lt; idArray.length; a++) { sumFields[sumFields.length] = repSection + "_" + idArray[a] + "_" + field; } getAttrs(sumFields, function(v) { console.log("%%% values of v: "+ JSON.stringify(v) +" %%%"); var sumTotal = 0; for(a=0; a&lt;idArray.length; a++){ sumTotal += parseInt(v[sumFields[a]]) || 0; console.log("$$$ sumTotal: " + sumTotal + " $$$"); } var setSumValue = {}; setSumValue[destination]=sumTotal; setAttrs(setSumValue); }); }); } Here's an example of how one section calls it... //Calculate Armor Weight&nbsp; on('change:repeating_armor',function(evenInfo){ getAttrs(["repeating_armor_armorWorn","repeating_armor_ArmorTypeWeight"],function(value) { var isWorn = parseInt(value.repeating_armor_armorWorn) || 0; var aWeight = parseInt(value.repeating_armor_ArmorTypeWeight) || 0; console.log("&amp;&amp;&amp; is Worn: "+isWorn+" || aWeight: "+aWeight+" &amp;&amp;&amp;"); var armorweightworn = isWorn * aWeight; console.log("### Worn Armor Weight: "+armorweightworn+" ###"); setAttrs({repeating_armor_armorCalcValue: armorweightworn}); }); repeatingSimpleSum("armor","armorCalcValue","armortotalweightcarried"); }); on('remove:repeating_armor', function() { repeatingSimpleSum("armor","armorCalcValue","armortotalweightcarried"); }); In that example, there's a checkbox on the armor that indicates whether it's worn or not. If it's worn, it has a value of 1, otherwise it's a value of 0 so the weight will either be the weight or 0. &nbsp;There are other ways that could have been done, but I felt that was the easies. :) Anyway, &nbsp;hope this helps.
Holy moly, I was thinking to myself originally 'how would I do worn weight' and just considered leaving it out. This is brilliant, i'm going to give it a try! Thank you!!
1538693650

Edited 1538695023
GiGs
Pro
Sheet Author
API Scripter
I made a tweak to finderski's function. This handles quantities and on/off statuses within the repeatingSimpleSum formula. function repeatingSum (destination, section, fieldsum, fieldmult, totalmult){ // destination = the name of the attribute that stores the total weight // section = name forof repeating fieldset, without the repeating_ // fieldsum = the name of the "weight" field to be summed // fieldmult = the name of quantity field, that multiplies weight. // Leave as "false" if ignored. If using a checkbox rather than a number input, set its value to 1. // totalmult = a multiplier to ever item in the fieldset. For instance, coinage might be 0.02 each, so multiple the final total by 0.02 // you can leave fieldmult and totalmult off. var repSection = "repeating_"+section; let multiplier = true; if (fieldmult === undefined || fieldmult === false || fieldmult === 'false') multiplier = false; if (totalmult === undefined) totalmult = 1; getSectionIDs(repSection, function(idArray) { //Construct Array of fields to get attributes for... var sumFields = []; var multFields = []; for (var a=0; a&lt; idArray.length; a++) { sumFields[sumFields.length] = repSection + "_" + idArray[a] + "_" + fieldsum; if(multiplier) multFields[multFields.length] = repSection + "_" + idArray[a] + "_" + fieldmult; } getAttrs(sumFields.concat(multFields), function(v) { console.log("%%% values of v: "+ JSON.stringify(v) +" %%%"); let sumTotal = 0; let tempSum = 0; for(a=0; a&lt;idArray.length; a++){ tempSum = parseInt(v[sumFields[a]]) || 0; if(multiplier) { tempSum = tempSum * parseInt(v[multFields[a]]) || 0; } sumTotal += tempSum; console.log("$$$ sumTotal: " + sumTotal + " $$$"); } var setSumValue = {}; setSumValue[destination]=sumTotal * totalmult; setAttrs(setSumValue); }); }); } Some examples of calling it: say you have an inventory fieldset, and you might carry, say, 1 sword, but 10 arrows: itemweight = the input box that contains the weight of a single item, itemcount = the input box that contains the number of items. weight_carried = the box that contains the total weight of your gear on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("weight_carried", "inventory","itemweight","itemcount"); }); Say you have an armour fieldset, and you might have several suits of armour. Each has a checkbox (name: armour_on), with a value =1. When you wear it, check the box, and the armour is calculated. on('change:repeating_armour remove:repeating_armour sheet_opened', function() { repeatingSum("weight_worn", "armour","armour_weight","armour_on"); }); Finally say you have a place for special artefacts, and you only ever have one of each. In this case, the multiplier field is set to false and ignored.&nbsp; on('change:repeating_artifacts remove:repeating_artifacts sheet_opened', function() { repeatingSum("weight_artifacts","artifacts","artifact_weight",false); }); You can also skip the last field entirely: on('change:repeating_artifacts remove:repeating_artifacts sheet_opened', function() { repeatingSum("weight_artifacts","artifacts","artifact_weight"); }); Then you have&nbsp; total_encumbrance box, and this makes sure they all add correctly on('change:weight_artifacts change:weight_carried change:weight_worn sheet_opened', function() { &nbsp; &nbsp; getAttrs(['weight_artifacts','weight_worn','weight_carried'], function(v) { &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; encumbrance_total: parseInt(v.weight_artifacts) || 0 + parseInt(v.weight_carried) || 0 + parseInt(v.weight_worn) || 0 &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; }); }); Thanks for posting it finderski. I like this approach a lot, and will be replacing the method I used to do it which was a little clunkier.
1538694236
GiGs
Pro
Sheet Author
API Scripter
I should probably have changed the function name to RepeatingSum, since its not quite&nbsp; a SimpleSum anymore.
1538695182
Pat S.
Forum Champion
Sheet Author
When I get the chance I might be rewritting my code some with what Finderski showed.
1538695277
GiGs
Pro
Sheet Author
API Scripter
I renamed the function and added another feature. Let's say you have an inventory section for tracking coins, but each coin is 0.02 in weight. on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("weight_coinage", "coinage","coinnumber",false,0.02); }); This means you dont have to enter the weight each time for each coin, you just enter the number of coins of that type, and the total is multiplied at the end for weight purposes. It's probably a bit overkill to do it this way, since coinage and similar things probably aren't done as repeating fieldsets, but there may be other applications for it.
Woah, you guys, seriously went the extra mile. I understand now what this is about, what I am going to do now is actually make a repeating section and try to use this latest example. Will get back here when/if successful! Many thanks guys!&nbsp;
1538695680
GiGs
Pro
Sheet Author
API Scripter
Pat S. said: When I get the chance I might be rewritting my code some with what Finderski showed. I recommend it. I get the impression that TAS is very powerful, but it's a bit overkill if you're just using it for summing encumbrance.
1538695810
GiGs
Pro
Sheet Author
API Scripter
Leothedino said: Woah, you guys, seriously went the extra mile. I understand now what this is about, what I am going to do now is actually make a repeating section and try to use this latest example. Will get back here when/if successful! Many thanks guys!&nbsp; Here;s the repeating section I used for testing. No CSS so it doesnt look pretty, but it works. &lt;!--Inventory --&gt; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Item &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Number &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Weight &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;fieldset class="repeating_inventory"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="text" name="attr_itemname"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="checkbox" name="attr_itemcount" value="1"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="number" name="attr_itemweight"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &lt;/fieldset&gt; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &lt;label&gt;Total: &lt;/label&gt; &nbsp; &nbsp; &lt;input type="number" name="attr_encumbrance"&gt; And the sheet worker: on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("encumbrance","inventory","itemweight","itemcount"); });
Wonderful, i'll open up a test sheet and go to work on this. I can backwards engineer the shizz out of it! :D&nbsp;
1538697036

Edited 1538697291
Leothedino
Sheet Author
Ok, within seconds it's functioning. The sheet Worker part is so simple as all the work is in the long function before it. That's really clever man, i'm kinda blown away.&nbsp; But a question, how would the part where you multiply a quantity work BEFORE it makes it to the 'total weight' box? Your example just shows 'name' and 'weight' inputs, and I saw inside the function notes on how it can do this (you mentioned coinage, as your example). How would that look if a quantity field was included, would it automatically detect it if the attr was correctly named? Sorry if this sounds ever so dumb and I admit, I should&nbsp; practice and play, but it's working like a well oiled machine right now and I fear breaking it. lol. EDIT: Apologies, I think GG highlighted this a few posts up. Information overload, my bad. I'll give it a good go!&nbsp;
1538697633

Edited 1538697656
GiGs
Pro
Sheet Author
API Scripter
There are two ways to do a coinage fieldset that occur to me. The one you ask about is like so: &lt;div class="row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Item &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Number &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &lt;fieldset class="repeating_coinage"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="text" name="attr_coinname"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="column"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="number" name="attr_coinnumber"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &lt;/fieldset&gt; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &lt;label&gt;Total: &lt;/label&gt; &nbsp; &nbsp; &lt;input type="number" name="attr_weight_coinage"&gt; So in this fieldset you enter only the number of coins. Assuming each coin is 0.02 weight: Then you'd use this: on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("weight_coinage", "coinage","coinnumber",false,0.02); }); since we dont have separate weight and quantity fields, the 4th parameter is set to false. And the 4th parameter is set to 0.02 and that will be a multiplier on the total number of coins to calculate weight. It occurred to me later though, that some systems have coins with different weight. A good way to represent that would be to replace the "itemname" with a select field, with options like "GP", "CP", "SP" and so on, and the value of those options wooild be that coin weight multiplier. So you'd put something like this isntead of the name, within the fieldset. &lt; select name="attr_cointype" &gt; &nbsp;&nbsp; &lt; option &nbsp;value =".05" &gt; Platinum &lt; /option &gt; &nbsp;&nbsp; &lt; option &nbsp;value =".02" &gt; Gold &lt; /option &gt; &nbsp;&nbsp; &lt; option &nbsp;value =".02" &gt; Silver &lt; /option &gt; &nbsp;&nbsp; &lt; option &nbsp;value =".01" &gt; Copper &lt; /option &gt; &lt; /select &gt; Which you would call like so: on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("weight_coinage", "coinage","coinnumber","cointype"); });
Great tip on the &lt;Select field&gt; with the values as differing weights, i'll be sure to use that if I can... though I believe it's a single currency for this system, but I am making frantic notes about everything I am learning here. :D
Hmm, I think I might need an additional Sheet Worker at play then, alongside this? One of my inventory lists has a quantity field. It looks like: &lt;Item Name&gt; | &lt;Quantity&gt; | &lt;Item Notes&gt; | &lt;Weight&gt; &nbsp;I really need that quantity field to change the weight on that row before the final weight is summed up as a total. If I understand this correctly, this function only listens for weights if they've been called for from within the sheet worker? What you provided before, for example: (in bold ) on('change:repeating_inventory remove:repeating_inventory sheet_opened', function() { repeatingSum("weight_coinage", "coinage","coinnumber", false,0.02 ); });
1538700121

Edited 1538700240
GiGs
Pro
Sheet Author
API Scripter
If I understand you correctly you are talking about a list something like: name: sword, itemquantity 1, itemweight: 5 name:arrows, &nbsp;itemquantity 10, itemweight 1 If so, that's answered by the earlier examples, and is exactly the case I tweaked finderski's function to handle. The call would be repeatingSum("weight_coinage", "coinage","itemweight","itemquantity");
1538700241

Edited 1538700314
Leothedino
Sheet Author
Oh hello, I think I just had a thunderbolt of understanding. With this in mind: function repeatingSum ( destination, section, fieldsum, fieldmult, totalmult ){ is this why the following Sheet Worker code is in this particular order? repeatingSum( "weight_coinage", "coinage","coinnumber",false,0.02 ); The top piece of code is the map for how to format the bottom? With this in mind, the quantity field is just another attribute that I can insert where '0.02' currently is?
1538700698

Edited 1538700796
GiGs
Pro
Sheet Author
API Scripter
In the repeatingsum formula, the third parameter is the "weight" that you sum up. Note that weight is in quotations because it might not be a weight. If you had a list of landholdings for example, you might list the monetary value of each. If you had a list of magical artifacts that add to your Power score, you might list the power each gives. For coins, you list how many of each type. There's lots of ways you might use such a list. It's called fieldsum, because its the number you sum up. However, some inventory lists have a separate quantity. You might need to know how many of each item you have. You might have two swords, or 10 arrows, whatever. In that case the 4th parameter, "fieldmult" is a per-item mulitipler.&nbsp; The fieldsum is the default value, whether it be weight of armour, weight of something carried, number of coins, value of house you own, whataver. The specific fieldset determines what that is. And if you need to have individual multipliers for each of those, thats when you use fieldsum. The final totalmult &nbsp;is ONLY used in special cases - where you need to multiply everything in an entire fieldset by a single fixed value.
1538704727
Finderski
Pro
Sheet Author
Compendium Curator
G G said: I made a tweak to finderski's function. This handles quantities and on/off statuses within the repeatingSimpleSum formula. That's cool. :)
GG, Finderski, Pat. I got it working! I am absolutely over the moon. Made my own repeating section, installed in the function you guys kindly sourced for me, and put together the sheet worker. I can even go through the function and make out a lot of which parts are doing what, a vast improvement from six hours ago! :D This was (I hope) the last 'big thing' my sheet needed, I am so grateful that you took the time to help me and i fully appreciate your patience, too. Seriously, thank you!
1538706040
GiGs
Pro
Sheet Author
API Scripter
That's great!
1538708672
Pat S.
Forum Champion
Sheet Author
G.G. I had a list of things I was going to use It on but then life kicked me between the legs like I was a football on kickoff. Maybe in time I will revisit my list but at the moment the sheet is mostly in maintance mode.
1538708758
GiGs
Pro
Sheet Author
API Scripter
Totally understandable, Pat.
1538775101

Edited 1538776530
GiGs
Pro
Sheet Author
API Scripter
I just noticed a minor typo in some of my earlier code. Where I've written&nbsp; sheet_opened , it should be&nbsp; sheet:opened . Example: this&nbsp; on('change:repeating_inventory remove:repeating_inventory sheet_opened ', function() { repeatingSum("weight_coinage", "coinage","itemweight","itemquantity"); }); should be on('change:repeating_inventory remove:repeating_inventory sheet:opened ', function() { repeatingSum("weight_coinage", "coinage","itemweight","itemquantity"); }); This ( sheet:opened ) runs the function whenever you open a character sheet, ensuring the any inventory/etc sections will always be correct in case of people editing values accidentally, or you changing the underlying character sheet code, etc. I also made a streamlined version of the sumRepeating code, thanks to Jakob's help in another thread, which I'll include here. Note that the version above and this one are&nbsp; identical &nbsp;in what they do. You can use whichever you feel like. The version above is much easier to understand, so if you are learning code as you go, it's probably the better one to use. The newer version is just a bit more compact. But it functionally does not matter which you use, they are called the same way and do the same thing. // destination = the name of the attribute that stores the total weight // section = name of repeating fieldset, without the repeating_ // fieldsum = the name of the "weight" field to be summed // fieldmult = the name of quantity field, that multiplies weight.&nbsp; //&nbsp; &nbsp; &nbsp; Leave as "false" if ignored. If using a checkbox rather than a number input, set its value to 1. // totalmult = a multiplier to ever item in the fieldset. For instance, coinage might be 0.02 each, so multiple the final total by 0.02 // you can leave fieldmult and totalmult off. let repeatingSum = function (destination, section, fieldsum, fieldmult, totalmult){ &nbsp; &nbsp; let multiplier = true; &nbsp; &nbsp; if (fieldmult === undefined || fieldmult === false || fieldmult === 'false') multiplier = false; &nbsp; &nbsp; if (totalmult === undefined) totalmult = 1; &nbsp; &nbsp; getSectionIDs(`repeating_${section}`, (idArray) =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; const sumFields = idArray.map(id =&gt; `repeating_${section}_${id}_${fieldsum}`); &nbsp; &nbsp; &nbsp; &nbsp; const multFields = multiplier ? idArray.map(id =&gt; `repeating_${section}_${id}_${fieldmult}`) : []; &nbsp; &nbsp; &nbsp; &nbsp; getAttrs(sumFields.concat(multFields), (v) =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log("===== values of v: "+ JSON.stringify(v) +" ====="); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let sumTotal = 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const rowValues = sumFields.map(attr =&gt; parseInt(v[attr], 10) || 0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(multiplier) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const rowMultiples = multFields.map(attr =&gt; parseInt(v[attr], 10) || 0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sumTotal = _.zip(rowValues, rowMultiples).map(([a, b]) =&gt; a*b).reduce((m, x) =&gt; m + x, 0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sumTotal = rowValues.reduce((m, x) =&gt; m + x, 0); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let setSumValue = {}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setSumValue[destination] = sumTotal * totalmult; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setAttrs(setSumValue);&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }
Oh, I actually noticed and caught that when I was doing my own attempt. No worries :D kept me on my game.&nbsp;