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

HarnMaster Gold character sheet: 'locked' columns in scrolling grid

July 20 (1 year ago)
Steven T.
Sheet Author

Hello everyone,

I'm new to creating character sheets and I'm working on a HarnMaster Gold sheet based on the existing HarnMaster 3 implementation by Olaf van Tol.  One of the things I want to change is the missile weapons, in order to fix some display problems and support longer missile weapon ranges (we're using GunMaster Gold by Bill Gant for firearms).

What I want to try and do is create some 'locked' columns, as in a spreadsheet, and allow the unlocked columns to scroll.  I've done this by using two repeating sections with the same class, but showing different columns.  One of the repeating sections is in a div that can be scrolled, to
give this effect:

Since both repeating_sections use the same class, they show the same data in the same order and usually line up correctly.  But, there are a few actions, like re-ordering the rows on the left, that do not cause the sheet to re-draw on the right and it will get out of alignment.  Any modifications to the data cause both to be re-drawn and then they line up correctly again, but it's annoying.

Does anyone know a better way to do this, or a way to force the scrolling repeating section to re-draw from e.g. a sheet worker?

Thanks!

July 20 (1 year ago)

Edited July 20 (1 year ago)
GiGs
Pro
Sheet Author
API Scripter

Reording repeating sections with a sheet worker is generally not advised. The function supplied for that is buggy.

There are ways to fake it, but it's better off avoided. That said, you might not need to do that.

When you create two repeating sections with the same class, you are in fact creating one repeating section, but making two copies of it. Any data you put in one is available in both, but it might not be displayed.

For your needs, since the copies are in almost the same place, you might be able to just using one copy of a repeating section (thus reordering works properly), and use CSS to display the right half with the scroll bar.

I'm not sure if this is the way to go, but I'd need some code to experiment with. You'd need to post the existing code for your section - HTML and CSS.

July 20 (1 year ago)
Steven T.
Sheet Author

Thanks!

It would be ideal to have a single repeating section with only the right side scrollable, if that's at all possible.
I've cut the code down to a smaller (if not minimal) example.

<div class='inventory-grid-section inven-missileweapons colored-grid'>
    <div class="missilecontainer-grid">
        <div class="missileweapons-grid">
	        <div class="skill-header skill-value">Missile Weapon</div>
            <div class="skill-header skill-value">ML</div>
            <div class="skill-header skill-value">Ammo</div>

            <fieldset class="repeating_missileweapon">
                <input type="text" name="attr_missileweapon_name" class="skill-value">
                <input type="number" name="attr_missileweapon_ml" class="skill-value" value="0">
                <input type="number" name="attr_missileweapon_ammo" class="skill-value">
            </fieldset> 
        </div>
        <div class="missile-ranges-grid">
            <div class="skill-header skill-value">4</div>
            <div class="skill-header skill-value">8</div>
            <div class="skill-header skill-value">16</div>  
            <div class="skill-header skill-value">32</div>
            <div class="skill-header skill-value">64</div>
            <div class="skill-header skill-value">128</div>
            <div class="skill-header skill-value">256</div>
            <div class="skill-header skill-value">512</div>
            <div class="skill-header skill-value">1024</div>

            <!-- Default values for medium projectile and range class 2 firearm.  Totally different for bows and suchlike! -->
            <!-- nbsp might be replaced by a check box to hide that range-data (e.g. for weapons that can't fire so far) -->
            <fieldset class="repeating_missileweapon">
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_4_mod_ml" class="skill-value" value="15">
                    <input type="number" name="attr_missileweapon_4_mod_dmg" class="skill-value" value="0">                    
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_8_mod_ml" class="skill-value" value="10">
                    <input type="number" name="attr_missileweapon_8_mod_dmg" class="skill-value" value="0">                     
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_16_mod_ml" class="skill-value" value="0">
                    <input type="number" name="attr_missileweapon_16_mod_dmg" class="skill-value" value="0">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_32_mod_ml" class="skill-value" value="-10">
                    <input type="number" name="attr_missileweapon_32_mod_dmg" class="skill-value" value="-1">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_64_mod_ml" class="skill-value" value="-20">
                    <input type="number" name="attr_missileweapon_64_mod_dmg" class="skill-value" value="-2">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_128_mod_ml" class="skill-value" value="-40">
                    <input type="number" name="attr_missileweapon_128_mod_dmg" class="skill-value" value="-4">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_256_mod_ml" class="skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_256_mod_dmg" class="skill-value" value="-6">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_512_mod_ml" class="skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_512_mod_dmg" class="skill-value" value="-9">
                </div> 
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_1024_mod_ml" class="range-data-ml skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_1024_mod_dmg" class="skill-value" value="-12">
                </div>
            </fieldset>
	</div>
    </div>
</div>

And the CSS

.inventory-grid-section {
   padding: 0px 3px;	
   grid-row-gap: 2px;
}

.missilecontainer-grid {
  display: grid;
  grid-template-columns: 0.75fr 1.25fr;
}

.missileweapons-grid,
.missileweapons-grid .repcontainer > .repitem {
   display: grid;
   grid-template-columns: 15fr 4fr 4fr;
   align-items: center;	
   align-content: baseline;
}

.missile-ranges-grid .skill-header {  
  grid-column: span 2;
}

.missile-ranges-grid .range-data {
  grid-column: span 2;
  display: flex;
}

.missile-ranges-grid {
  overflow-x: scroll;
  border-left: 1px solid black;
}

.missile-ranges-grid,
.missile-ranges-grid .repcontainer > .repitem {
  display: grid;
  grid-template-columns: repeat(18, 4em);
  align-items: center; 
  align-content: baseline;
}

.charsheet .repcontainer,
.charsheet .repcontrol  {
	display: grid;
	grid-column: 1/-1;
}

.colored-grid {
	border: grey 2px solid;
  border-radius: 8px;
	background-color: var(--background-grid);
}

July 20 (1 year ago)

Edited July 20 (1 year ago)
GiGs
Pro
Sheet Author
API Scripter

I havent tried it yet, but your code construction suggests to me, you could simply move the fieldset up in the hierarchy a bit, and keep your divs inside the fieldset. Have you tried this, and if so, what went wrong?

To be clear, I'm talking about something like this:

<!-- moved the headings out: the CSS for this would have to be created -->
<fieldset class="repeating_missileweapon">
    <div class='inventory-grid-section inven-missileweapons colored-grid'>
        <div class="missilecontainer-grid">
            <div class="missileweapons-grid">

                <input type="text" name="attr_missileweapon_name" class="skill-value">
                <input type="number" name="attr_missileweapon_ml" class="skill-value" value="0">
                <input type="number" name="attr_missileweapon_ammo" class="skill-value">

            </div>
            <div class="missile-ranges-grid">
                <!-- Default values for medium projectile and range class 2 firearm.  Totally different for bows and suchlike! -->
                <!-- nbsp might be replaced by a check box to hide that range-data (e.g. for weapons that can't fire so far) -->
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_4_mod_ml" class="skill-value" value="15">
                    <input type="number" name="attr_missileweapon_4_mod_dmg" class="skill-value" value="0">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_8_mod_ml" class="skill-value" value="10">
                    <input type="number" name="attr_missileweapon_8_mod_dmg" class="skill-value" value="0">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_16_mod_ml" class="skill-value" value="0">
                    <input type="number" name="attr_missileweapon_16_mod_dmg" class="skill-value" value="0">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_32_mod_ml" class="skill-value" value="-10">
                    <input type="number" name="attr_missileweapon_32_mod_dmg" class="skill-value" value="-1">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_64_mod_ml" class="skill-value" value="-20">
                    <input type="number" name="attr_missileweapon_64_mod_dmg" class="skill-value" value="-2">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_128_mod_ml" class="skill-value" value="-40">
                    <input type="number" name="attr_missileweapon_128_mod_dmg" class="skill-value" value="-4">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_256_mod_ml" class="skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_256_mod_dmg" class="skill-value" value="-6">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_512_mod_ml" class="skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_512_mod_dmg" class="skill-value" value="-9">
                </div>
                <div class="range-data">
                    <input type="number" name="attr_missileweapon_1024_mod_ml" class="range-data-ml skill-value" value="-99">
                    <input type="number" name="attr_missileweapon_1024_mod_dmg" class="skill-value" value="-12">
                </div>

            </div>
        </div>
    </div>
</fieldset>

This doesn't contain headings - a div above the fieldset containing the headings would be good.


Have you tried this?

July 21 (1 year ago)

Edited July 21 (1 year ago)
Steven T.
Sheet Author

Yes, it results in each individual row being independently scrollable, like this (I didn't bother putting the headings back in):



This prevents the rows getting out of order, but the column headers might have to go into each row and that, along with the scrollbar, would really bloat the vertical size of the rows.

It does make me wonder if all the scrollbars but the bottom could be hidden and then all (or just the bottom) scrollbar could be used to scroll all the rows at the same time.

<edit> I'm not sure it's possible to do that in a roll20 sheet. :-(

July 21 (1 year ago)
GiGs
Pro
Sheet Author
API Scripter

Ah, that makes sense. The scrollbars could be hidden, I'll have to look at the code for to put a scroll bar for the whole section.

July 22 (1 year ago)
Steven T.
Sheet Author


GiGs said:

Ah, that makes sense. The scrollbars could be hidden, I'll have to look at the code for to put a scroll bar for the whole section.


Well, I'm stumped.  I can't see a better way (than 2 sections) to do this without sheet workers with access to the DOM.  I'll have to go back to scrolling the entire grid, unless there's some clever trick or roll20-specific thing I'm missing.