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 .
×
Advertisement Create a free account

updating repeating section

I have the following code:     on(`change:repeating_skills`, function(){        getAttrs(["repeating_skills_skillMod","repeating_skills_attribute","strength","dexterity","iq","health"], function(value){            let modVal=1*(value[`repeating_skills_skillMod`])||0;            let attr=(value[`repeating_skills_attribute`])            let st=1*(value[`strength`])||0;            let dx=1*(value[`dexterity`])||0;            let iq=1*(value[`iq`])||0;            let ht=1*(value[`health`])||0;            let per=1*(value[`perception`])||0;            let will=1*(value[`will`])||0;            if(attr=="ST"){                modVal=modVal+st            }            if(attr=="DX"){                modVal=modVal+dx            }            if(attr=="IQ"){                modVal=modVal+iq            }            if(attr=="HT"){                modVal=modVal+ht            }            if(attr=="PER"){                modVal=modVal+per            }            if(attr=="WILL"){                modVal=modVal+will            }            setAttrs({repeating_skills_skillLevel:modVal,repeating_skills_name:attr})        });      }); This updates the skill level whenever the repeating section row is changed. The problem is that I also need it to update all the rows in the repeating section whenever the values for attr_strength, attr_dexterity,attr_iq,attr_health,attr_perception,or attr_will are changed. Can anyone clue me in to how to do this?
1627530199
Kraynic
Pro
Sheet Author
You need to add them to the list of changes to watch on your first line. on(`change:repeating_skills change:iq change:strength change:dexterity change:health change:perception change:will`, function(){ Anything that is listed on that line should also be on the getAttrs line as well.
The problem is that those attributes are outside the repeating section, and I need them to update every line inside the repeating section
The base abilities are strength, dexterity, iq, health, perception, and will. Each skill in the repeating section is based off one of those attributes, as determined by the value of  repeating_skills_attribute. . When the row in the repeating section is changed, the skill updates, but I need the row to also update when the attribute is changed. So, if the value for strength changes, I need every row that has a value of "strength" for  repeating_skills_attribute  to update. When dexterity changes, I need every row where  repeating_skills_attribute  is set to "dexterity: to update, etc.
So I found a snippet that I could modify to work and ended up with this: on('change:strength', function () {     getSectionIDs('repeating_skills', function (ids) {         const fieldnames = [];         ids.forEach(id => {             fieldnames.push('repeating_skills_' + id + '_st');         });         getAttrs(['strength'], function (values) {             const output = {};             const str = parseInt(values.strength) || 0;             ids.forEach(id => {                 output['repeating_skills_' + id + '_st'] = str;             });             setAttrs(output);         });     }); }); I can duplicate that for each of the other attributes, and it works fine, but that seems like a lot of unnecessary code. How do I do the above for each of the six attributes in a single loop?
1627554793

Edited 1627606525
GiGs
Pro
Sheet Author
API Scripter
You dont want to do this for each attribute, you should put them all in one worker. It#s not easy to figure out how to do it, because your code in your last post uses different attributes to the first post. I've adapted your first worker. It could be written more elegantly, but I kept the same layout as your worker (except for correcting the if statements by adding else s), so you can see what's going on. on ( `change:repeating_skills:skillmod change:repeating_skills:attribute change:strength change:dexterity change:iq change:health` ,  function (){      getSectionIDs ( 'repeating_skills' ,  function  ( ids ) {          const   fieldnames  = [];          ids . forEach ( id   =>  {              fieldnames . push (                  `repeating_skills_ ${ id } _skillMod` ,                  `repeating_skills_ ${ id } _attribute`             );         });          getAttrs ([ ...fieldnames , "strength" , "dexterity" , "iq" , "health" ],  function ( value ){              let   st = 1 *( value [ `strength` ])|| 0 ;              let   dx = 1 *( value [ `dexterity` ])|| 0 ;              let   iq = 1 *( value [ `iq` ])|| 0 ;              let   ht = 1 *( value [ `health` ])|| 0 ;              let   per = 1 *( value [ `perception` ])|| 0 ;              let   will = 1 *( value [ `will` ])|| 0 ;              const   output  = {};              ids . forEach ( id   =>  {                  let   modVal = 1 *( value [ `repeating_skills_ ${ id } _skillMod` ])|| 0 ;                  let   attr =( value [ `repeating_skills_ ${ id } _attribute` ]);                  if ( attr == "ST" ){                      modVal = modVal + st                 }  else   if ( attr == "DX" ){                      modVal = modVal + dx                 }  else   if ( attr == "IQ" ){                      modVal = modVal + iq                 }  else   if ( attr == "HT" ){                      modVal = modVal + ht                 }  else   if ( attr == "PER" ){                      modVal = modVal + per                 }  else   if ( attr == "WILL" ){                      modVal = modVal + will                 }                  output [ `repeating_skills_ ${ id } _skillLevel` ] =  modVal ;                  output [ `repeating_skills_ ${ id } _name` ] =  attr ;             });              setAttrs ( output );         });      }); }); I notice you have a repeating_skills_attribute and a repeating_skills_name which seem to hold identical values. This seems odd. One of them isn't needed.
If there is a more elegant way to do this (and I have no doubt that there is) I would much prefer that. The above looks like exactly what I was trying to figure out, but when I tried it, it just sets all the values to zero.  To start from the beginning, each skill has a difficulty of Easy(-1), Average(-2), Hard(-3), or Very Hard.(-4). Each skill is also associated with a base attribute (strength, dexterity, iq, health, perception, or will). The actual skill Level is the base attribute score + difficulty + skill Modifier.  The stripped down html is: <input type="hidden" name="attr_strength" value="10"/> <span name="attr_strength"></span> <input type="hidden" name="attr_dexterity" value="10"/> <span name="attr_dexterity"></span> <input type="hidden" name="attr_iq" value="10"/> <span name="attr_iq"></span> <input type="hidden" name="attr_health" value="10"/> <span name="attr_health"></span> <input type="hidden" name="attr_perception" value="10"/> <span name="attr_perception"></span> <input type="hidden" name="attr_will" value="10"/> <span name="attr_will"></span>                             <fieldset class="repeating_skills">                                 <div class="skillRow">                                     <select name="attr_skillTL" class="skillTLSelect">                                         <option>0</option>                                         <option>1</option>                                         <option>3</option>                                         <option>4</option>                                         <option>5</option>                                         <option>6</option>                                         <option>7</option>                                         <option>8</option>                                         <option selected>9</option>                                         <option>10</option>                                         <option>11</option>                                         <option>12</option>                                     </select>                                     <input type="text" name="attr_name" class="skillName" value="New Skill"/>                                     <input type="hidden" name="attr_skillLevel" value="0"/>                                     <div class="skillSpan"><span name="attr_skillLevel"></span></div>                                     <button type="roll" class="d6" value="@{chatMode}&{template:skillRoll}{{rollType=@{name} Check}}{{Level=@{skillLevel}}}{{modifier=?{Modifier|0}}}{{roll=[[[[([[([[1d6]]+[[1d6]]+[[1d6]]-(@{skillLevel}+?{Modifier|0}))*-1]]-(@{skillLevel}+?{Modifier|0}))*-1]]]]}}{{r0=$[[0]]}}{{r1=$[[1]]}}{{r2=$[[2]]}}{{target=[[@{skillLevel}+?{Modifier|0}]]}}{{margin=$[[3]]}}{{minus9=[[@{skillLevel}-9]]}}{{plus9=[[@{skillLevel}+9]]}}"></button>                                     <select name="attr_attribute" class="attrSelect">                                         <option>ST</option>                                         <option>DX</option>                                         <option>IQ</option>                                         <option>HT</option>                                         <option>PER</option>                                         <option>WILL</option>                                     </select>                                     <select name="attr_difficulty" class="difficultySelect">                                         <option value="-1">Easy</option>                                         <option value="-2">Average</option>                                         <option value="-3">Hard</option>                                         <option value="-4">Very Hard</option>                                     </select>                                     <input type="number" name="attr_skillMod" class="modInput" value="0"/>                                     <input type="number" name="attr_skillCost" class="modInput" value="0"/>                                                                                   <button type="roll" class="macroButton" title="Macro" value="@{macroText}"></button>                                     <textarea class="macroText" name="attr_macroText"></textarea>                                                                      </div>                             </fieldset> If it is any help, the full sheet is:  HTML     CSS
1627606589
GiGs
Pro
Sheet Author
API Scripter
I made a couple of syntax errors in the above code. Thats what I get for posting just before bed. The on(change) line and the getAttrs line both contained errors. I've fixed the code above.
1627607463
GiGs
Pro
Sheet Author
API Scripter
If you want to make the code a touch more elegant, you should match up the attributes names (strength, dexterity, etc) used in the select dropdown - don't use ST, DX, etc in one place, and strength, dexterity, etc in the other. That allows you to use this for the worker:     on(`change:repeating_skills:skillmod change:repeating_skills:attribute change:st change:dx change:iq change:ht change:per change:will`, function(){         console.log('triggered');         getSectionIDs('repeating_skills', function (ids) {             const fieldnames = [];             ids.forEach(id => {                 fieldnames.push(                     `repeating_skills_${id}_skillMod`,                     `repeating_skills_${id}_attribute`                 );             });             getAttrs([...fieldnames,"ST","DX","IQ","HT", "PER", "WILL"], function(value){                 const output = {};                 ids.forEach(id => {                     let modVal= +value[`repeating_skills_${id}_skillMod`]||0;                     let attr=value[`repeating_skills_${id}_attribute`];                     let attrmod = +value[attr]||0;                     output[`repeating_skills_${id}_skillLevel`] = modVal + attrmod;                     output[`repeating_skills_${id}_name`] = attr;                 });                 setAttrs(output);             });          });     }); Here I assumed you changed the names at the start. It would be easier ti change the select, but those names seem more sensible. In this worker, you grab the attribute name from the select as before, but then you grab the attribute value directly, with                     let attrmod = +value[attr]||0; Since the attributes have been included in getAttrs, and have the same name as in the select dropdown, you can just use that dropdown name to grab their value. Final bit of advice, something to do with all selects, is this:      < select   name = "attr_attribute"   class = "attrSelect" >              < option   selected > - </ option >              < option > ST </ option >              < option > DX </ option >              < option > IQ </ option >              < option > HT </ option >              < option > PER </ option >              < option > WILL </ option >          </ select >          Add an option at the start for when players haven't selected something, and use selected to make that the default. Without this, its easy for players to assume that ST is selected, because it is showing in the dropdown. But it isn't. And the only way to select it is first select something else, and then go back to ST. You could instead make sure the first entry is actually selected, like so:      < select   name = "attr_attribute"   class = "attrSelect" >              < option selected > ST </ option >              < option > DX </ option >              < option > IQ </ option >              < option > HT </ option >              < option > PER </ option >              < option > WILL </ option >          </ select >          But I prefer the first option. You need to do this for all selects.