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

Help with dynamically creating/deleting fieldset rows

June 28 (3 weeks ago)

Edited June 28 (3 weeks ago)

Hello! I have what I feel is a pretty simple problem statement but which I cannot find a lot of resources to assist with.

I'm developing my own sheet for 2e AD&D and I'm maintaining two separate inventory sections- one for what is on someone's person, and one for their "stash" at home. I'd like to provide players a button to transfer items seamlessly between the two lists.


Basically I have two fieldsets which contain identically constructed attributes, and I'd like to use a sheet worker to allow clicking the button to delete a row from one fieldset and construct the same line item in the other fieldset. (Please forgive the oddly named attributes, I'm modifying and existing sheet and don't want to lose data.)


<fieldset name="repeating_gear" class="repeating_gear">
  <table>
    <tr>
      <td><input type="text" name="attr_geardesc"></td>
      <td><input type="number" name="attr_gearquantity"></td>
      <td><input type="number" name="attr_gearweigh"></td>
      <td><input type="number" name="attr_geartotal"></td>
      <td><input type="text" name="attr_gearloc"></td>
      <td><button type="roll" name="roll_send_down">&nbsp;Send</button></td>
    </tr>
  </table>
</fieldset>

<fieldset name="repeating_stash" class="repeating_stash">
  <table>
    <tr>
      <td><input type="text" name="attr_geardesc"></td>
      <td><input type="number" name="attr_gearquantity"></td>
      <td><input type="number" name="attr_gearweigh"></td>
      <td><input type="number" name="attr_geartotal"></td>
      <td><input type="text" name="attr_gearloc"></td>
      <td><button type="roll" name="roll_send_up">&nbsp;Send</button></td>
    </tr>
  </table>
</fieldset>


I assume I can get a sheet worker to execute a command when a button is pressed, and I actually see a way to remove a repeating set row via script worker, but I'm basically at a loss about creating a fieldset row in the other fieldset to match. Does anyone have suggestions or examples for this scenario? 

P.S. I'm also unfamiliar with how to format a code block on these forums. Markdown ``` is not functioning :(

June 28 (3 weeks ago)

Edited June 28 (3 weeks ago)
GiGs
Pro
Sheet Author
API Scripter

This isnt an answer to your specific question, but is a different solution. You can have the same fieldset with different displays, or in your example, the same fieldset displayed twice, exactly the same way. So you could just use the same name in both instances, and they'll include everything.do:

<fieldset class="repeating_gear">
  <table>
    <tr>
      <td><input type="text" name="attr_geardesc"></td>
      <td><input type="number" name="attr_gearquantity"></td>
      <td><input type="number" name="attr_gearweigh"></td>
      <td><input type="number" name="attr_geartotal"></td>
      <td><input type="text" name="attr_gearloc"></td>
      <td><button type="roll" name="roll_send_down">&nbsp;Send</button></td>
    </tr>
  </table>
</fieldset>

<fieldset class="repeating_gear">
  <table>
    <tr>
      <td><input type="text" name="attr_geardesc"></td>
      <td><input type="number" name="attr_gearquantity"></td>
      <td><input type="number" name="attr_gearweigh"></td>
      <td><input type="number" name="attr_geartotal"></td>
      <td><input type="text" name="attr_gearloc"></td>
      <td><button type="roll" name="roll_send_up">&nbsp;Send</button></td>
    </tr>
  </table>
</fieldset>


Also note that in fieldsets/repeating sections, the class is the name. Don't bother including the name.

June 28 (3 weeks ago)

Edited June 28 (3 weeks ago)

Thanks for the name/class distinction, I didn't realize that! But otherwise yes I know I can perfectly clone and maintain the state of the fieldset twice, that's just not related to the problem statement :(

The goal is to have two separate inventories for purpose of tracking weight/encumbrance, and to answer the idea of "what do you have as you set off on this trip". The two inventories have no value in being the same when you want to know whether that the extra longsword which weighs a few pounds is attached to the person's bag or it remained back home. The idea is to move items between these inventories to sort what's on your person.

I can iterate through a fieldset to determine the names of the items and their weights etc. but I don't have a way to create fieldset entries once I've read them

June 28 (3 weeks ago)

Edited June 28 (3 weeks ago)
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator

Creating a fieldset via sheetworker is simply done by setting an attribute with a repeating ID that doesn't exist in that fieldset. Real IDs are more complex than this obviously, but say you had rows in your stash with IDs -a,-b, and -c. You could make a new fourth row in the stash by just doing this:

setAttrs({"repeating_stash_-d_geardesc":"new gear description"});

You don't need to set every attribute in the section to create the section. Any attributes that you don't set for the new row will be implicitly created as empty attributes (equal to an empty string). You can also set a repeating attribute that doesn't exist in your html field, and the row will still be created, just without any data displayed in the html. You can also reuse IDs, so you could parse the id from the row that is being moved, and use that same ID for the row that you are creating.

I think that the Send button you have in your html is what you intend to use to trigger the sheetworker to move items? If that's the case, it needs to be an action button. Roll buttons can't trigger sheetworker functions; action buttons can.

<td><button type="action" name="act_send_up">↑&nbsp;Send</button></td>

<script type="text/worker">
//Listener for the button
on('clicked:repeating_store:send_up",function(event){...});
</script>

And, I would also recommend just using normal spaces instead of the html entity for a space. It will make your code more readable, and you won't run into possible issues with the html entity being parsed away by roll20's systems. e.g. replace "↑&nbsp;Send" with "↑ Send ".

Alternatively, you can use GiGs note about duplicate fieldsets with the same name and a simple checkbox to accomplish the filtered display that you are looking for without needing a sheetworker:

<div class="gear-container">
  <fieldset class="repeating_gear">
    <table>
      <tr>
        <td><input type="text" name="attr_geardesc"></td>
        <td><input type="number" name="attr_gearquantity"></td>
        <td><input type="number" name="attr_gearweigh"></td>
        <td><input type="number" name="attr_geartotal"></td>
        <td><input type="text" name="attr_gearloc"></td>
        <td><input class="equip-check" type="checkbox" name="attr_equipped" value="1" checked></td>
      </tr>
    </table>
  </fieldset>
</div>
<div class="stash-container">
  <fieldset class="repeating_gear">
    <table>
      <tr>
        <td><input type="text" name="attr_geardesc"></td>
        <td><input type="number" name="attr_gearquantity"></td>
        <td><input type="number" name="attr_gearweigh"></td>
        <td><input type="number" name="attr_geartotal"></td>
        <td><input type="text" name="attr_gearloc"></td>
        <td><input class="equip-check" type="checkbox" name="attr_equipped" value="1"></td>
</tr> </table> </fieldset>

and then just use css to filter the display:

.stash-container{
  .repitem:has(.equip-check:checked){
    display: none !important;
  }
}
.gear-container{
  .repitem:has(.equip-check:not(:checked)){
    display: none !important;
  }
}

The downside to the html and css method is of course that the duplicate fieldsets will still have the html content for the hidden elements, and those elements will contribute to paint time since css has to do the logic for whether to render them or not; but this shouldn't be an issue unless players routinely have gear/stashes of 100s of items. Which option is best for you depends on your comfort level with sheetworkers.

June 28 (3 weeks ago)
GiGs
Pro
Sheet Author
API Scripter


Con C. said:

The goal is to have two separate inventories for purpose of tracking weight/encumbrance, and to answer the idea of "what do you have as you set off on this trip". The two inventories have no value in being the same when you want to know whether that the extra longsword which weighs a few pounds is attached to the person's bag or it remained back home. The idea is to move items between these inventories to sort what's on your person.

I might be belaboring this, but you can have the same fieldset in two places with apparently different data. You could have inventory details in one copy and not in the other. One store exists, with all the data, but different copies of it are displayed. 

Otherwise you dont just have the problem of copying items from one set to another- when an item is just changed, you need to make sure those changes are copied to the other set. Using just one fieldset solves that issue. 

July 02 (3 weeks ago)

Thanks a bunch, this was exactly what I was looking for!

I didn't know it was possible to filter visible elements in such a simple way with that css, it solved the issue immediately! I agree it's impractical for large datasets but I don't expect my players to accrue large enough inventories for this to matter. Though separately I can already foresee expanding this design to use the thorough sheet worker solution in the near future to add different inventory groups ie. multiple stashes, inventory on horse, inventory on person vs. in backpack on back, etc. (where a single checkbox isn't going to cut it with sending gear around!) as players have expressed interest in more granularity, so the advanced solution with sheet workers has not gone unnoticed or unappreciated Scott :)

Thanks again this is exactly what I was hoping to learn. I'm not a frontend guy personally so it's enlightening to crawl these forums for wizard magic like this.

July 02 (3 weeks ago)
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator

Great to hear. Also, note you can do this with more complex assignment by using multiple check boxes with the same name but different values, or with a select that has a hidden input version of the attribute for the css to key off of. However, I think that if you get much past 3 duplicated sections that would be displayed at once, it would be better to go with the sheetworker method.