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

Custom CSheets, HTML, and Dependent Drop-Downs

I'm relatively new to HTML, but so far I haven't really had any issues that a bit of googling couldn't fix. I'm making a custom character sheet because I don't particularly care for any of the existing 5e sheets, plus I want to strengthen my HTML/CSS skills. I've run into an issue with drop-down lists, specifically I want to make a list for the subclasses that populates based on what's selected in my class list. The only methods I've found so far require loading from an external file (txt, json, or sql) and I'm not sure if that's possible in roll20. Is there another method? Maybe something involving a worker script? I've had a bit of trouble with those, too. Any help is greatly appreciated.
May 30 (8 years ago)
Finderski
Sheet Author
Compendium Curator
I don't believe a Sheet Worker will do the trick in this case, but I could be wrong.  Not very elegant, but you could create multiple drop down menus and use CSS to show one menu and hide the others based on the value of your class field.
May 30 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter
Sheet Workers would definitely allow you to do so. But it could not be distributed if you include content that is licensed.

5e may be a more mechanically simple system than say Pathfinder, but the amount of effort to make a sheet is immense. I've spent thousands of hours on shaped and I'm sure Steve has put in a lot of time on OGL. Creating something from scratch will take a lot of work. If you're interested in styling changes you could try stylish or add feature requests to either of our sheets - that'd be a lot less work.

Finderski said:

I don't believe a Sheet Worker will do the trick in this case, but I could be wrong.  Not very elegant, but you could create multiple drop down menus and use CSS to show one menu and hide the others based on the value of your class field.

That's an interesting idea, I hadn't even thought of that.

Kryx said:
Sheet Workers would definitely allow you to do so. But it could not be distributed if you include content that is licensed.

5e may be a more mechanically simple system than say Pathfinder, but the amount of effort to make a sheet is immense. I've spent thousands of hours on shaped and I'm sure Steve has put in a lot of time on OGL. Creating something from scratch will take a lot of work. If you're interested in styling changes you could try stylish or add feature requests to either of our sheets - that'd be a lot less work.
What would be considered licensed? I'm guessing anything that's not in the SRD... I suppose I could make a separate, SRD-only version down the line if I felt like distributing it. Also, I realize how much effort it is; I've already put in a few hours without much to show for it, but like I said, I'm trying to expand my knowledge of html and css. On top of that, I just like writing code.
I tried messing with a simple sheet worker just to get the experience for next level to update based on how much experience the character currently has and everything seemed right based on everything I was reading in examples and on the wiki/forums, but it simply wouldn't work. I think it had something to do with the way I was getting or setting attributes (maybe both?). Where could I find a simple example of a sheet worker that uses both getAttrs and setAttrs for just one or two attributes?
May 30 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter
Any WotC content not in the SRD or UA would not be distributable.

For accessing data: for Shaped I've wrapped all of the roll20 calls in my own wrappers so you'll have to ask someone else how to do it the vanilla way.

To address your initial question: to populate a <select> it will always have to be populated and you can then hide and show things in css via a hidden field. You can see examples of this behavior all over the Shaped sheet. In the case of <select>s you can see it by searching through my html (with the chrome inspector) looking for "sheet-srd-hidden".
I still haven't quite wrapped my head around hiding/showing fields, but I got my exp worker... well, working. I'm not sure what I did wrong last night, maybe I just needed a fresh look at things because I'm having no issues with it now. I was looking through the Shaped sheet in the chrome inspector and I have to say, I'm impressed. I really like how similar it is to the actual fifth edition character sheet, but is there a way to get it to show a separate spell sheet? I'm thinking of switching to Shaped from OGL while I work on my custom sheet, but my players and I prefer having spells on their own page, which neither of them seem to have.
May 30 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter
With 14.X.X you can view them on their own sheet. In earlier versions you can use "Expand/Contract".
I believe I've found a way to populate the drop-down menu, but I need to access the element via javascript and for some reason, document.getElementsByClassName() doesn't seem to work.

on("change:pc_class", function()
{
    getAttrs(["pc_class"], function(vals)
    {
        /*if(vals.pc_class)
            setAttrs({pc_name: "class is valid"}); this works, so I know the event is happening*/
        var list = document.getElementsByClassName('sclass dropdown'); //this breaks everything below it
        switch(vals.pc_class)
        {
            case "Barbarian":
                setAttrs({pc_name: "Barbarian"}); //this works, but only when I get rid of the getElements call
                break;
                
        }
    });
});
Does Roll20 have issues with getting elements this way or am I just missing something?
May 30 (8 years ago)
Jakob
Sheet Author
API Scripter
You can neither access nor manipulate the DOM in any way using sheet workers.

Jakob said:

You can neither access nor manipulate the DOM in any way using sheet workers.

Unfortunate, but good to know, thanks!
May 30 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter

Michael M. said:

Jakob said:

You can neither access nor manipulate the DOM in any way using sheet workers.
Unfortunate, but good to know, thanks!
Welcome to developing for Roll20. Enjoy. :D
The one thing I can't seem to figure out is how to retrieve the currently selected <option> from a <select>. If I could do that, I'm pretty sure I could show/hide the other <select>s based on that using the general sibling selector (~).
May 31 (8 years ago)
Lithl
Pro
Sheet Author
API Scripter

Michael M. said:

The one thing I can't seem to figure out is how to retrieve the currently selected <option> from a <select>. If I could do that, I'm pretty sure I could show/hide the other <select>s based on that using the general sibling selector (~).
You can't with CSS.

However, you could use a sheet worker to get the value of the attribute backing the select, and set the value of a checkbox or radio button (which you could hide) based on that value, and use the input's :checked pseudo-selector to show/hide other selects in CSS.

Or, even simpler, if you named the checkboxes/radio buttons the same as the first select (with each having the value of one of the options), Roll20 will propagate the attribute value to the checkboxes/radio buttons for you. For example:
<select name="attr_example">
<option value="1">The first option</option>
<option value="2">The second option</option>
</select>
<input type="radio" name="attr_example" class="sheet-hidden-radio sheet-first-option" value="1">
<input type="radio" name="attr_example" class="sheet-hidden-radio sheet-second-option" value="2">
<select name="attr_example-1" class="sheet-sub-option sheet-first-option">
<option value="1">First option's first sub-option</option>
<option value="2">First option's second sub-option</option>
</select>
<select name="attr_example-2" class="sheet-sub-option sheet-second-option">
<option value="1">Second option's first sub-option</option>
<option value="2">Second option's second sub-option</option>
</select>
.sheet-hidden-radio,
.sheet-sub-option {
display: none;
}

input.sheet-first-option:checked ~ select.sheet-first-option,
input.sheet-second-option:checked ~ select.sheet-second-option {
display: inline;
}
May 31 (8 years ago)

Edited May 31 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter
Due to how roll20 works there is a better way to structure the html and css:
<div>
  <select name="attr_class">
    <option value="Barbarian">Barbarian</option>
    <option value="Bard">Bard</option>
  </select>
</div>
<div>
  <input type="hidden" name="attr_class" class="class-name">
  <select name="attr_archetype" class="archetype">
    <option value="1" class="barbarian">First class's option</option>
    <option value="2" class="bard">Second class's option</option>
  </select>
</div>
.sheet-class-name:not([value='Barbarian']) ~ .sheet-archetype .sheet-barbarian,
.sheet-class-name:not([value='Bard']) ~ .sheet-archetype .sheet-bard {
  display: none;
}
I added the wrapper divs asumming you don't always want the selects next to eachother.
First of all, thank you both for your input. I know it's probably a little annoying dealing with someone like me who has very little experience with things like this. I'm much more used to working with C-based languages since I'm a game developer.
Brian, I was able to get your example working pretty easily. Kryx, I'd like to do it the way you are proposing since it involves less lines of code, but I can't seem to get it working. From what I understand, since the first select and the hidden input both have the same attribute associated with them, they should automatically share values because of how Roll20 works (just like it works for the radio buttons in Brian's example). The css should then see that value and hide the appropriate options. The problem is, even when I copy your example directly, it just doesn't want to work. Am I missing something?
May 31 (8 years ago)

Edited May 31 (8 years ago)
Kryx
Pro
Sheet Author
API Scripter
I missed sheet-
.sheet-class-name:not([value='Barbarian']) ~ .sheet-archetype .sheet-barbarian,
.sheet-class-name:not([value='Bard']) ~ .sheet-archetype .sheet-bard {
  display: none;
}
Your understanding of the other parts is correct.

From a CSS perspective you should limit the styling added. Meaning don't add a styling then remove it, just remove it when appropriate. That apporach makes large CSS files much much easier to understand and handle.
Okay, I should have noticed that since, you know, EVERYTHING starts with sheet-. I wasn't thinking clearly. Thanks again!