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

Sheet Worker not binding?

1619269727

Edited 1619269773
So i'm stealing code  borrowing an example from the CSS Wizardry wiki, for the "Fill Radio Buttons to the Left" section. I've made a couple of tweaks, namely: 1: As I will be doing this for numerous sections of my character sheet (Every skill has the same setup), i've couched the binder loop in another foreach, that will contain my 'types'. 2: I've added a "0" to the example. 3: The test fire of this system is inside a repeating section. I *suspect* that it's this one that's causing my problem? The Sheet Worker code now reads: <script type="text/worker"> const dotTypes = ["membertemp"]; const dotValues = ["0","1","2","3","4","5"]; dotTypes.forEach(function(type) { dotValues.forEach(function(value) { console.log(`${type}-${value} Bind`); on(`clicked:${type}-${value}`, function() { console.log(`clicked:${type}-${value}`); setAttrs({ type: value }); console.log(type + ": "+ value); }); }); }); </script> (the console.logs have obviously been added to try and debug) And the corresponding repeating section reads as: <fieldset class="repeating_memberships" name="repeating_memberships"> <input type="text" name="attr_membername"> <input type="number" name= "attr_memberrank" value="1"> <div class="dots"> <input type="hidden" name="attr_membertemp" class="dot" value="1" /> <button type="action" name="act_membertemp-0" class="dot"> <span class="checked"></span> </button> <button type="action" name="act_membertemp-1" class="dot gt-0"> <span class="checked"></span> </button> <button type="action" name="act_membertemp-2" class="dot gt-0 gt-1"> <span class="checked"></span> </button> <button type="action" name="act_membertemp-3" class="dot gt-0 gt-1 gt-2"> <span class="checked"></span> </button> <button type="action" name="act_membertemp-4" class="dot gt-0 gt-1 gt-2 gt-3"> <span class="checked"></span> </button> <button type="action" name="act_membertemp-5" class="dot gt-0 gt-1 gt-2 gt-3 gt-4"> <span class="checked"></span> </button> </div> </fieldset> I see the "bind" messages scroll through, but the buttons are nonresponsive. I tried changing the binding string to clicked:repeating_memberships:${type}-${value},  but that also did not produce a reaction on button click. What have I messed up here?
1619275169
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ok, so there are a few issues that I see, and they're ones that are some odd bits of how stuff works on sheets. You were correct in your attempted fix to change to clicked:repeating_memberships:${type}-${value} Your setAttrs is a little off. The object that you are creating actually has a key of "type" and its value is the value of the current step in the forEach. What you need to have is a key of the attribute (including the repeating fieldset). To do that would look something like this: <script type="text/worker"> const dotTypes = ["repeating_membership:membertemp"]; const dotValues = ["0","1","2","3","4","5"]; dotTypes.forEach(function(type) { dotValues.forEach(function(value) { console.log(`${type}-${value} Bind`); on(`clicked:${type}-${value}`, function(event) {//Note that the function will now take the passed event property console.log({event});//changed this to log the actual event const setObj = {};//I prefer to create the object I'm going to use in setAttrs separately. This way I can log it if there's a problem, and I can add to it dynamically let attribute = event.triggerName.replace(/clicked:|\d+$/g,'');//Extract the repeating section from the triggerName property of the event, assuming that the button name minus the -# is the attribute name. This set up will also work for non repeating action buttons setObj[attribute] = value;//Assign the value to the attribute. Using this construction we can dynamically assign values to keys of the object whether they already exist or not. Nonexistent keys are created. setAttrs(setObj); console.log(`${type}: ${value}`);//changed this to use template literals as they're more readable IMO }); }); }); </script This isn't going to noticeably affect anything right now, but just remember that setAttrs and getAttrs are asynchronous. This means that in your current code, your log of type + ": "+ value will actually be logged before your attribute is set. Now, I'm not sure if any of that will fix your problem, but it should be worth a try.
Thanks for the insights :) I did figure it was the repeating section screwing it up. Did have to make a slight tweak to attribute (needed the trailing - snipped off in order for it to set the correct attribute), but otherwise working perfectly... the async bit wasnt so much a sync/async thing as it was a "Debug log SOMETHING so i know it got past that point in the code without failing silently" (as the first one was just a "did this trigger and get the right words?" check). Now on to figuring out why the CSS isnt working given that i copy and pasted it from the example...
Self-answered point: The new sheet sanitizer (or lack thereof) isn't sticking "sheet-" in front of the classes, so the CSS is incorrectly telling the system to look for "sheet-dots" etc and it's not finding it. Solution is to just bulk remove "sheet-" from the CSS file.
1619362714
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
EtoileLion said: async bit wasnt so much a sync/async thing as it was a "Debug log SOMETHING so i know it got past that point in the code without failing silently" (as the first one was just a "did this trigger and get the right words?" check). So, just keep in mind that because of the async nature of setAttrs, your last log will get sent pretty much no matter what, because the setAttrs doesn't do anything until the call stack has completely emptied. About the only thing I can think of that that would stop that final log is if you tried to invoke a nonexistent variable in your call to setAttrs, or something similarly immediate.
1619366231

Edited 1619367223
Okay, now i'm utterly confused. I tried to get a little bit fancy. Which is usually where things go wrong, but anywayy... <script type="text/worker"> const dotTypes = ["repeating_memberships:membertemp","vocation","...a lot of other stuff"]; const dotValues = ["1","2","3","4","5"]; dotTypes.forEach(function(type) { dotValues.forEach(function(value) { on(`clicked:${type}-${value}`, function(event) { console.log({event}); let attribute = event.triggerName.replace(/clicked:|-\d+$/g,''); let govalue = event.triggerName.substring(event.triggerName.length-1); getAttrs([attribute],function(current) { console.log(`${current[attribute]}:${govalue}`); if(current[attribute] === govalue) { govalue = Math.max(govalue - 1,0); } console.log(`${current[attribute]}:${govalue}`); const setObj = {}; setObj[attribute] = govalue; setAttrs(setObj); }); }); }); }); </script> Probably not the best way to do it, but regardless, the idea being "If I click on the current value of the field, make it one less." (this allows me to not have a "0" bubble.) The trouble is... it's coming up with values that it shouldnt be able to if I sit there and rabbit the same button over and over? So I set... science-2 by clicking science-2. No problem. Then i click science-2 again. Code registers that i pushed science-2, makes the value of science 1. Fine. Intended. Then i click science-2 again. Code registers an event with the triggerName "clicked:science-2"... and then tells me my current value is 1 (correct), and that my go-value is 1.... (uhhh... how did it do a substring on "clicked-science-2" and come up with a 1?!?!?!). It sets the value to 0 (which would be accurate if i'd clicked the 1, because 1=1, so set to 0.) I figure maybe it's hiding the button for science-2, but that wouldnt explain the triggerName... Then i click science-2 again.... Code registers an event with the triggerName "clicked:science-2"... and then tells me my current value is 0 (correct), and that my go-value is 0.... further clicking results in a 0->0 continuation (because i've math-locked it to a 0 minimum) but uhhh... How is my code generating incorrect values?
1619371238
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
So, I'd add the following to your console.log before the if statement: console.log(`${current[attribute]}===${govalue}:${current[attribute] === govalue}`); Just to make sure that your comparison is working.
1619552344

Edited 1619552371
Oddly, it seems that my sandbox must have been polluted, because the code worked fine. Different, yet related issue: If the first thing someone does in a repeating section is click on an action button invoking that script, the repitem gets marked as broken, and can never shake the broken state. If the user edits any 'normal' field in the repitem first, it works perfectly well.