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

Get the name of a repeating section in a sheetworker

1598339598
Peter B.
Pro
Sheet Author
Hello Roll20! I have a rather annoying programing problem. Working on an old sheet, and trying to improve the functionality. I have multiple repeating section of this format: <fieldset name="repeating_spells1"> <input name="attr_spellname1"> </fieldset> <fieldset name="repeating_spells2"> <input name="attr_spellname2"> </fieldset> <fieldset name="repeating_spells3"> <input name="attr_spellname3"> </fieldset> This makes it rather annoying to make sheet workers for, as I cannot make a single sheet worker, that is watching for changes on all the repeating sections and always updates the associated sections "spellname" field. Therefore I was wondering if it is possible in a sheet worker, to get the name of the repeating section that is currently being made changes two, so that I can use some string parsing and find the number in the repeating section, and use that to update the appropriate spellname field? Luckily the number in the repeating section and the spellname are always matching :) Another solution would be to rename all the spellname fields to remove the number, but then players would lose data, unless I migrate all the current data to the new fields, and I do not know how to do that for repeating fields, so my first approach seems more reachable :)
1598352877

Edited 1598353090
Andreas J.
Forum Champion
Sheet Author
Translator
Peter B. said: This makes it rather annoying to make sheet workers for, as I cannot make a single sheet worker, that is watching for changes on all the repeating sections and always updates the associated sections "spellname" field. Therefore I was wondering if it is possible in a sheet worker, to get the name of the repeating section that is currently being made changes two, so that I can use some string parsing and find the number in the repeating section, and use that to update the appropriate spellname field? Luckily the number in the repeating section and the spellname are always matching :) Oh, this is absolutely possible, I do this plenty with non-repeating sections, but with some modification, it should work well with repeating ones as well. I don't work with repeating sections enough to be able to give you a quick and solid example. Check out the use of Template literals . Many sheet authors use them to simplify stuff when there is lot of repeating. I've recently done a bit of updating of the documentation. Chronicles of Darkness by Roll20 is a sheet using template literals together with numbers to have a sheetworker listen to attributes "attack1" though "attack5". Later there is a similar section where it handles 16 health boxes in a similar sheetworker. Unfortunately it doesn't show examples of how template literals are used inside the sheet itself, but if you look up some of my latest sheets you probably can find some simple examples of this. (I did the CoD sheetworkers, but don't understand half of it any longer, so can't really answer questions related to it. I streamlined a bunch of it's older sheetworkers to not repeat themselves too much). I'm sure GiGs will show up and show a great example shortly. Speaking of, the documentation could really do with an good example of how to use template literals.
1598372186
Peter B.
Pro
Sheet Author
📜🗡Andreas J.🏹📜 said: Check out the use of Template literals . Many sheet authors use them to simplify stuff when there is lot of repeating. I've recently done a bit of updating of the documentation. Thank you for the hint to use Template literals. This will be useful after  I get the string from the repeating section! My bigges problem is how do I get the name of a repeating section in a sheet worker? If you any examples of doing that, it would be great!
1598376444
Kavini
Pro
Marketplace Creator
Sheet Author
Compendium Curator
So, there's actually a couple of ways you might do this. The first would be to use eventInfo.sourceAttribute to isolate the correct repeating section. This would require some string manipulation, but is very doable.  But I actually think an easier way to do this would be to define the repeating sections you want to affect in an array, and then loop through them. So, it would look something like this: ["spells1","spells2","spells3"].forEach(section => on(`change:repeating_${section}`, eventInfo => doSomething(section)); What this will do is iterate through the array of sections, passing each section name to an event handler, and then allowing you to pass this string to a function (inline or otherwise). You could also combine this with sourceAttribute for even more granular control.
1598377636
Peter B.
Pro
Sheet Author
Nic B. said: So, there's actually a couple of ways you might do this. The first would be to use eventInfo.sourceAttribute to isolate the correct repeating section. This would require some string manipulation, but is very doable.  But I actually think an easier way to do this would be to define the repeating sections you want to affect in an array, and then loop through them. So, it would look something like this: ["spells1","spells2","spells3"].forEach(section => on(`change:repeating_${section}`, eventInfo => doSomething(section)); What this will do is iterate through the array of sections, passing each section name to an event handler, and then allowing you to pass this string to a function (inline or otherwise). You could also combine this with sourceAttribute for even more granular control. Thanks Nic B. This looks exactly like what I am trying to do! :)
1598391145
GiGs
Pro
Sheet Author
API Scripter
Nic B. said: But I actually think an easier way to do this would be to define the repeating sections you want to affect in an array, and then loop through them. So, it would look something like this: ["spells1","spells2","spells3"].forEach(section => on(`change:repeating_${section}`, eventInfo => doSomething(section)); This is the best way to do it. Since you are operating from the design of the sheet, you know exactly what repeating sections exist, so can build your code with foreknowledge of what triggers exist. You probably dont need the eventInfo part, since you have created a loop of separate change events here, so when the event is triggered, it can only be inside a specific repeating section. It is possible to call this without using a forEach loop, by combining the change event to include all 3 repeating section names, but the code tends to be a bit more complicated, and you probably will need to use eventInfo. The above method leads to more straitforward code.
1598420828
Peter B.
Pro
Sheet Author
GiGs said: Nic B. said: But I actually think an easier way to do this would be to define the repeating sections you want to affect in an array, and then loop through them. So, it would look something like this: ["spells1","spells2","spells3"].forEach(section => on(`change:repeating_${section}`, eventInfo => doSomething(section)); This is the best way to do it. Since you are operating from the design of the sheet, you know exactly what repeating sections exist, so can build your code with foreknowledge of what triggers exist. You probably dont need the eventInfo part, since you have created a loop of separate change events here, so when the event is triggered, it can only be inside a specific repeating section. It is possible to call this without using a forEach loop, by combining the change event to include all 3 repeating section names, but the code tends to be a bit more complicated, and you probably will need to use eventInfo. The above method leads to more straitforward code. Thanks for the clarification GiGs!  I am going to use the forEach loop as the actualy sheet has 69 repeating sections that I need to listen on! Yeah... its a mess, and a mess that is VERY hard to clean up, but I am trying :)
1598425559
GiGs
Pro
Sheet Author
API Scripter
If you have 69 repeating sections, chances are a loop might not do the job. You use a loop like this when all the repeating sections are basically doing exactly the same thing, just the attribute names are different. If the repeating sections are doing different things, but they are in similar groups, you can probably organise them into similar groups and use a different loop for each of them.  It's likely though that you'll have to handle some sections uniquely.
1598426000
GiGs
Pro
Sheet Author
API Scripter
Also looking back at the first post, which has this group: <fieldset name="repeating_spells1"> <input name="attr_spellname1"> </fieldset> <fieldset name="repeating_spells2"> <input name="attr_spellname2"> </fieldset> <fieldset name="repeating_spells3"> <input name="attr_spellname3"> </fieldset> What you probably want to do is set up an array of numbers, and then use template literals to build the relevant names, like this: const spells = [1, 2, 3]; spells.forEach(num => {     on(`change:repeating_spells${num}:spellname${num}`, () => {         getAttrs([`repeating_spells${num}_spellname${num}`], values => {             /* do your stuff here */         });     }); }); This allows you to access the repeating section name, and the attribuets within the repeating section, assuming they use the same number. This suggestion is without seeing exactly what your repeating sections look like, so i might be off-base, but its likely you'll have to make some consideration for the attribute names within the repeating section, unless they are named exactly the same.
1598428233
Peter B.
Pro
Sheet Author
GiGs said: Also looking back at the first post, which has this group: <fieldset name="repeating_spells1"> <input name="attr_spellname1"> </fieldset> <fieldset name="repeating_spells2"> <input name="attr_spellname2"> </fieldset> <fieldset name="repeating_spells3"> <input name="attr_spellname3"> </fieldset> What you probably want to do is set up an array of numbers, and then use template literals to build the relevant names, like this: const spells = [1, 2, 3]; spells.forEach(num => {     on(`change:repeating_spells${num}:spellname${num}`, () => {         getAttrs([`repeating_spells${num}_spellname${num}`], values => {             /* do your stuff here */         });     }); }); This allows you to access the repeating section name, and the attribuets within the repeating section, assuming they use the same number. This suggestion is without seeing exactly what your repeating sections look like, so i might be off-base, but its likely you'll have to make some consideration for the attribute names within the repeating section, unless they are named exactly the same. You are right. This is exactly what I want to do. Thank you for the nice example! :) And about the 69 repeating section. Yes they actually do exactly the same thing, atleast for the function I am going to write, they are going to do exactly the same thing. So a loop will work just fine :)