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

Button tabs within button tabs

I've put buttons on my sheet to separate all the sections, coded like so: html – <div>     <button type="action" name="act_x">Page X</button>     <button type="action" name="act_y">Page Y</button>     <button type="action" name="act_z">Page Z</button> </div> <input type='hidden' class='sheet-tabstoggle' name='attr_sheetTab'  value='x' /> <script type="text/worker">     const buttonlist = ["x","y","z"];     buttonlist.forEach(button => {         on(`clicked:${button}`, function() {             setAttrs({                 sheetTab: button             });         });     }); </script> CSS – .sheet-x, .sheet-y, .sheet-z { display: none; } .sheet-tabstoggle[value="x"] ~ div.sheet-x, .sheet-tabstoggle[value="y"] ~ div.sheet-y, .sheet-tabstoggle[value="z"] ~ div.sheet-z { display: block; } Now this works fine, but I would also like to have a separate set of buttons on one of the sections (e.g. Page Y) that display a set of sub-sections (e.g. Page Y1, Page Y2, ...). What's the trick to this? Or is it not possible? If I just duplicate the above but swap out all the section names (x, y and z) it doesn't work.
1628183271
Kraynic
Pro
Sheet Author
It would probably need to have a different naming scheme, so that it isn't altering the same value as the worker for your main tabs.  If you don't use a different naming scheme, then it will deselect the current main tab you are on causing it (and all content within it) to become hidden. Basically, you need the subtabs to NOT be tied to the sheetTab attribute.  Maybe use something like subtab or maybe ysubtab to differentiate that pages subtabs from another easily.
Thanks for the tip. That certainly seems pertinent, but has proven insufficient. I've tried adding the following to 'Page Y' (NB: name here is sheetTabs rather than sheetTab): <div> <button type="action" name="act_one">One</button> <button type="action" name="act_two">Two</button> <button type="action" name="act_three">Three</button> </div> <input type='hidden' class='sheet-tabstoggle' name='attr_sheetTabs'  value='one'  /> <div class='sheet-one'> 1 </div> <div class='sheet-two'> 2 </div> <div class='sheet-three'> 3 </div> And added the following to the script worker:       const buttonlist = ["one","two","three"];     buttonlist.forEach(button => {         on(`clicked:${button}`, function() {             setAttrs({                 sheetTabs: button             });         });     }); And added the following to the CSS: .sheet-one, .sheet-two, .sheet-three { display: none; } .sheet-tabstoggle[value="one"] ~ div.sheet-one, .sheet-tabstoggle[value="two"] ~ div.sheet-two, .sheet-tabstoggle[value="three"] ~ div.sheet-three { display: block; } The result is that the XYZ buttons don't work. What else would need changing?
1628241348

Edited 1628252148
GiGs
Pro
Sheet Author
API Scripter
It looks like you have used the variable buttonlist in that second set, does the first list also use it? If so, that's your problem - you cant set a variable with the same name twice with const. You can use just one sheet worker for both sets, if you did this: const  buttonlist = {          x :   "sheetTab" ,          y :   "sheetTab" ,          z :   "sheetTab" ,          one :   "sheetTabs" ,          two :   " sheetTabs " ,          three :   " sheetTabs "     };     buttonlist . forEach ( button   =>  {          on ( `clicked: ${ button } ` ,  function () {              setAttrs ({                  [ tabslist [ button ]]:   button             });         });     }); I'd recommend changing the names to be more descriptive, and make it easier to expand to more tabs on other pages. Lets say you had three pages, named 'character', 'minions'. and 'config'. On the character tab, you had three tabs, for 'stats', 'powers', and 'weapons'. I'd set that up like this: < div >      < button   type = "action"   name = "act_character" > Character </ button >      < button   type = "action"   name = "act_minions" > Minions </ button >      < button   type = "action"   name = "act_config" > Config </ button > </ div > < input   type = 'hidden'   class = 'tabstoggle'   name = 'attr_sheetTab'    value = 'character'    /> < div   class = "character" >      < button   type = "action"   name = "act_stats" > Stats </ button >      < button   type = "action"   name = "act_powers" > Powers </ button >      < button   type = "action"   name = "act_weapons" > Weapons </ button >      < span   name = "attr_characterTab" ></ span >      < input   type = 'hidden'   class = 'sheet-tabstoggle'   name = 'attr_characterTab'    value = 'stats'    />      < div   class = "stats" >         stats      </ div >      < div   class = "powers" >         powers              </ div >      < div   class = "weapons" >         weapons      </ div > </ div > < div   class = "minions" >     minions     </ div > < div   class = "config" >         config </ div > Notice I've used the same classname for the input inside the character tab, but I've changed its name. Then I need a sheet worker. const   tabslist  = {          character :   "sheetTab" ,          minions :   "sheetTab" ,          config :   "sheetTab" ,          stats :   "characterTab" ,          powers :   "characterTab" ,          weapons :   "characterTab"     };           Object.keys(tabslist). forEach ( button   =>  {          on ( `clicked: ${ button } ` ,  function () {              setAttrs ({                  [ tabslist [ button ]]:   button             });         });     }); Notice I can easily expand this for new tabs sets, but just adding extra lines to the tablist variable. And most importantly, I can look at the code and see what it is actually doing. Finally I need some CSS .sheet-character , .sheet-minions , .sheet-config , .sheet-stats , .sheet-powers , .sheet-weapons  {      display :  none ; } .sheet-tabstoggle [ value = "character" ] ~  div.sheet-character , .sheet-tabstoggle [ value = "minions" ] ~  div.sheet-minions , .sheet-tabstoggle [ value = "config" ] ~  div.sheet-config , .sheet-tabstoggle [ value = "stats" ] ~  div.sheet-stats , .sheet-tabstoggle [ value = "powers" ] ~  div.sheet-powers , .sheet-tabstoggle [ value = "weapons" ] ~  div.sheet-weapons  {      display :  block ; } Here I can just group all the rules together for convenience. CSS doesn't care where they are on the sheet. By using the same class name (tabsToggle), I have made copy and paste easier, and using actual descriptive names for the sections I've made it very easy to remember what part of the sheet is being affected. Note that you can use the same tabsToggle class name because the ~ CSS rule we are using to display/hide sections must be within the same container and at the same level. So the tabstoggle on the page tabs is at a different place to the one on the characterstab, so they don't affect each other.
Thanks GiGs, that's really informative. I'm afraid it's still not working for me though. I pasted all that code into a blank sheet and added a little text to each main and sub section, but it just displays everything all at once regardless of button-clicking. Any further guidance much appreciated!
1628252202

Edited 1628252274
GiGs
Pro
Sheet Author
API Scripter
I had an embarrassing number of syntax errors, but I've fixed them now (2 in the sheet worker, and 1 in the HTML). It should work now (it does in my testing - though I'm not using legacy mode, so my code doesn't have the sheet- part in classnames in the CSS).
Fantastic! Thank you so much, that's brilliant.