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

Filter Repeating Section

Hello, I'm having a hard time trying to figure out how what I want to achieve.  I have two repeating sections.  Repeating section #1 is an inventory section, filled with items with a simple name input. Repeating section #2 is meant to be a filtered version of #1, where it only shows certain items based on name inputted.  Both repeating sections are meant control each other, meaning if you delete from one, it deletes from the other.  Any help or guidance would be greatly appreciated!
1717767074
GiGs
Pro
Sheet Author
API Scripter
Roll20 doesn't allow us to create truly dynamic html, so what you want might not be possible. If you describe what you want with specifics, we might be able to tell you a way to do it.
1717779391

Edited 1717779667
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
This is actually pretty straightforward. There are a couple different ways to go about it too: Two separate repeating sections and you populate the filtered section via sheetworker as the user changes the name to filter by Filtered section is a repeat of the non filtered section (i.e. same repeating section name) and you use css to control the display Both methods require some JS to do. The performance of each is probably close to identical, but I'm going to demonstrate the second option (reuse the section name) as I think it will provide a slightly better user experience and we won't need to create JS to keep the values of the filtered and unfiltered views in sync. You'll need a couple pieces for this method: The HTML for each section CSS to control the display in the filtered version of the section Javascript to control some attributes HTML I'm going to provide some very basic html. I'll note the sections that are essential for this method and you can add to it as you need to for your use case. <h2>Source Section</h2> <fieldset class="repeating_equipment"> <!-- the name of the item. Currently this is all we are filtering for and the only data that the user sees in the section. You can add additional data for the section as you see fit --> <input type="text" name="attr_name"> </fieldset> <h2>Filtered Section</h2> <!-- an input for the user to enter what to filter by (the equipment name in this case) --> <label> <span>name to filtere for:</span> <input type="text" name="attr_equipment_filter"> </label> <!-- a wrapper class to let us target when our filtering css applies --> <div class="filtered-section"> <fieldset class="repeating_equipment"> <!-- the name of the item. Currently this is all we are filtering for and the only data that the user sees in the section. You can add additional data for the section as you see fit --> <input type="text" name="attr_name"> <!-- this input will control whether the repeating item is displayed or not. This is the piece that actually makes this technique function. --> <input type="checkbox" class="filter-control" hidden name="attr_filtered" value="1"> </fieldset> </div> CSS The CSS for this is just one declaration. Note that I have prepended the css with .ui-dialog .tab-content .charseet . This is because this is a standard practice of mine to ensure that my css overrides the R20 default CSS and that all of my css operates from the same base specificity level. /* Checks each repeating item to see if the filter control checkbox contained in it is checked or not. Then sets the ones that don't contain a checked on to display none. */ .ui-dialog .tab-content .charsheet .filtered-section .repitem:has(.filter-control:not(:checked)){ display: none !important; } Note that :has  is a relatively new CSS selector. Browser support for it is about 92% globally , but for Roll20 purposes it is much higher as all browsers that Roll20 actively supports have :has implementation. Javascript The javascript is probably the most complex part of this. it's also where you could do the most. This JS does a very simple text filter on the name, but you can do whatever logic you want. //List of attributes contained in our repeating section that we want to filter by, or that control the filtering. Make sure to update this with the actual attributes that you want to filter by. const equipmentFilterAttributes = ['name','filtered']; //We setup a listener to look for changes in our filter input and the names of the equipment so that if the user later adds an item that matches the filter, it will be added to our filtered view on('change:equipment_filter change:repeating_equipment:name',(event) => { getSectionIDs('repeating_equipment',(idArray) => { //Assemble our array of attributes to get for the filter operation. This will include all the filterable attributes from the repeating section. const getArr = idArray.reduce((m,id) => { m.push(...equipmentFilterAttributes.map(n => `repeating_equipment_${id}_${n}`)) return m; },['equipment_filter']); getAttrs(getArr,(attributes) => { //Empty object to accumulate our changes in so that we can use just a single setAttrs const setObj = {} //Iterate over each repeating row and check if the name contains the name to search for. //Your actual filter logic can be anything you want, just make sure to set the row's filtered attribute to 1 if it meets the criteria and 0 if it doens't. idArray.forEach(id => { //create the row prepend so we don't have to remake it for all operations const row = `repeating_equipment_${id}`; let filtered = 0; const rowName = attributes[`${row}_name`].toLowerCase(); const filterName = attributes.equipment_filter.toLowerCase(); if( filterName && rowName.includes(filterName) ){ setObj[`${row}_filtered`] = 1; }else{ setObj[`${row}_filtered`] = 0; } }); setAttrs(setObj,{silent:true}); }) }) }) And putting it all together gives us behavior like this:
Scott C, this is exactly what I needed. Thank you very much for taking the time to help! I really appreciate the notes and details in the code, Javascript is a bit of a newer venture for me so it's still a bit difficult to grasp at times.  Thanks again, cheers!