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

Repeating Section Question

1591302184
Eli N.
Pro
Compendium Curator
I have a repeating section for tracking wounds                 <fieldset class="repeating_wounds">                     <div class="sheet-col-1-16"></div>                     <div class="sheet-col-1-8">Wounds</div>                     <div class="sheet-col-1-8"><input type="number" name="attr_woundname" value="0"/></div>                     <div class="sheet-col-1-8"><input type="number" name="attr_woundname_days" value="0"/></div>                     <div class="sheet-col-1-8"></div>                     <div class="sheet-col-3-8"><input type="ntext" name="attr_wound5" /></div>                     <div class="sheet-col-1-16"></div>                 </fieldset> Is there a way so the first one says wound 1, then wound 2 then wound 3 and so on? 
1591309512
GiGs
Pro
Sheet Author
API Scripter
Where do you want it to say say "wound 1" ?  Also what does the wound5 attribute represent? Do you really want Wounds there? That will be repeated on every row of the field section. You have a lot of empty divs there, what's going on with those?
1591327842
Eli N.
Pro
Compendium Curator
Sorry It shouldn't say wound5, I want it to say Wound 1, Wound 2 instead of Wound #                 <fieldset class="repeating_wounds">                     <div class="sheet-col-1-8">Wound #</div>                     <div class="sheet-col-1-8"><input type="number" name="attr_woundname" value="0"/></div>                     <div class="sheet-col-1-8"><input type="number" name="attr_woundname_days" value="0"/></div>                     <div class="sheet-col-3-8"><input type="ntext" name="attr_wound" /></div>                 </fieldset> That ways I get Wound 3, A box for would size, box for wound days to heal, and then a box for notes. I have all the boxes working fine, I just need the text to change. 
1591329331

Edited 1591332248
GiGs
Pro
Sheet Author
API Scripter
You can do it with the CSS counter property. For your HTML: <h2 class="wound-reset"></h2> <fieldset class="repeating_wounds">     <div class="sheet-col-1-8 wound-counter"></div>     <div class="sheet-col-1-8"><input type="number" name="attr_woundname" value="0"/></div>     <div class="sheet-col-1-8"><input type="number" name="attr_woundname_days" value="0"/></div>     <div class="sheet-col-3-8"><input type="ntext" name="attr_wound" /></div> </fieldset> The h2 at the start can be replaced with anything. If you have a heading or any item just before the fieldset, add wound-reset to its class. It's just something that has to be before the fieldset. Notice in the fieldset, that first div is empty. Leave it empty. The CSS will fill it. Then for your CSS: .charsheet .sheet-reset {     counter-reset: wound-counter; } div.sheet-wound-counter::before {     /* Increments "wound-counter" by 1 */     counter-increment: wound-counter;     content: "Wound " counter(wound-counter); } This will create Wound 1, Wound 2, etc., in order. And if players reorder wounds, or delete some, the wound numbers will remain consistent: the first will always be #1, the second #2, etc.
1591372608
Eli N.
Pro
Compendium Curator
The previous incarnation of this character sheet had current health set up  <div class="sheet-col-1-12"><input type="number" name="attr_hp" value="@{hp|max}-@{wound1}-@{wound2}-@{wound3}-@{wound4}-@{wound5}-@{wound6}-@{wound7}-@{wound8}-@{wound9}-@{wound10}" disabled="disabled"/></div> How would I replace that with my new repeating fields?  I guess I also need to write a script worker that would transition any current values into this repeating field so it doesn't delete anyone's information, is that correct? Or is there a way I can rename my repeating field so I don't need a script worker?  Currently wounds 1-10 have just these two fields of actual information                 <div class="sheet-col-1-8"><input type="number" name="attr_wound1" value="0"/></div>                 <div class="sheet-col-1-8"><input type="number" name="attr_wound1_days" value="0"/></div>
1591380532
GiGs
Pro
Sheet Author
API Scripter
You would need to use a sheet worker to handle this. Here's one that should do the trick: on('change:hp_max change:repeating_wounds:wound sheet:opened', () => {     getSectionIDs('repeating_wounds', idarray => {         const fieldnames = [];         idarray.forEach(id => fieldnames.push(`repeating_wounds_${id}_wound`));         getAttrs([...fieldnames, 'hp_max'], v => {             const hp_max = parseInt(v.hp_max) || 0;             const hp = hp_max - fieldnames.reduce((total, item) => total += (parseInt(v[item]) || 0), 0);             setAttrs({hp});         });     }); }); To get this working you have to fix an error in your repating section's HTML: <div class="sheet-col-3-8"><input type="ntext" name="attr_wound" /></div> The type there isnt valid. It should be type="text" or type="number" I recommend number.
1591382106

Edited 1591382272
Eli N.
Pro
Compendium Curator
The script worker doesn't appear to be having any effect. Whatever value I set as attr_hp doesn't change. I copied it exactly as stated above. I changed the layout of my repeating section to be                      <div class="sheet-col-1-8"><input type="number" name="attr_wound" value="0"/></div>                     <div class="sheet-col-1-8"><input type="number" name="attr_wound_days" value="0"/></div>                     <div class="sheet-col-3-8"><input type="text" name="attr_wound_notes" /></div> Also, I just noticed this, why does  @{hp|max}  work, but not this  @{hp_max}?                  <div class="sheet-col-1-12"><input type="number" name="attr_hp"  value="@{hp|max}" disabled="disabled"/></div>                 <div class="sheet-col-1-12"><input type="number" name="attr_hp_max" value="0"/></div> I tried just setting the value of attr_hp to several things, but that shouldn't matter right? As the script worker will just overwrite whatever the value is set to.  Should the SetAttrs be structured with hp: hp?
1591382408

Edited 1591382462
GiGs
Pro
Sheet Author
API Scripter
You need to get rid of the disabled on the hp line: <div class="sheet-col-1-12"><input type="number" name="attr_hp"  value="" readonly /></div> Then the sheet worker will calculate it for you. Sheet workers cant change disabled attributes. @{hp|max} is the syntax you use for dice rolls, hp_max is the syntax you use in sheetworkers. It's irritating we have to use different syntaxes, but thats the way it is. setAttrs can be structured with hp:hp,  but when both sides of the : are the same, you dont need to.
1591384290
Eli N.
Pro
Compendium Curator
Thanks! That did the trick
1591384739
GiGs
Pro
Sheet Author
API Scripter
you're welcome :)
1591386431
Eli N.
Pro
Compendium Curator
In order to transition current character sheets that have a non-repeating field wound section to a repeating wound section would this Sheet Worker work? Obviously with more sections for wound2 through 10 on('sheet:opened',function() {         getAttrs(['wound1', 'wound2','wound3','wound4','wound5','wound6','wound7','wound8','wound9','wound10','wound1_days','wound2_days','wound3_days','wound4_days','wound5_days','wound6_days','wound7_days','wound8_days','wound9_days','wound10_days'], function(values) {             if (values.wound1 > 0) {                 setAttrs({'repeating_wounds_1_wound': values.wound1,                           'repeating_wounds_1_wound_days': values.wound1_days});             }         });     });
1591388752

Edited 1591388772
GiGs
Pro
Sheet Author
API Scripter
There are two problems with that. The major problem is it would run every time you opened the sheet, so it would keep overwriting new values with old values. The other problem is you can't create new repeating sections that way. You need a function to create new rows.  To solve the first problem, create a hidden attribute: <input type="hidden" name="attr_codeversion" value="0" />  Then you need to create two functions. First the following sheet worker: on('sheet:opened', function () {     getAttrs(['codeversion'], function (values) {         if ((parseFloat(values.codeversion) || 0) < 1) {             updateWounds();         }     }); }); What this function does: very time the sheet is opened, it checks the codeversion attribute. If it is 1 or higher, it does nothing. If it is less than 1, it launches a function to convert the wound boxes to a repeating section. that function will also set the codeversion  attribute to a value of 1. So after the update function has run once, it will never run again. The update function is below. What it does: it builds an array of all the wound attributes, from 1-10, and gets their values.  Then it loops through 1 to 10, and checks in order, the wound1, wound2, etc attribute. If there is a value, it creates a new rowid for the section id, and creates new attribute names for the wound, wound_days, and wound_notes within that section, and grabs the corresponding values from the old stats. Then it sets code_version to 1 and updates the sheet. function updateWounds() {     const fieldnames = [];     const rows = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];     rows.forEach(num => fieldnames.push(`wound${num}`, `wound${num}_days`, `wound${num}_notes`));     getAttrs(fieldnames, function (values) {         const output = {};         const getValue = field => (values[field] != 'undefined') ? values[field] : '';         rows.forEach(row => {             const wound = parseInt(values[`wound${row}`]) || 0;             if (wound > 0) {                 const rowid = generateRowID();                 output[`repeating_wounds_${rowid}_wound`] = wound;                 output[`repeating_wounds_${rowid}_wound_days`] = getValue(`wound${row}_days`);                 output[`repeating_wounds_${rowid}_wound_notes`] = getValue(`wound${row}_notes`);             }         });         output.codeversion = 1;         setAttrs(output);     }); } If your old attributes dont have a wound1_notes section, you just need to make two changes: Change this line rows.forEach(num => fieldnames.push(`wound${num}`, `wound${num}_days`, `wound${num}_notes`)); to rows.forEach(num => fieldnames.push(`wound${num}`, `wound${num}_days`)); and delete this line:                 output[`repeating_wounds_${rowid}_wound_notes`] = getValue(`wound${row}_notes`);
1591393381
Eli N.
Pro
Compendium Curator
The hidden attribute should be outside the repeating section correct?
1591393573
GiGs
Pro
Sheet Author
API Scripter
Yes, you can put it anywhere/ I'd put it right at the start of your sheet. It's hidden, so players never see it, and its a hidden sheet setting so may as well put it where its easily accessible when you're looking at the design.
1591402298
Eli N.
Pro
Compendium Curator
Ugh oh, when I add those elements it no longer calculates the current HP Also I tested it on a game and it did not create any repeating sections. 
1591402460
Eli N.
Pro
Compendium Curator
aaaaaaaannnd It was my fault. nevermind. 
1591403112
GiGs
Pro
Sheet Author
API Scripter
hehe, glad you got it sorted.