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

Checking Previous Checkboxes in a Grid

I have a character sheet set up in a grid to keep things well ordered. All stats and skills are given a value from 1-5. I want to use a series of checkboxes that fill to the value clicks and all previous values. I was going to use the radio button trick here, but having the radios under different divs messes things up pretty badly in that they all stay 'selected' in appearance;&nbsp; <a href="https://wiki.roll20.net/CSS_Wizardry#Fill_Radio_Buttons_to_the_Left" rel="nofollow">https://wiki.roll20.net/CSS_Wizardry#Fill_Radio_Buttons_to_the_Left</a> . I know the secret sauce is in the for loop, but I'm not sure of the best way to implement it. I tried setting strength_${i} &nbsp;to checked, but had poor results. Sample HTML &lt;!-- opening of grid a couple lines back here --&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_1" value="1" checked="checked"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_2" value="2"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_3" value="3"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_4" value="4"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_5" value="5"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;!-- Grid continues onward from here --&gt; SAMPLE JS &lt;script type="text/worker"&gt; const strengthValues = ["1","2","3","4","5"]; strengthValues.forEach(function(value) { on(`change:strength_${value}`, function() { let k = 0; &lt;!-- I am using k to make sure I am iterating through my loop correctly. It currently is! for (let i = 1; i &lt;= value; i++){ k++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- I need to iterate though my boxes to check up to the one clicked. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- For example, if someone clicks strength_3 while it is already clicked, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- it will click up strength_1 and 2, and also click 3 again. } &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- a for-loop will eventually go here that removes all checks from values higher than what is clicked setAttrs({ "strength": k }); }); }); &lt;/script&gt; I'm also concerned that changing the checkbox values in this for loop will trigger the event handler for those values as well. In the example above, clicking on 3 will also enabled selected clauses for 1 &amp; 2, triggering event handlers and make this an endless loop. I am also going to have a LOT of these by the time I'm done (24 different stats, ex Might, Agility, Smarts etc...). There an easier way to do the onChange event, or will I just need 24 for these in my code? Thanks in advance!
A more current script that is checking all boxes. I may need to find a way to pass something, or change the `change:...` to some other event handler. &lt;div&gt;&lt;input type="checkbox" name="attr_strength_1" value="1" checked="checked"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_2" value="2"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_3" value="3"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_4" value="4"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_5" value="5"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;script type="text/worker"&gt; const strengthValues = ["1","2","3","4","5"]; strengthValues.forEach(function(value) { on(`change:strength_${value}`, function() { if (value &gt; 0) { let k = 0; for (let i = 1; i &lt;= value; i++){ k++; setAttrs({ ["strength_" + i] : i }); } for (let j = 5; j &gt; value; j--) { setAttrs({ ["strength_" + j] : 0 }); } setAttrs({ "strength": k }); } }); }); &lt;/script&gt;
I'm thinking the trick may be using the eventInfo and only having it run when sourceType = player, but not quite sure how to get that across as of now.
1614363028
Kavini
Pro
Marketplace Creator
Sheet Author
Compendium Curator
When you use setAttrs, you can define the second parameter as an object. One of the parameters of that object can be silent , which will prevent propagation to other sheetworkers. i.e: setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;"strength": k }, { &nbsp;&nbsp;&nbsp;&nbsp;silent: true });
Figured it out. eventInfo was the key! Showing the code in case anyone stumbled across this at some point. &lt;div&gt;&lt;input type="checkbox" name="attr_strength_1" value="1" checked="checked"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_2" value="2"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_3" value="3"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_4" value="4"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_5" value="5"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;input type="hidden" name="attr_test" value="0"&gt; &lt;script type="text/worker"&gt; const strengthValues = ["1","2","3","4","5"]; strengthValues.forEach(function(value) { on(`change:strength_${value}`, function(eventinfo) { let key = eventinfo.sourceType; if (key == "player") { let k = 0; for (let j = 1; j &lt;= 5; j++) { setAttrs({ ["strength_" + j] : 0 }); } for (let i = 1; i &lt;= value; i++){ k++; setAttrs({ ["strength_" + i] : i }); } setAttrs({ "test": k }); } }); }); &lt;/script&gt;
Nic B. said: When you use setAttrs, you can define the second parameter as an object. One of the parameters of that object can be silent , which will prevent propagation to other sheetworkers. i.e: setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;"strength": k }, { &nbsp;&nbsp;&nbsp;&nbsp;silent: true }); The change to strength &nbsp;was not causing the issues. It was the changing of the associated strength_{#} &nbsp;values that were doing it in the for-loops, which is outside the scope of the setAttrs area. The eventInfo was able to handle this in the end. Good thought, though!
1614385516

Edited 1614468356
GiGs
Pro
Sheet Author
API Scripter
Your code will be more efficient if you rewrite it so the setAttrs isnt inside a loop. const &nbsp; strengthValues &nbsp;=&nbsp;[ '1' , '2' , '3' , '4' , '5' ]; strengthValues . forEach ( function ( value )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; on ( `change:strength_ ${ value } ` ,&nbsp; function ( eventinfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; key &nbsp;=&nbsp; eventinfo . sourceType ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;( key &nbsp;===&nbsp; 'sheetworker' ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; output &nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for &nbsp;( let &nbsp; j &nbsp;=&nbsp; 1 ;&nbsp; j &nbsp;&lt;=&nbsp; 5 ;&nbsp; j ++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ 'strength_' &nbsp;+&nbsp; j ]&nbsp;=&nbsp;( j &nbsp;&lt;=&nbsp; value )&nbsp;?&nbsp; j &nbsp;:&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output . test &nbsp;=&nbsp; value ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setAttrs ( output ); &nbsp;&nbsp;&nbsp;&nbsp;}); }); Note I reversed the eventinfo test, to check for worker instead, and to stop the sheet worker if true. Since it can only be 'player' or 'worker' this is a good way to simplify syntax. Secondly I removed one of the for loops by checking the value inside the loop. Finally this process creates an object variable, output, which holds the attributes you want to set. And stores them until you set them all at once with setAttrs. That said, I think a better approach is to use only one sheet worker, instead of creating 5 (one for each strength value). First, change your inputs like so: &lt;div&gt;&lt;input type="checkbox" name="attr_strength_1" value="1" checked="checked"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_2" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_3" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_4" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div&gt;&lt;input type="checkbox" name="attr_strength_5" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;input type="hidden" name="attr_test" value="0"&gt; Using a consistent value of 1 makes other code (like CSS testing for values) based on it a bit easier. With eventInfo.sourceAttribute we always know which button was clicked. So the sheet worker below has a bunch of things going on. I've inserted comments to try to explain most of it. //&nbsp;build&nbsp;a&nbsp;string&nbsp;for&nbsp;all&nbsp;5&nbsp;strength&nbsp;value&nbsp;inputs. const &nbsp; strengthValues &nbsp;=&nbsp;[ '1' , '2' , '3' , '4' , '5' ]; //&nbsp;build&nbsp;a&nbsp;string&nbsp;for&nbsp;all&nbsp;5&nbsp;strength&nbsp;value&nbsp;inputs. const &nbsp; strengthChanges &nbsp;=&nbsp; strengthValues . map ( value &nbsp; =&gt; &nbsp; `change:strength_ ${ value } ` ). join ( '&nbsp;' ); on ( strengthChanges ,&nbsp; eventinfo &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; key &nbsp;=&nbsp; eventinfo . sourceType ; &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;value&nbsp;-&nbsp;if&nbsp;it&nbsp;is&nbsp;0&nbsp;or&nbsp;higher. &nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; on &nbsp;=&nbsp;+ eventinfo . newValue &nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;last&nbsp;letter&nbsp;of&nbsp;name,&nbsp;and&nbsp;turn&nbsp;it&nbsp;into&nbsp;a&nbsp;number;&nbsp;not&nbsp;if&nbsp;on&nbsp;is&nbsp;zero,&nbsp;the&nbsp;input&nbsp;was&nbsp;unclicked. &nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; which &nbsp;=&nbsp;&nbsp;+ eventinfo . sourceAttribute . slice (- 1 )&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; if ( key &nbsp;===&nbsp; 'sheetworker' )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; output &nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp; for &nbsp;( let &nbsp; i &nbsp;=&nbsp; 1 ;&nbsp; i &nbsp;&lt;=&nbsp; 5 ;&nbsp; i ++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;the&nbsp;complicated&nbsp;test&nbsp;here&nbsp;checks: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;if&nbsp;input&nbsp;is&nbsp;below&nbsp;the&nbsp;button&nbsp;clicked,&nbsp;set&nbsp;it&nbsp;to&nbsp;1. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;if&nbsp;the&nbsp;input&nbsp;is&nbsp;EQUAL&nbsp;to&nbsp;button&nbsp;clicked,&nbsp;toggle&nbsp;between&nbsp;1&nbsp;and&nbsp;0&nbsp;based&nbsp;on&nbsp;last&nbsp;value &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;if&nbsp;input&nbsp;is&nbsp;above&nbsp;button&nbsp;clicked,&nbsp;set&nbsp;to&nbsp;zero. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ `strength_ ${ i } ` ]&nbsp;=&nbsp;( i &nbsp;&lt;&nbsp; which &nbsp;||&nbsp;( i &nbsp;===&nbsp; which &nbsp;&amp;&amp;&nbsp; on ))&nbsp;?&nbsp; 1 &nbsp;:&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; output . test &nbsp;=&nbsp; on &nbsp;?&nbsp; which &nbsp;:&nbsp; which &nbsp;- 1 ; &nbsp;&nbsp;&nbsp;&nbsp; setAttrs ( output ); }); Note: one change in this behaviour. Lets say the person has buttons 1-3 clicked and a value of 3. They then click button 3. Now this unclicks it, and leaves buttons 1-2 clicked. If you want to keep the same inputs having values 1-5, you just need to change one line: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ `strength_ ${ i } ` ]&nbsp;=&nbsp;( i &nbsp;&lt;&nbsp; which &nbsp;||&nbsp;( i &nbsp;===&nbsp; which &nbsp;&amp;&amp;&nbsp; on ))&nbsp;?&nbsp; i &nbsp;:&nbsp; 0 ;
Made a new html file and tried both of your codes. Neither of them are functioning as my code intended; back-selecting the checkboxes and selecting the one that is clicked, while unchecking all ahead of the clicked one. For example, if checkboxes 1-4 are currently checked and then the player clicks on box #2, only 1-2 will be checked and 3-5 will be unchecked. Both of your codes are currently only functioning as regular checkboxes for me. The simplification of the for loops is a good idea, though, and I'll be sure to implement that!
1614468431
GiGs
Pro
Sheet Author
API Scripter
I had a silly mistake in the code, I had used 'worker' instead of 'sheetworker' - the code is fixed. The first version also had an oversight with setting value that caused the test attribute to not be set - thats been fixed. Code above is updated!
Yep! I eventually figured out some of the errors and expanded the code to allow for multiple attributes. It is working pretty well. Now I'm just dredging the forums and wiki for hiding sections using JS since I can't use IDs. const dotValues = ["1","2","3","4","5"]; const statNames = ["might","athletics","endurance","exert","fortitude","meleeattack","agility","manipulation","rangedattack","ridepilot","physicaldefense","stealth","smarts","academics","arte","edge","mentalattack","profession","presence","influence","insight","mentaldefense","perception","survival"]; dotValues.forEach(function(value) { statNames.forEach(function(stat) { on(`change:${stat}_${value}`, function(eventinfo) { let key = eventinfo.sourceType; if (key == "sheetworker") { return; } var output = {}; for (let i = 1; i &lt;= 5; i++) { output[stat + '_' + i] = (i &lt;= value) ? i : 0; } output[stat + ""] = value; setAttrs(output); }); }); });
Figured it out. It was pretty painful in so far as I had to make a LOT of CSS handlers for the grid, despite the ease of the code. Tracks the HP number nhp &nbsp;and fills the physical php &nbsp;and mental mhp &nbsp;via some hidden attributes in a grid container, where the grids are listed as hidden until the values of the respective hidden attributes are set as 1. JS on("change:might change:agility change:smarts change:presence", function() { getAttrs(['might', 'agility', 'smarts', 'presence'], function(values) { let phy1 = parseInt(values['might'])||0; let phy2 = parseInt(values['agility'])||0; let men1 = parseInt(values['smarts'])||0; let men2 = parseInt(values['presence'])||0; let phy = phy1 + phy2; let men = men1 + men2; let loopcap = Math.max(phy, men); var buildhp = {}; for(let i = 3; i &lt;= 10; i++){ buildhp['nhp' + i] = (i &lt;= loopcap) ? 1 : 0; buildhp['php' + i] = (i &lt;= phy) ? 1 : 0; buildhp['mhp' + i] = (i &lt;= men) ? 1 : 0; } setAttrs(buildhp); }); }); HTML &lt;div class='sheet-block sheet-hpBox'&gt; &lt;div class='sheet-smallTitle sheet-hptitle'&gt;Health&lt;/div&gt; &lt;input type="hidden" class='sheet-togglephp3' name="attr_php3" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp4' name="attr_php4" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp5' name="attr_php5" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp6' name="attr_php6" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp7' name="attr_php7" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp8' name="attr_php8" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp9' name="attr_php9" value="0"&gt; &lt;input type="hidden" class='sheet-togglephp10' name="attr_php10" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp3' name="attr_mhp3" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp4' name="attr_mhp4" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp5' name="attr_mhp5" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp6' name="attr_mhp6" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp7' name="attr_mhp7" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp8' name="attr_mhp8" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp9' name="attr_mhp9" value="0"&gt; &lt;input type="hidden" class='sheet-togglemhp10' name="attr_mhp10" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp3' name="attr_nhp3" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp4' name="attr_nhp4" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp5' name="attr_nhp5" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp6' name="attr_nhp6" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp7' name="attr_nhp7" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp8' name="attr_nhp8" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp9' name="attr_nhp9" value="0"&gt; &lt;input type="hidden" class='sheet-togglenhp10' name="attr_nhp10" value="0"&gt; &lt;div class='sheet-nhp0'&gt;&lt;/div&gt;&lt;div class='sheet-php0'&gt;&lt;img src="<a href="https://i.ibb.co/d6LgGxf/phyIcon.png" rel="nofollow">https://i.ibb.co/d6LgGxf/phyIcon.png</a>" alt="Physical" style="width:30px;height:30px;"&gt;&lt;/div&gt;&lt;div class='sheet-mhp0'&gt;&lt;img src="<a href="https://i.ibb.co/xX1J8Qk/menicon.png" rel="nofollow">https://i.ibb.co/xX1J8Qk/menicon.png</a>" alt="Mental" style="width:30px;height:30px;"&gt;&lt;/div&gt; &lt;div class='sheet-nhp1'&gt;1&lt;/div&gt;&lt;div class='sheet-php1'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp1'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp2'&gt;1&lt;/div&gt;&lt;div class='sheet-php2'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp2'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp3'&gt;2&lt;/div&gt;&lt;div class='sheet-php3'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp3'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp4'&gt;2&lt;/div&gt;&lt;div class='sheet-php4'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp4'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp5'&gt;3&lt;/div&gt;&lt;div class='sheet-php5'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp5'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp6'&gt;3&lt;/div&gt;&lt;div class='sheet-php6'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp6'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp7'&gt;4&lt;/div&gt;&lt;div class='sheet-php7'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp7'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp8'&gt;4&lt;/div&gt;&lt;div class='sheet-php8'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp8'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp9'&gt;5&lt;/div&gt;&lt;div class='sheet-php9'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp9'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class='sheet-nhp10'&gt;5&lt;/div&gt;&lt;div class='sheet-php10'&gt;&lt;input class='sheet-phyhpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class='sheet-mhp10'&gt;&lt;input class='sheet-menthpbox' type="checkbox" value="1"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt; &lt;/div&gt; &lt;!-- end hpBox --&gt; CSS .sheet-hptitle { grid-column: 1 / 4; grid-row: 1; } .sheet-nhp0 { grid-column: 1; grid-row: 2; } .sheet-nhp1 { grid-column: 1; grid-row: 3; margin-top: 3px; } .sheet-nhp2 { grid-column: 1; grid-row: 4; margin-top: 3px; } .sheet-nhp3 { grid-column: 1; grid-row: 5; display: none; margin-top: 3px; } .sheet-nhp4 { grid-column: 1; grid-row: 6; display: none; margin-top: 3px; } .sheet-nhp5 { grid-column: 1; grid-row: 7; display: none; margin-top: 3px; } .sheet-nhp6 { grid-column: 1; grid-row: 8; display: none; margin-top: 3px; } .sheet-nhp7 { grid-column: 1; grid-row: 9; display: none; margin-top: 3px; } .sheet-nhp8 { grid-column: 1; grid-row: 10; display: none; margin-top: 3px; } .sheet-nhp9 { grid-column: 1; grid-row: 11; display: none; margin-top: 3px; } .sheet-nhp10 { grid-column: 1; grid-row: 12; display: none; margin-top: 3px; } .sheet-php0 { grid-column: 2; grid-row: 2; } .sheet-php1 { grid-column: 2; grid-row: 3; } .sheet-php2 { grid-column: 2; grid-row: 4; } .sheet-php3 { grid-column: 2; grid-row: 5; display: none; } .sheet-php4 { grid-column: 2; grid-row: 6; display: none; } .sheet-php5 { grid-column: 2; grid-row: 7; display: none; } .sheet-php6 { grid-column: 2; grid-row: 8; display: none; } .sheet-php7 { grid-column: 2; grid-row: 9; display: none; } .sheet-php8 { grid-column: 2; grid-row: 10; display: none; } .sheet-php9 { grid-column: 2; grid-row: 11; display: none; } .sheet-php10 { grid-column: 2; grid-row: 12; display: none; } .sheet-mhp0 { grid-column: 3; grid-row: 2; } .sheet-mhp1 { grid-column: 3; grid-row: 3; } .sheet-mhp2 { grid-column: 3; grid-row: 4; } .sheet-mhp3 { grid-column: 3; grid-row: 5; display: none; } .sheet-mhp4 { grid-column: 3; grid-row: 6; display: none; } .sheet-mhp5 { grid-column: 3; grid-row: 7; display: none; } .sheet-mhp6 { grid-column: 3; grid-row: 8; display: none; } .sheet-mhp7 { grid-column: 3; grid-row: 9; display: none; } .sheet-mhp8 { grid-column: 3; grid-row: 10; display: none; } .sheet-mhp9 { grid-column: 3; grid-row: 11; display: none; } .sheet-mhp10 { grid-column: 3; grid-row: 12; display: none; } .sheet-togglephp3[value="1"] ~ div.sheet-php3, .sheet-togglephp4[value="1"] ~ div.sheet-php4, .sheet-togglephp5[value="1"] ~ div.sheet-php5, .sheet-togglephp6[value="1"] ~ div.sheet-php6, .sheet-togglephp7[value="1"] ~ div.sheet-php7, .sheet-togglephp8[value="1"] ~ div.sheet-php8, .sheet-togglephp9[value="1"] ~ div.sheet-php9, .sheet-togglephp10[value="1"] ~ div.sheet-php10, .sheet-togglenhp3[value="1"] ~ div.sheet-nhp3, .sheet-togglenhp4[value="1"] ~ div.sheet-nhp4, .sheet-togglenhp5[value="1"] ~ div.sheet-nhp5, .sheet-togglenhp6[value="1"] ~ div.sheet-nhp6, .sheet-togglenhp7[value="1"] ~ div.sheet-nhp7, .sheet-togglenhp8[value="1"] ~ div.sheet-nhp8, .sheet-togglenhp9[value="1"] ~ div.sheet-nhp9, .sheet-togglenhp10[value="1"] ~ div.sheet-nhp10, .sheet-togglemhp3[value="1"] ~ div.sheet-mhp3, .sheet-togglemhp4[value="1"] ~ div.sheet-mhp4, .sheet-togglemhp5[value="1"] ~ div.sheet-mhp5, .sheet-togglemhp6[value="1"] ~ div.sheet-mhp6, .sheet-togglemhp7[value="1"] ~ div.sheet-mhp7, .sheet-togglemhp8[value="1"] ~ div.sheet-mhp8, .sheet-togglemhp9[value="1"] ~ div.sheet-mhp9, .sheet-togglemhp10[value="1"] ~ div.sheet-mhp10 { display: block; }