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

How to target option wich are in a repeatable section ?

1696774678

Edited 1696774711
Shey L'Ours
Pro
Sheet Author
Hard question for a problem I was thinking simple. Here, i'm try to filter injuries, my game have more of 100 differents. So I use a selector for the "area" (zone) and another for the "kind" (type). Its in french, but its mainly part of the body and kind of weapons. Problem is that I was using (in the same situation but oustide of repeating) class to show/hide options. If I choose "jambe" so every other sheet-(area) than sheet-jambe, I was addClass sheet-hidden and removeClass sheet-hidden to the one selected. And same for the kind of injuries. There is the HTML. < fieldset id = "BLESSURES" class = "repeating_blessures" >             < div class = "sheet-blessure-section" >                 < select type = "text" name = "attr_blessure-zone" class = "sheet-150" >                     < option class = "sheet-nothidden" selected value = "none" >✗</ option >                     < option type = "text" value = "jambe" >Jambe</ option >                     < option type = "text" value = "bras" >Bras</ option >                     < option type = "text" value = "torse" >Torse</ option >                     < option type = "text" value = "tete" >Tête</ option >                     < option type = "text" value = "special" >Spécial</ option >                     < option type = "text" value = "permanente" >Perma.</ option >                 </ select >                                 < select type = "text" name = "attr_blessure-type" class = "sheet-200" >                     < option class = "sheet-nothidden" selected value = "none" >✗</ option >                     < option value = "contendant" >Contendant</ option >                     < option value = "tranchant" >Tranchant</ option >                     < option value = "perforant" >Perforant</ option >                 </ select >                 < select type = "text" name = "attr_blessure-name" class = "sheet-300" >                     < option class = "sheet-nothidden" selected value = "none" >✗</ option >                     < option class = "sheet-jambe sheet-contendant" >Jambe 1</ option >                     < option class = "sheet-jambe sheet-perforant" >Jambe 2</ option >                     < option class = "sheet-jambe sheet-tranchant" >Jambe 3</ option >                     < option class = "sheet-bras sheet-contendant" >Bras 1</ option >                     < option class = "sheet-bras sheet-perforant" >Bras 2</ option >                     < option class = "sheet-bras sheet-tranchant" >Bras 3</ option >                     < option class = "sheet-torse sheet-contendant" >Torse 1</ option >                     < option class = "sheet-torse sheet-perforant" >Torse 2</ option >                     < option class = "sheet-torse sheet-tranchant" >Torse 3</ option >                     < option class = "sheet-tete sheet-contendant" >Tête 1</ option >                     < option class = "sheet-tete sheet-perforant" >Tête 2</ option >                     < option class = "sheet-tete sheet-tranchant" >Tête 3</ option >                     < option class = "sheet-special sheet-contendant" >Special 1</ option >                     < option class = "sheet-special sheet-perforant" >Special 2</ option >                     < option class = "sheet-special sheet-tranchant" >Special 3</ option >                     < option class = "sheet-permanente sheet-contendant" >Permnante 1</ option >                     < option class = "sheet-permanente sheet-perforant" >Permnante 2</ option >                     < option class = "sheet-permanente sheet-tranchant" >Permnante 3</ option >                 </ select >                 < input type = "number" name = "attr_blessure_itt" value = "0" class = "sheet-35" >             </ div >         </ fieldset > My issue is that in a repeating section, I'm unable to make the difference between class. In the line 1, 3 or 10, sheet-(area) will still be sheet-(area) and so I'm unable to correctly sort my injuries. I've try many things, but I don't sucessfully reach my goal. When I'm targetting blessure-name wich is the select where the options are, I'm only able to get the value of it. I'm looking for any idea you can have for solve that. And if you know how to call only the options wich are in the select repeating_blessure_${id}_blessure-name, it may help that ? :/ Here is my actuel JS, wich is like unfinished :/ < script id = "✓-SCRIPTCALC : BLESSURES" type = "text/worker" >             on("change:repeating_blessures", function(eventInfo) {                 getSectionIDs("repeating_blessures", function(ids) {                     console.log("IDs des lignes existantes : " + ids.join(", "));                             ids.forEach(function(id) {                         var sheetBlessureZoneId = `repeating_blessures_${id}_blessure-zone`;                         var sheetBlessureTypeId = `repeating_blessures_${id}_blessure-type`;                         var sheetBlessureNameId = `repeating_blessures_${id}_blessure-name`;                                 getAttrs([sheetBlessureZoneId, sheetBlessureTypeId, sheetBlessureNameId], function(values) {                             var choosenZone = values[sheetBlessureZoneId] || '';                             var choosenType = values[sheetBlessureTypeId] || '';                             var choosenName = values[sheetBlessureNameId] || '';                                     console.log(`ID : ${id} - Zone / Type / Name : ${choosenZone} / ${choosenType} / ${choosenName}`);                                     const zoneOptions = ['jambe', 'bras', 'torse', 'tete', 'special', 'permanente'];                             const typeOptions = ['contendant', 'tranchant', 'perforant'];                             zoneOptions.forEach(function(zone) {                                 const zoneOptionClass = `.sheet-${zone}`;                                 const zoneOptionDiv = $20(zoneOptionClass);                                         if (zone === choosenZone) {                                     zoneOptionDiv.removeClass('sheet-hidden');                                 } else {                                     zoneOptionDiv.addClass('sheet-hidden');                                 }                             });                                     typeOptions.forEach(function(type) {                                 const typeOptionClass = `.sheet-${type}`;                                 const typeOptionDiv = $20(typeOptionClass);                                         if (type === choosenType) {                                     typeOptionDiv.removeClass('sheet-hidden');                                 } else {                                     typeOptionDiv.addClass('sheet-hidden');                                 }                             });                         });                     });                 });             });         </ script >
1696781405

Edited 1696781448
GiGs
Pro
Sheet Author
API Scripter
I'm going to suggest abandoning the use of addClass and removeClass. Instead use a hidden attribite, and set its value to 0 or 1. Give it a class, and then have a CSS rule that shows or hides the area you want to show or hide using a pure CSS solution. It looks like you have a getAttrs inside a loop there, which is one of the most basic mistakes people do with repeating sections. Your sheet worker should look like this: on ( "change:repeating_blessures:blessure-zone change:repeating_blessures:blessure-type change:repeating_blessures:blessure-name" , function ( eventInfo ) {     getSectionIDs ( "repeating_blessures" , function ( ids ) {         const fields = [];         ids . forEach ( function ( id ) {             fields . push ( `repeating_blessures_ ${ id } _blessure-zone` ,             `repeating_blessures_ ${ id } _blessure-type` ,             `repeating_blessures_ ${ id } _blessure-name` );         });         getAttrs ( fields , function ( values ) {             const output = {}; // this is used for the later setAttrs - any attribute values you create go here.             ids . forEach ( function ( id ) {                 var choosenZone = values [ `repeating_blessures_ ${ id } _blessure-zone` ] || '' ;                 var choosenType = values [ `repeating_blessures_ ${ id } _blessure-type` ] || '' ;                 var choosenName = values [ `repeating_blessures_ ${ id } _blessure-name` ] || '' ;                 // this is where your work goes             });             setAttrs ( output );         });     }); }); The work part inside the final forEach needs to be created, and I don't know what that would look like because I would need to see the html of your repeating section and now which sections you were trying to show or hide. Or what exactly you were trying to do.
1696782562
Shey L'Ours
Pro
Sheet Author
Still trying to process your idea, letting you know what is looking like at the same time ! 
1696887058
Shey L'Ours
Pro
Sheet Author
Actually, most of my thing are working with what I've start.  The only thing I struggling with, is that lane:  $20(`select[name="attr_blessure-name"] option`).addClass('sheet-hidden'); that I've try so many way to target the option I want to delete This upper one is working, but hide every option of every line since I don't target a specific line, so i've try a lot $20(`repeating_blessure_${id} select[name="attr_blessure-name"] option`).addClass('sheet-hidden'); $20(`repeating_blessure_${id}_blessure-name option`).addClass('sheet-hidden'); $20(`.repeating_blessure_${id}_blessure-name option`).addClass('sheet-hidden'); $20(`.repeating_blessure_${id} option`).addClass('sheet-hidden'); $20(`.repeating_blessure_${id} select option`).addClass('sheet-hidden'); I'm not familiar with this thing, I'm not sure how to correctly write it :/
1696893074
GiGs
Pro
Sheet Author
API Scripter
Shey L'Ours said: Actually, most of my thing are working with what I've start.  The only thing I struggling with, is that lane:  $20(`select[name="attr_blessure-name"] option`).addClass('sheet-hidden'); Should this be? $20(`select[name="blessure-name"] option`).addClass('sheet-hidden');
1696895448
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
GiGs said: Shey L'Ours said: Actually, most of my thing are working with what I've start.  The only thing I struggling with, is that lane:  $20(`select[name="attr_blessure-name"] option`).addClass('sheet-hidden'); Should this be? $20(`select[name="blessure-name"] option`).addClass('sheet-hidden'); Nope, because the name is the name property of the attribute, which includes the attr_.
1696895623
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
The problem you are running into is that the row ID that is passed to all events in the javascript is all lowercased, but the actual id is many cased. The only way that you are going to be able to do this is pretty complicated: hide the default add row button for your repeating section(s) Create an action button that will trigger a sheetworker to create new rows for your section(s) In the sheetworker to create rows, store the actual id of the row in an attribute with its correct casing. Get that raw ID attribute value for use in your jquery targeting
1696908294
GiGs
Pro
Sheet Author
API Scripter
It sounds like the method I suggested, of outputting hiddent attribute values that have their own classes, will be easier. But it's hard to know how to build code for that without seeing the section's HTML and knowing what you want to use the classes for.
1696918606

Edited 1696918668
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
GiGs said: It sounds like the method I suggested, of outputting hiddent attribute values that have their own classes, will be easier. But it's hard to know how to build code for that without seeing the section's HTML and knowing what you want to use the classes for. Yep, it's what I'd probably do for this. My post was meant to show all the hoops required to jump through to achieve it with the current methodology. And I didn't even include needing to redo the class application on each sheet open event.
1696944096
Shey L'Ours
Pro
Sheet Author
GiGs said: It sounds like the method I suggested, of outputting hiddent attribute values that have their own classes, will be easier. But it's hard to know how to build code for that without seeing the section's HTML and knowing what you want to use the classes for. I've sent the HTML in the very first post and what is look like, some time before, let me know what you exactly need and I can surely provide. My goal is hide/show options depending of the two other select.  Example : I get an arrow in the chest. So the "zone" will be chest and the "type" will be "perforant". When the player have choose thoses two options. It hide all the injuries not corresponding and show all those wich fit the case. Nothing seem simple with thoses sheetworker, may I just choose the easy way to have many option below the select and hope player will not harm themself to often :X
1696949334
GiGs
Pro
Sheet Author
API Scripter
The HTML in your first post includes only one div. But your repeating section sheet worker is trying tov add/remove a class from two divs.So I'm not sure whatever bits you are trying to show or hide. So, forget the sheet worker. Can you describe exactly what you want to happen?
1696953786
GiGs
Pro
Sheet Author
API Scripter
By the way, the basic principle is this. First put a hidden input directly before the part you want to show or hide. Give a name you can access in the ssheet worker, and value of 0 or 1 Give it a class you'll access in the CSS: Give the div that follows its own class. <input type="hidden" name="attr_stat" class="hide" value="0"> <div class="toggle"> <!-- this is the area that will hide or show --> </div> Then create css to show or hide that div based on the value of the hidden input .charsheet hide:not([value="1"] ) ~ div.toggle { display: none; } Finally create a sheet worker that sides the value of that input to 1 or 0. I cant incolude a sheet worker, because I don't know exactly what you want arranged here, or when it should be triggered, but hopefully you get the idea.
1697059462

Edited 1697061863
Shey L'Ours
Pro
Sheet Author
Thanks for the precision, I was busy trying to make it work and i'm happy to say I've reach almost the same result as your solution. So its look like a good news. My CSS : .sheet-blessure-type-list-hideshow [ value = "1" ] ~ .sheet-blessure-name-jambe-contendant-div, .sheet-blessure-type-base-hideshow [ value = "1" ] ~ .sheet-blessure-name-jambe-contendant-div {     display: block !important ; } .sheet-blessure-type-list-hideshow[value="0"]~.sheet-blessure-name-jambe-contendant-div, .sheet-blessure-type-base-hideshow[value="0"]~.sheet-blessure-name-jambe-contendant-div {     display: none !important ; } My HTML :      <fieldset id="BLESSURES" class="repeating_blessure"> <div class="sheet-blessure-section">                 <!-- //// ZONE BASE //////////////////////// --> <select type="text" name="attr_blessure-zone" class="sheet-100"> <option class="sheet-nothidden" selected value="none">✗</option> <option type="text" value="bras">Bras</option> <option type="text" value="torse">Torse</option> <option type="text" value="jambe">Jambe</option> <option type="text" value="tete">Tête</option> <option type="text" value="special">Special</option> <option type="text" value="permanent">Permanent</option> </select> < !-- //// TYPE BASE //// -->       < input class = "sheet-blessure-type-base-hideshow sheet-always-hidden" type = "number" name = "attr_blessure-type-base-hideshow" value = "1" />       < input class = "sheet-100 sheet-blessure-type-base-div" selected value = "✗" disabled >       <!-- //// TYPE LIST //// -->       < input class = "sheet-blessure-type-list-hideshow sheet-always-hidden" type = "number" name = "attr_blessure-type-list-hideshow" value = "0" />           < select   class = "sheet-100 sheet-blessure-type-list-div" type = "text" name = "attr_blessure-type-list" >                < option selected value = "none" >✗</ option >                < option type = "text" value = "contendant" >Contendant</ option >                < option type = "text" value = "tranchant" >Tranchant</ option >                < option type = "text" value = "perforant" >Perforant</ option >            </ select > My JS: < script id = "✓-SCRIPTCALC : BLESSURES" type = "text/worker" >             on("change:repeating_blessure:blessure-zone", function() {                 getAttrs(["repeating_blessure_blessure-zone", "repeating_blessure_blessure-type-base-hideshow", "repeating_blessure_blessure-type-list-hideshow"], function(values) {                     var blessureZone = values["repeating_blessure_blessure-zone"] || "";                     var baseHideshow = parseInt(values["repeating_blessure_blessure-type-base-hideshow"]) || 0;                     var listHideshow = parseInt(values["repeating_blessure_blessure-type-list-hideshow"]) || 0;                             console.log(`BZ : ${blessureZone}`);                     console.log(`Base Before : ${baseHideshow}`);                     console.log(`List Before : ${listHideshow}`);                             if (blessureZone === "jambe" || blessureZone === "bras" || blessureZone === "torse" || blessureZone === "tete") {                         console.log("List Affichée / Base Cachée");                         var attrsToSet = {};                         attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 0;                         attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 1;                         setAttrs(attrsToSet);                     } else {                         console.log("List Cachée / Base Affichée");                         var attrsToSet = {};                         attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 1;                         attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 0;                         setAttrs(attrsToSet);                     }                 });             });         </ script > Last thing is. That it actually setAttrs to attr_ But it don't update live the value on my line like this one : < input value = "0" /> Value always stay 0. Did I make a wrong move somewhere ?
1697062791

Edited 1697063128
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Edit: ignore what was here, I misread the code. I don't usually use the shortcut repeating section syntax, so I can't actually tell if your javascript is correct or not. Check your developer console (ctrl-shift-J on chrome) and see if you get an error about "attempted to set a repeating attribute, but no id provided" showing up. There's also a small code critique. Generally you want there to only be a single setAttrs in a given function line, so I'd recommend changing your code to: <script id="✓-SCRIPTCALC : BLESSURES" type="text/worker"> on("change:repeating_blessure:blessure-zone", function() { getAttrs(["repeating_blessure_blessure-zone", "repeating_blessure_blessure-type-base-hideshow", "repeating_blessure_blessure-type-list-hideshow"], function (values) { // updated var to let/const as these are preferable in modern JS let blessureZone = values["repeating_blessure_blessure-zone"] || ""; let baseHideshow = parseInt(values["repeating_blessure_blessure-type-base-hideshow"]) || 0; let listHideshow = parseInt(values["repeating_blessure_blessure-type-list-hideshow"]) || 0; console.log(`BZ : ${blessureZone}`); console.log(`Base Before : ${baseHideshow}`); console.log(`List Before : ${listHideshow}`); // create the set object out here. const attrsToSet = {}; if (blessureZone === "jambe" || blessureZone === "bras" || blessureZone === "torse" || blessureZone === "tete") { console.log("List Affichée / Base Cachée"); attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 0; attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 1; } else { console.log("List Cachée / Base Affichée"); attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 1; attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 0; } // just set the changes with a single setAttrs rather than having it nested in the if/else setAttrs(attrsToSet); }); }); </script>
1697063065
GiGs
Pro
Sheet Author
API Scripter
Wow, those are long and unwieldy attribute and class names. You have console logs there for the two branches of the if statement. Is the correct branch running each time? Unrelated (maybe) there are a couple of syntax errors. in select, don't use type="text". This: <select type="text" name="attr_blessure-zone" class="sheet-100"> <option class="sheet-nothidden" selected value="none">✗</option> <option type="text" value="bras">Bras</option> <option type="text" value="torse">Torse</option> <option type="text" value="jambe">Jambe</option> <option type="text" value="tete">Tête</option> <option type="text" value="special">Special</option> <option type="text" value="permanent">Permanent</option> </select> should be <select type="text" name="attr_blessure-zone" class="sheet-100"> <option class="sheet-nothidden" selected value="none">✗</option> <option value="bras">Bras</option> <option value="torse">Torse</option> <option value="jambe">Jambe</option> <option value="tete">Tête</option> <option value="special">Special</option> <option value="permanent">Permanent</option> </select> Also this input will be ignored: <input class="sheet-100 sheet-blessure-type-base-div" selected value="✗" disabled> There is no name or type, so its value will not be saved or stored. Also selected is not used for inputs. Finally, disabled is incompatible with sheet workers/ ther'es no indication you are using sheet owrkers with that attribute, but just in case you do - you'll need to remove disabled.
1697067678
Shey L'Ours
Pro
Sheet Author
Wow, those are long and unwieldy attribute and class names. 1. Yeah :/ But it help a lot to remind me where I go, especially in that case where I need to change everything, everytime. 2. Synthax corrected, nothing irrelevant, I take all ! Also this input will be ignored 3. I've done verification, since its linked to the upper one, it seem working by edditing manually the value of the upper one to 0 ? It past over the .sheet-blessure-type-base-hideshow[value="0"]~.sheet-blessure-type-base-div { display: none !important; } <input class="sheet-blessure-type-base-hideshow" type="number" name="attr_blessure-type-base-hideshow" value="1"/> <input class="sheet-100 sheet-blessure-type-base-div" value="✗" name="attr_blessure-type-base" disabled> Scott C. said: I don't usually use the shortcut repeating section syntax, so I can't actually tell if your javascript is correct or not. Check your developer console (ctrl-shift-J on chrome) and see if you get an error about "attempted to set a repeating attribute, but no id provided" showing up. There's also a small code critique. Generally you want there to only be a single setAttrs in a given function line, so I'd recommend changing your code to: That was a smart idea, I've correct what I miss and add console.log to verify my output. Actually, value seem to be set as expected. I just don't understand why it don't update my live code by adjusting the value from 0 to 1, as the JS say, and as I see in the console. :'( <script id="✓-SCRIPTCALC : BLESSURES" type="text/worker"> on("change:repeating_blessure:blessure-zone", function() { getAttrs(["repeating_blessure_blessure-zone", "repeating_blessure_blessure-type-base-hideshow", "repeating_blessure_blessure-type-list-hideshow"], function (values) { let blessureZone = values["repeating_blessure_blessure-zone"] || ""; let baseHideshow = parseInt(values["repeating_blessure_blessure-type-base-hideshow"]) || 0; let listHideshow = parseInt(values["repeating_blessure_blessure-type-list-hideshow"]) || 0; console.log(`BZ : ${blessureZone}`); console.log(`BEFORE actual Base = ${baseHideshow} / List = ${listHideshow}`); const attrsToSet = {}; if (blessureZone === "jambe" || blessureZone === "bras" || blessureZone === "torse" || blessureZone === "tete") { attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 0; attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 1; console.log(`AFTER set Base = 0 / List = 1`); } else { attrsToSet["repeating_blessure_blessure-type-base-hideshow"] = 1; attrsToSet["repeating_blessure_blessure-type-list-hideshow"] = 0; console.log(`AFTER set Base = 1 / List = 0`); } setAttrs(attrsToSet); }); }); </script> That feeling of everything supposed working but not working its... annoying... thank guys anyway for the time you've allready take to help me. That's much appreciated, feel sure to know this.