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

Need Gig - Sheet Worker Help

1588305020

Edited 1588305197
Victor B.
Pro
Sheet Author
API Scripter
I suck at sheetworkers.  Alright with APIs.  Not even close to TheAarons or Scotts code, but I muddle along. I need to create multiple drop downs based on the characteristics defined to talents.  So plan is to loop through talents and build these drop downs and save them as attributes that I'll reference throughout the sheet related to the characteristic being rolled.  Here's the code.  doubt it will work.  Gig, I need you again!!! Don't fail me in my time of need! const talentStat = ['WS', 'BS', 'S', 'T', 'I', 'Ag', 'Dex', 'Int', 'WP', 'Fel']; stats.forEach(talentStat => { on(`sheet:opened change:repeating_Talents:TalentName change:repeating_Talents:TalentChar change:repeating_Talents:TalentLevel`,         function () {                 let rollQuery = 'Talents|' getAttrs([                       "repeating_Talents:TalentName",                       "repeating_Talents:TalentChar",                        "repeating_Talents:TalentLevel"                  ], function (v) {                         if (${talentStat} == v.TalentChar) {                             ${rollQuery) = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|'                         }     }); setAttrs({ [`${talentStat}Talents`]:  rollQuery }); }); });
1588308714
GiGs
Pro
Sheet Author
API Scripter
lol, I'm flattered. There are a few syntax errors. The first is on the on(change) line. attributes here must  always be listed in lower case, regardless of what they actually are in the sheet. So this would be on(`sheet:opened change:repeating_talents:talentname change:repeating_talents:talentchar change:repeating_talents:talentlevel`, function () { Then in your getAttrs, you use the wrong sepeating attribute syntax. You use : as a separate on the on(change) line, but in getAttrs, you have to use an underscore. Yes, this is irritating and confusing. So that would be getAttrs([             "repeating_Talents_TalentName",             "repeating_Talents_TalentChar",             "repeating_Talents_TalentLevel"         ], function (v) { Then two more that have the same cause if ( ${talentStat} == v.TalentChar) {        ${rollQuery) = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|' You only put variables inside ${ } brackets when they are in template literals - string sthat use backticks ` `. The above section should be if ( talentStat == v.TalentChar) {        rollQuery = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|' There's also a problem with rollquery - it completely overwrites the variable you created earlier. that is suggesting to me that it doenst belong here. So fixing the syntax errors I have spotted so far, we'd have: const talentStat = ['WS', 'BS', 'S', 'T', 'I', 'Ag', 'Dex', 'Int', 'WP', 'Fel']; stats.forEach(talentStat => {     on(`sheet:opened change:repeating_talents:talentname change:repeating_talents:talentchar change:repeating_talents:talentlevel`, function () {         let rollQuery = 'Talents|'         getAttrs([             "repeating_Talents_TalentName",             "repeating_Talents_TalentChar",             "repeating_Talents_TalentLevel"         ], function (v) {             if (talentStat === v.TalentChar) {                 rollQuery = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|'             }         });         setAttrs({             [`${talentStat}Talents`]: rollQuery         });     }); }); HOWEVER , this is a flawed design. Which I only noticed after spotting the above syntax errors. You are creating 10 different sheet workers that all access the exact same repeating section. You should only use one sheet worker. (And that if statement probably isnt needed.) So we need to rewrite it.  And the way the rollquery attribute is initialised suggests to me that you cant use this repeatign section syntax, but need to use getSectionIDs. But I am not sure, I need to know more. I'll ask about that in the next post.
1588309242

Edited 1588309268
GiGs
Pro
Sheet Author
API Scripter
Victor B. said: I need to create multiple drop downs based on the characteristics defined to talents.  So plan is to loop through talents and build these drop downs and save them as attributes that I'll reference throughout the sheet related to the characteristic being rolled.   I'm dubious that the method you've used is the right one for the job, so can you explain more about what you're trying to do here. You are creating a rollQuery attribute that exists in each row of the repeating section, but how are you planning to use it? The more I understand about its function, the easier it'll be to build an efficient sheet worker for it. Also, what does the html for these three attributes look like: TalentName, TalentChar, TalentLevel?
1588309411
GiGs
Pro
Sheet Author
API Scripter
Final post for now. i made this a separate post so you dont miss it: Dont use upper caps in the repeating section name attribute.  repeating_Talents  should be  repeating_talents .  I'm not talking about the way its printed in the sheet worker - but on the character sheet itself, in the html. The other attributes dont need to change. But this one causes issues with scripts that access the section, and some uses of buttons inside the section.  You can change it without losing data - for most purposes, the character sheet ignores case in attribute names.
1588335337

Edited 1588335979
Victor B.
Pro
Sheet Author
API Scripter
Alright, what I need to do is ANYTIME a change is made to the talents repeating section, I need to loop through the section, and build up to 10 drop downs against those talents.  So idea is to loop, find all talents that have WS as an characteristic, format a drop down roll query and then store it in a hidden attribute dedicated to WS.  I need to do this for all 10 characteristics.  Then I'm going to add the WS Roll Query attribute to everywhere that there are rolls against WS so players can select from a list of WS from a Roll Query related talents and the results show in chat. 
1588359364
GiGs
Pro
Sheet Author
API Scripter
Ah I see now, the final rollquery is being saved outside the repeating section. With repeating sections, there are two different syntaxes you use. First, the syntax where you can address names like this: "repeating_Talents_TalentName" That syntax should only used when the change is limited to one row of the repeating section, and the end result is inside that row. It's like when you have an ability score and a skill level, and are adding them together to get a final skill score. You'd have them all in the same row of the section, so you can address them this way. They can even use attributes from outside the section, but they cannot use attributes from different rows of the same section. There's another syntax which uses the function getSectionIDs , which allows you to things with all of the rows of the section at once. With your function, Whenever you change one row of the section, it has to get values from all of the rows to build the query properly, so for that you need getSectionIDs. I'll post up a version to try after I've had my breakfast. It would be handy to be able to see the html for TalentName, TalentChar, TalentLevel , so can check the syntax will work properly.
1588359767
Victor B.
Pro
Sheet Author
API Scripter
Here's the repeating section for talents <fieldset class="repeating_Talents"> <div class="sheet-row"> <div class="sheet-col-2-11 sheet-pad-r-sm sheet-vert-top"> <input type="text" name="attr_TalentName"/> </div> <div class="sheet-col-1-6 sheet-pad-r-sm sheet-vert-top"> <input type="text" name="attr_TalentTest"/> </div> <div class="sheet-col-3-10 sheet-pad-r-sm sheet-vert-top"> <textarea class="sheet-xs-textarea" type="text" name="attr_TalentDesc"></textarea> </div> <div class="sheet-col-1-13 sheet-center sheet-pad-r-sm sheet-vert-top" style="margin-top:1px"> <select class="sheet-select-no-arrow-center" name="attr_TalentChar"> <option value="1" data-i18n="NONE">None</option>      <option value="@{WeaponSkillBonus}" data-i18n="ABBREVIATE-WEAPON-SKILL">WS</option> <option value="@{BallisticSkillBonus}" data-i18n="ABBREVIATE-BALLISTIC-SKILL">BS</option> <option value="@{StrengthBonus}" data-i18n="ABBREVIATE-STRENGTH">S</option> <option value="@{ToughnessBonus}" data-i18n="ABBREVIATE-TOUGHNESS">T</option> <option value="@{InitiativeBonus}" data-i18n="ABBREVIATE-INITIATIVE">I</option> <option value="@{DexterityBonus}" data-i18n="ABBREVIATE-DEXTERITY">Dex</option>     <option value="@{AgilityBonus}" data-i18n="ABBREVIATE-AGILITY">Ag</option> <option value="@{IntelligenceBonus}" data-i18n="ABBREVIATE-INTELLIGENCE">Int</option> <option value="@{WillPowerBonus}" data-i18n="ABBREVIATE-WILL-POWER">WP</option> <option value="@{FellowshipBonus}" data-i18n="ABBREVIATE-FELLOWSHIP">FP</option> </select> </div> <div class="sheet-col-1-13 sheet-center sheet-pad-r-sm sheet-vert-top"> <input class="sheet-center" type="number" name="attr_TalentLevel" value="1"/> </div> <div class="sheet-col-1-13 sheet-center sheet-pad-r-sm sheet-vert-top"> <input class="sheet-center" type="number" name="attr_TalentMax" value="@{TalentChar}" disabled="true"/> </div> <div class="sheet-col-1-20 sheet-center sheet-pad-r-sm sheet-vert-top"> <input type="checkbox" name="attr_TalentTaken" value="1"/> </div> <div class="sheet-col-1-20 sheet-center sheet-pad-r-sm sheet-vert-top"> <input type="checkbox" name="attr_TalentCareer" value="1"/> </div> <span class="sheet-spacer"></span> </div> </fieldset>  
1588360787
GiGs
Pro
Sheet Author
API Scripter
PS: I just noticed another error with the earlier script. setAttrs is outside  the getAtrrs function. It has to be nested inside it for it to work.  Thanks for the html. Remember to change this one line: <fieldset class="repeating_Talents"> to this <fieldset class="repeating_talents"> If any players using your sheet try to use buttons in macros, or use scripts like my Universal Chat Menu script, they wont work reliably unless you make that all lower-case.
1588363935

Edited 1588364140
GiGs
Pro
Sheet Author
API Scripter
It's just as well i asked to see the html. There was a very subtle error we might not have been able to figure out for ages. In your worker you set these stats: const talentStat = ['WS', 'BS', 'S', 'T', 'I', 'Ag', 'Dex', 'Int', 'WP', 'Fel']; Then later in the worker you have this comparison if (talentStat === v.TalentChar) { The problem is TalentChar is going to be something like "@{WeaponSkillBonus}" So they will never match. Also, is this correct?  rollQuery = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|' Should it be  rollQuery = v.TalentName + ',' + v.TalentChar + '-' + v.TalentLevel + '|'
1588364801

Edited 1588375412
GiGs
Pro
Sheet Author
API Scripter
Here's a first pass at the sheet worker. It's pretty complex. It loops through the repeating section once, and builds a full set of 10 queries. Then it checks the queries on the sheet, and if there computed version is different from any on the sheet, it updates those. This handles switches from one stat to another - updating both changed queries at the same time. It also handles what happens when you delete a row in the repeating section. Hopefully it works! It looks longer than it is-  without the annotations it would be a bit shorter. // for stat values, we need to create a corrospendance between the stat scores on the sheet and the stat which governs them. const statvalues = {'@{WeaponSkillBonus}':'WS', '@{BallisticSkillBonus}': 'BS', '@{StrengthBonus}':'S', '@{ToughnessBonus}':'T',      '@{InitiativeBonus}': 'I', '@{DexterityBonus}': 'Dex', '@{AgilityBonus}': 'Ag', '@{IntelligenceBonus}': 'Int',      '@{WillPowerBonus}': 'WP', '@{FellowshipBonus}': 'Fel'}; // in the change event, need to add the remove: option, because the queries may need to be updated if a repeating row is deleted. on(`sheet:opened change:repeating_talents:talentname change:repeating_talents:talentchar change:repeating_talents:talentlevel remove:repeating_talents`, function () {     // get the row ids of every row in the repeating section     getSectionIDs('repeating_talents', idarray => {         //now loop through the section, and get the full names of each row attribute, including the row id.         const fieldnames = [];         idarray.forEach(id => fieldnames.push(                 `repeating_talents_${id}_TalentName`,                 `repeating_talents_${id}_TalentChar`,                 `repeating_talents_${id}_TalentLevel`         ));         // also get the names of the query attributes, because we'll be checking their values later.         Object.values(statvalues).forEach(stat => fieldnames.push(`${stat}Talents`));         // getAttrs asks for an array, and we have one, so dont need to build one using the square brackets.         getAttrs(fieldnames, function (v) {             // define an attribute to hold all 10 queries             const queries  = {};             // set its default values             Object.values(statvalues).forEach(stat => {                 queries[`${stat}Talents`] = 'Talents|';             });             // now loop through each row, and update the relevant query.             idarray.forEach(id => {                 // get the values for this row                 const tname = v[`repeating_talents_${id}_TalentName`];                 const tchar = v[`repeating_talents_${id}_TalentChar`];                 const tlevel = v[`repeating_talents_${id}_TalentLevel`];                 // find out which query stat to update                 const stat = statvalues[tchar];                 // update that query                 queries[`${stat}Talents`] = queries[`${stat}Talents`] + `${tname},${tchar}-${tlevel}|`;             });             // could output this to setAttrs right now, but to optimise it a little, we check which stats have been changed             // and only print those out             const output = {};             Object.keys(queries).forEach(query => {                 const statonsheet = v[query];                 const queryvalue = queries[query];                 if (statonsheet != queryvalue) {                     output[query] = queryvalue ;                 }             });                          setAttrs(output);         });     }); });
1588373715
Victor B.
Pro
Sheet Author
API Scripter
Thanks very much.  My weakness on Roll20 is sheet workers.  I'm not good with them at all.  Really appreciate this.  I'll give a whirl here in a bit.  
1588375493
GiGs
Pro
Sheet Author
API Scripter
One thing I meant to ask: in your query, you have this  rollQuery = v.TalentName + ',' + v.TalentName + '-' + v.TalentLevel + '|' Which i amended to  rollQuery = v.TalentName + ',' + v.TalentChar + '-' + v.TalentLevel + '|' But I meant to ask, is that a dash or a minus sign there? Should it be a plus?
1588395901
Victor B.
Pro
Sheet Author
API Scripter
Minus I want TllentName - TalentLevel to display in the resulting chat window
1588395963
Victor B.
Pro
Sheet Author
API Scripter
Visual cue to players that a talent has been selected and the level of that talent is displayed in chat
1588396568
GiGs
Pro
Sheet Author
API Scripter
In that case, change this line queries[`${stat}Talents`] = queries[`${stat}Talents`] + `${tname},${tchar}-${tlevel}|`; to queries[`${stat}Talents`] = queries[`${stat}Talents`] + `${tname},${tname}-${tlevel}|`;
1588445700
GiGs
Pro
Sheet Author
API Scripter
Did the sheet worker work okay, or does it need tweaking?
1588481848
Victor B.
Pro
Sheet Author
API Scripter
Works perfect all good
1588482462
GiGs
Pro
Sheet Author
API Scripter
Wow, there's a first time for everything, lol. Great! :)