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

5e dnd Sheetworker assistance (using Community Contributed 5e character sheet)

I am obviously doing something wrong.  I want to click a button on my character sheet (or click a checkbox on to create an event) Here is the follow codes I am using for the text worker, as well as part of my html (I looked through for typos but I couldn't find them, doesn't mean they are there) Also note I made said macro as a mashup of several posts on the forums when I attempted to look up how to perform the task I am trying. Now to the code! on(`change:short_rest clicked:actionshortrest`, function (eventinfo) { //Section of repeating to be checking let section = "classresources"; //get proper id for repeating sections (repeating_classresources_) getSectionIDs(`repeating_${section}`, function (idArray) { let fields = ["ClassResourceName", "ClassResourceRecharge", "ClassResourceTotal", "ClassResourceTotal_max"]; const attrArray = idArray.reduce( (m,id) => [...m, ...(fields.map(field => `repeating_${section}_${id}_${field}`))],[]); getAttrs(attrArray, function (values) { const setattrobj = {}; values.forEach(item =>{ //check if ClassResourceRecharge has been set to the string "Short Rest" (this attr is set with a dropdown) if(values.ClassResourceRecharge == "Short Rest" ){ setattrobj.ClassResourceTotal = parseInt(values["ClassResourceTotal_max"])||0; } }); //check if empty or not if(setattrobj) { setAttrs(setattrobj); } // set checkbox back to 0 to uncheck it, regardless of results // when I put the below setAttrs here in the code, it doesn't execute }); }); // setAttrs is executeing fine, reset the checkbox setAttrs({"short_rest":0}); }); And.... part with action button and checkbox (I tried using hidden attribute with the checkbox and that didn't seem to work either)  Got the Short rest below to work but had to move the setAttrs to outside the getAttrs functions <div class="sheet-row"> <div class="sheet-col-4-5 sheet-center sheet-small-label sheet-sub-header sheet-padl sheet-padr">Short & Long Rests</div> <div class="sheet-row"> <div class="sheet-col-2-5 sheet-padl sheet-align-left sheet-padr"> <input type="hidden" name ="attr_hidden_short_rest" value="1"/> <input type="checkbox" name="attr_short_rest" value="1"/> <button type="button" name="act_actionshortrest" title="Click me to take a Short Rest!"><span style="font-family: fontello"></span>:Take Short Rest?</button> </div> <div class="sheet-col-2-5 sheet padl sheet-align-right sheet-padr"> <input type="hidden" name ="attr_hidden_long_rest" value="1"/> <input type="checkbox" name="attr_long_rest" value="@{hidden_longrest}"/> <button type="button" name="act_actionlongrest" title="Click me to take a Long Rest!"><span style="font-family: fontello">:</span>Take Long Rest?</button> </div> </div> </div> And repeating section part of my html <fieldset class="repeating_classresources"> <div class="sheet-row"> <div class="sheet-col-5-12"> <input type="text" name="attr_ClassResourceName" /> </div> <div class="sheet-col-1-4"> <select name="attr_ClassResourceRecharge"> <option value="None">None</option> <option value="Short Rest">Short Rest</option> <option value="Long Rest">Long Rest</option> <option value="Other">Other</option> </select> </div> <div class="sheet-col-1-6"> <input type="number" name="attr_ClassResourceTotal" value="1" min="0" step="1" /> </div> <div class="sheet-col-1-6"> <input type="number" name="attr_ClassResourceTotal_max" value="1" min="0" step="1" /> </div> </div> </fieldset> My Class resource page with resources does not reset, see below.  While writing this post, I was able to atleast get my sheetworker to recognize and change my checkbox back to unchecked, however Still doesn't reset my classresources... and I am not sure what it is that I am doing wrong...  I seen some code with getSectionId inside getAttrs and I seen other with getAttrs inside the getSectionId code.... not sure if it matters or which one is "best practice" If anyone looking at this see's why it wouldn't be making changes I would be sooooo happy :) Thank you for your time. Few more pictures of the sheet.. And this...
1593235636

Edited 1593235674
Also tried changing code to this, cause I know I am messing something up with the repeating sections... on(`change:short_rest clicked:actionshortrest`, function (eventinfo) { //Section of repeating to be checking let section = "classresources"; //get proper id for repeating sections (repeating_classresources_) getSectionIDs(`repeating_${section}`, function (idArray) { let fields = ["ClassResourceName", "ClassResourceRecharge", "ClassResourceTotal", "ClassResourceTotal_max"]; const attrArray = idArray.reduce( (m,id) => [...m, ...(fields.map(field => `repeating_${section}_${id}_${field}`))],[]); getAttrs(attrArray, function (values) { const setattrobj = {}; values.forEach(id =>{ //check if ClassResourceRecharge has been set to the string "Short Rest" (this attr is set with a dropdown) if(values[`repeating_classresources_${id}_ClassResourceRecharge`] == "Short Rest" ){ setattrobj[`repeating_classresources_${id}_ClassResourceTotal`] = parseInt(values[`repeating_classresources_${id}_ClassResourceTotal_max`])||0; } }); //check if empty or not if(setattrobj) { setAttrs(setattrobj); } // set checkbox back to 0 to uncheck it, regardless of results // when I put the below setAttrs here in the code, it doesn't execute }); }); // set Attrs is executeing fine, reset the checkbox setAttrs({"short_rest":0}); }); Still not working :(
1593238196

Edited 1593238262
GiGs
Pro
Sheet Author
API Scripter
If setAttrs is not firing there, you need to check that setattrobj has the values it should have. This is a good example of why I often say set variables in your code. It makes logging easier. So update with this sheet worker, and check in the browser console to see if the correct values are being created. on(`change:short_rest clicked:actionshortrest`, function (eventinfo) { //Section of repeating to be checking let section = "classresources"; //get proper id for repeating sections (repeating_classresources_) getSectionIDs(`repeating_${section}`, function (idArray) { let fields = ["ClassResourceName", "ClassResourceRecharge", "ClassResourceTotal", "ClassResourceTotal_max"]; const attrArray = idArray.reduce( (m,id) => [...m, ...(fields.map(field => `repeating_${section}_${id}_${field}`))],[]);                 console.log(`====== attrArray: ${attrArray.join(', ')}`; getAttrs(attrArray, function (values) { const setattrobj = {}; values.forEach(id =>{                                 const recharge = values[`repeating_classresources_${id}_ClassResourceRecharge`]; console.log(`==== id: ${id}; recharge: ${recharge}`); //check if ClassResourceRecharge has been set to the string "Short Rest" (this attr is set with a dropdown)                                 // a common source of errors is having mismatched cases, so here we ensure they are both the same case. if(recharge.toLowerCase() === "short rest" ){                                         const max = parseInt(values[`repeating_classresources_${id}_ClassResourceTotal_max`])||0;                                         console.log(`==== id: ${id}; max: ${max}`); setattrobj[`repeating_classresources_${id}_ClassResourceTotal`] = max; } }); //check if empty or not                         console.log(`=== setattrobj: ${JSON.stringify(setattrobj)}`);                         // add short_rest here so that it gets updated along with the rest.                         setattrobj.short_rest = 0;                                            // since setattrobj will now always contain something, no need for the if statement setAttrs(setattrobj); }); }); });
I found an error in your above code (understandable its 2am when you responded :P ) on the console command below the attrArray build. but was able to figure that out through the console. Anyway this is what showed up thus far. My attrArray seems to be working correctly (items seems to be what i want.  ====== attrArray: repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceName, repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceRecharge, repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceTotal, repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceTotal_max, repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceName, repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceRecharge, repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceTotal, repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceTotal_max, repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceName, repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceRecharge, repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceTotal, repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceTotal_max However the "values.forEach(...{})" is showing that it is having Object type mismatch. sheetsandboxworker.js?1593282912846:733 TypeError: values.forEach is not a function at Object.eval [as -MAEcE6yhp2wPK25klcv//false//0.576186630557858] (eval at messageHandler (sheetsandboxworker.js?1593282912846:698), <anonymous>:52:15) at _fullfillAttrReq (sheetsandboxworker.js?1593282912846:673) at messageHandler (sheetsandboxworker.js?1593282912846:705) I'm not sure why it would be a mismatch, as values is the output Object from getAttr (statsarray,function(values){}); Also now my checkbox doesn't "set" when moved inside the getAttr function so that part of the code is simply not executing Does the code short circuit (stop executing further code) if it can't resolve part of the code? cause the setAttr function isn't in the forEach function so I'm surprised it didn't execute even though it has a problem with that part of the code. Nothing I've seen so far in the forums would indicate that I am doing something wrong with regards to the forEach function.. I added another console.log to look at "values" made by the getAttrs and it seems to be good (has the correct values. This is the console log output from that code ===== values: {"repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceName":"ResourceA","repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceRecharge":"Short Rest","repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceTotal":"4","repeating_classresources_-madeyzzhwfvznv9bbjx_ClassResourceTotal_max":"10","repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceName":"ResourceB","repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceRecharge":"Short Rest","repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceTotal":"1","repeating_classresources_-manyxvzbzwt0dvixxpt_ClassResourceTotal_max":"2","repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceName":"ResourceC","repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceRecharge":"Short Rest","repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceTotal":"3","repeating_classresources_-manyz4fpxu5ohwg5lyg_ClassResourceTotal_max":"7"}
1593285632

Edited 1593285694
GiGs
Pro
Sheet Author
API Scripter
To answer your question, yes, if there is a critical error, the code stops executing. If it was an API script, it would cause the sandbox to crash, but the sheet worker has better sandboxing and it just brings down that worker. (Sometimes it'll cause all sheet workers to fail.) This is usually a good thing - you need to know what sheet workers are failing, and when they fail to update attributes, that lets you know something is up. values isn't an array, so values.forEach wont work. That's your error. values is an object. That section should be using the getSectionIDs array, like so idArray.forEach(id =>{
1593288563

Edited 1593288966
Thanks GiGs, That worked :) does that mean "Objects" can only use for loops to iterate their key:item  pairs?
1593289153

Edited 1593290022
Well it works with my Checkbox, the sheetworker is not recognizing my action button :( (but it is updating my resources, consider this still a win! :P) <button type="button" name="act_actionshortrest" title="Click me to take a Short Rest!"><span style="font-family: fontello"></span>:Take Short Rest?</button> I made sure that my action button had no "_" characters in it's name (action button FAQ on roll20 mentions it can't cypher those) ...  Edit:I put a console in my code right after the "on(..." event with just button click event and it appears the clicked: <buttonName> syntax is not activating the sheetworker at all. Is support for action buttons removed from roll20 in an update? Edit2: NM I found the issue. my "button type" was = to button not action :) re reading through FAQ is helpful.
1593289782

Edited 1593289797
GiGs
Pro
Sheet Author
API Scripter
J.C said: does that mean "Objects" can only use for looks to iterate their key:item  pairs? I'm not parsing this properly, "for looks"? But you can iterate through objects in multiple ways, it just depends on what you want. You can treat an object like an array with the following: // this turns the keys of an object into an array, then you loop through that array. // you can then get the values the same way your normally do with values[key]. Object.keys(values).forEach(key => {     console.log(`${key}: ${values[key]}`) }); // if you dont need to know the name of the keys, you can just get the values as an array // this is handy in situations where, say, you just want to add up all the attributes in values. Object.values(values).forEach(value => {     console.log(`${value}`); }); // you can also get an array of [key, value] pairs. In this example, I've used destructuring to break the array apart // so you can address them directly using the variables key and value. Object.entries(values).forEach(([key, value]) => {     console.log(`${key}: ${value}`); }); Each has its own time for when its the best one to use. I've used all 3 in sheet workers at various times. There's other methods of accessing objects dynamically (for instance, using reduce or filter, not to mention for...of and for...in loops), but the above are the closest parallels to the code above.
Sorry I made an edit to the above looks = loops :P typo must have not fixed it fast enough for you. 
Also thank you for that example of object looping I will probably steal those in the future
1593290774

Edited 1593290856
GiGs
Pro
Sheet Author
API Scripter
Action buttons are still supported. It took some careful study of your code to figure out the problem here! The error is in the html. This <button type="button" name="act_actionshortrest" should be <button type="action" name="act_actionshortrest"