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

Linking the number of Visible Health Boxes to a changable humber

1671122435
Chris Jones
Pro
Sheet Author
Hello all. I'm using a character sheet whereby characters can have a varying Max health, represented by Health boxes on the page. At the moment, we have a number field where users input their max health, but there's still the same number of boxes visable on the sheet. I know you can use CSS code to hide certain elements, but i don't know if i can tie this to a field where users enter a number, as opposed to a checkbox.  This is what i have in the HTML for my max health box at the moment:                         <input style="width: 40px" type="number" name="attr_maxhealth" />                     And this is the code for the multi-state Health boxes.   <div align="center" class="sheet-health-box">                             <input type="radio" class="sheet-health-box sheet-no-health" name="attr_health-box9" value="0" />                             <input type="radio" class="sheet-health-box sheet-bashing-health" name="attr_health-box9" value="1" />                             <input type="radio" class="sheet-health-box sheet-lethal-health" name="attr_health-box9" value="2" />                             <input type="radio" class="sheet-health-box sheet-aggravated-health" name="attr_health-box9" value="3" checked="checked"                             />                             <span class="sheet-health-box sheet-no-health"></span>                             <span class="sheet-health-box sheet-bashing-health"> ∕ </span>                             <span class="sheet-health-box sheet-lethal-health">☓</span>                             <span class="sheet-health-box sheet-aggravated-health"></span>                         </div> It looks like this on the page: Any ideas if this is doable? Cheers Chris
1671124535
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
There are a couple ways to do this. Is there a (reasonable) upper limit on health?
1671124888
Chris Jones
Pro
Sheet Author
Yeah, the max is only 15, so we don't need to go too far
1671223472
Chris Jones
Pro
Sheet Author
Anyone else have any thoughts on this?
1672782712
Chris Jones
Pro
Sheet Author
Now we've cleared the New year I thought I'd see if anyone had any ideas about this one
1672783809
Andrew R.
Pro
Sheet Author
The official 13th Age sheet does this for Recoveries, so it’s doable. Sadly, we don’t get to look at it in the Git repository. 
1672786881

Edited 1672831732
GiGs
Pro
Sheet Author
API Scripter
I do this a lot, but I use a lot of hidden attributes, a sheet worker, and CSS. Basically you start with a master stat, like health_max, that can't go above 15. I assume that you have a div that contains each input. You need to add a class to each div, and hidden input with a different name before every sing;e div, like so: < input style = " width: 40px " type = "number" name = "attr_health_max" /> < input type = "hidden" class = " health- toggle " name = "attr_toggle_health9" value = "0" /> < div align = "center" class = "sheet-health-box health-hide" > The hidden input needs to be named with the health bar, as in this case toggle_health9. For health button 3, that would need to be < input type = "hidden" class = "health- toggle " name = "attr_toggle_health3" value = "0" /> < div align = "center" class = "sheet-health-box health-hide" > Notice you need to add a health-toggle class to the input, and a health-hide class to the div. Then in your CSS sheet create the following rule: input. health - toggle [ value = "0" ] + div.health-hide {     display : none ; } The + selector here means it will select only the very next element. So you can use the same classes over multiple elements, and it'll work for all 15 health divs. Note: it looks like you might be using legacy code, so the above CSS declaration would look like: input. sheet-health - toggle [ value = "0" ] + div.sheet-health-hide {     display : none ; } Everything else is the same. You don't need to add the sheet- part to the html tab (though you can if it seems neater). Finally, add the following sheet worker to your HTML page: on ( 'change:health_max sheet:opened' , () => {         getAttrs ([ 'health_max' ], values => {             const output = {};             const max = + values . health_max || 0 ;             for ( let n = 0 ; n <= 15 ; n ++) {                 output [ `toggle_health ${ n } ` ] = n <= max ? 1 : 0 ;             }             setAttrs ( output );         });     }); This will set the value of the hidden toggle inputs appropriataly when max health changes. Notice I changed the name of the max health stat to health_max. This is so that the health bars for tokens work properly. When you have a health (or any attribute), there is a hidden attribute with _max appaended to the name. Thus when you add a stat to a token, its current value and max value are set appropriately.
1672831866
GiGs
Pro
Sheet Author
API Scripter
So to summarise the previous step: Change maxhealth stat to health_max before each stat div, add a hidden input with a name that includes the health you want it to remain visible Add a class to the hidden input and the div. Add a CSS rule to hide the divs Add a sheet worker to trigger when health_max changes, which sets the value of the hiddent attributes. It's a pretty simple process, it just looks complicated.
1672838176
Chris Jones
Pro
Sheet Author
Thanks for the reply, really appreciate the detail there. I'm unfortunately not getting any success, so i suspect i've missed something simple! It has managed to hide the health boxes at least, however the x and / symbols (used for different damage types) is visible instead. This is the code i have at the moment in my html doc. I copied yourCSS text into my CSS file  <td colspan="3">  <label style="width: 120px;margin-left: 50px;; padding-right: 0px">Max Health:</label>  <input style="width: 40px" type="number" name="attr_health_max" />  </td>  <tr> on('change:health_max sheet:opened', () => {         getAttrs(['health_max'], values => {             const output = {};             const max = +values.health_max || 0;             for(let n = 0; n <= 15; n++) {                 output[`toggle_health${n}`] = n <= max ? 1: 0;             }             console.info(output)             setAttrs(output);         });     }); </tr> <td colspan="3" align="right" valign="middle"> <div style="text-align: center; ">margin-left:80px"> >>>> Everything below  repeats for health boxes 2-15  <<<<                         <div align="center" class="health-toggle health-hide">                             <input type="hidden" class="health-toggle sheet-no-health" name="attr_toggle_heath-box1" value="0" />                             <input type="hidden" class="health-toggle sheet-bashing-health" name="attr_toggle_heath-box1" value="1" />                             <input type="hidden" class="health-toggle sheet-lethal-health" name="attr_toggle_heath-box1" value="2" />                             <input type="hidden" class="health-toggle sheet-aggravated-health" name="attr_toggle_heath-box1" value="3" />                             <span class="health-toggle sheet-no-health"></span>                             <span class="health-toggle sheet-bashing-health"> ∕ </span>                             <span class="health-toggle sheet-lethal-health">☓</span>                             <span class="health-toggle sheet-aggravated-health"></span>                         </div>
1672840504
GiGs
Pro
Sheet Author
API Scripter
You need to put thesheet worker inside a scrupt block. The scriptblock looks like this: <script type="text/worker"> </script> For maximum efficiency this should be the last thing in your html file, and all your sheet workers go inside that. So with the sheet worker above, it would look like <script type="text/worker">     on('chan ge:health_max sheet :opened', () => {         getAttrs(['health_max'], values => {             const output = {};             const max = +values.health_max || 0;             for(let n = 0; n <= 15; n++) {                 output[`toggle_health${n}`] = n <= max ? 1: 0;             }             setAttrs(output);         });     }); </script> If you add any extra sheet workers, they'd go inside the same script block.
1672840779

Edited 1672843080
GiGs
Pro
Sheet Author
API Scripter
Also, your divs need a hidden input directly before each one, not inside the div, like so <input type="hidden" class="health-toggle" name="attr_toggle_health1" value="0" /> <div align="center" class="health-toggle health-hide">     <!-- code for health-box 1 - which should be completely unchanged from your original code --> </div> <input type="hidden" class="health-toggle" name="attr_toggle_health2" value="0" /> <div align="center" class="health-toggle health-hide">     <!-- code for health-box 2 --> <!-- and so on --> The classes of the hidden input boxes don't matter, except for the toggle class, because the input will never be visible. Note that the name of these hidden inputs must perfectly match the names defined inside the sheet worker on this line: output[`toggle_health${n}`] = n <= max ? 1: 0; The toggle_health${n} is the name of the input, with the ${n} changing to a number (from 0 to 15) created by the for loop.
1672840953
GiGs
Pro
Sheet Author
API Scripter
Finally, remember you might need to add sheet- to the class names in the CSS file - it depends on whether you are using legacy code or not. I had tested the code above, so I know it works. If you still have problems, you might need to share the complete html and css files in something like pastebin.com so I can see where the problem lies.
1672848073
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
I'll add that you don't actually need the sheetworker. You can do this with just html/css like so: HTML <input type="number" name="attr_health_max" value="10"> <div class="fill-left"> <input class="fill-left__radio" name="attr_health" value="1" type="checkbox" title="@{health}"/> <input type="checkbox" hidden value="1" class="fill-display-control" name="attr_health_max"> <input class="fill-left__radio" name="attr_health" value="2" type="checkbox" title="@{health}"/> <input type="checkbox" hidden value="2" class="fill-display-control" name="attr_health_max"> <input class="fill-left__radio" name="attr_health" value="3" type="checkbox" title="@{health}"/> <input type="checkbox" hidden value="3" class="fill-display-control" name="attr_health_max"> <input class="fill-left__radio" name="attr_health" value="4" type="checkbox" title="@{health}"/> <input type="checkbox" hidden value="4" class="fill-display-control" name="attr_health_max"> <input class="fill-left__radio" name="attr_health" value="5" type="checkbox" title="@{health}"/> </div> CSS .fill-display-control:checked ~ .fill-left__radio{ display:none!important; } And, not directly related to your question, but to get the checkboxes above to fill in left to right is slightly different from the wiki example, that css looks like: .ui-dialog .tab-content .charsheet .fill-left__radio { appearance: none; -webkit-appearance: none; /* Using black as a placeholder fill color */ background-color: black; width: 100%; height: 100%; cursor: pointer; } .ui-dialog .tab-content .charsheet .fill-left__radio:checked ~ .fill-left__radio { background-color: transparent; }
1672849620
Chris Jones
Pro
Sheet Author
Thanks everyone - against my own coding inadequacies I've managed to get it working! Thanks very much!
1673018869

Edited 1673019239
GiGs
Pro
Sheet Author
API Scripter
Scott C. said: I'll add that you don't actually need the sheetworker. You can do this with just html/css like so: Nice. I dont use :checked so I never thought of doing it that way.