GiGs said: In your final sheet worker you have this: getAttrs(["repeating_section_attr_op2"] let op2 = parseInt(values.op2)||0; That should be getAttrs(["repeating_section_op2"] let op2 = parseInt(values.repeating_section_op2)||0; The attr_ part is not part of the attribute name, its just a prefix used by roll2-'s back-end to let it know this is an attribute. The only time you ever use it is when creating the attribute in html. Secondly, you have sheet:opened in that worker. You'll need to either replace that or change the sheet worker. There are two syntaxes ofr accessing attributes in repeating sections, one is compatible with sheet:opened, and one is npt. You are using the version that is not. Note: If setAttrs is trying to change an attribute inside the repeating section, its name will need changing too. Here's something ypou might be missing.op2 is not the name of an attribute. A fieldset is like a construction kit: it tells roll20 how to build each attribute in a repeating section. Remember a repeating section can be multiple rows, and a full attribute name is unique, and identifes every attribute in the section. The full name of every attribute in a repeating sectio is made of three parts and really looks like this: repeating_section_-gy5uw8wg_op2 The three parts of the repeating section attribute are: The repeating section name The row id (this is randomly generated, so looks weird like my example) The field name: this is the name of sapecific sub-attributes in the repeating section, like op2. Roll20 needs the full name of the attribute to do anything with it and you can get that with the getSectionIDs function (which gives you each row id). But in the abbreviated form you have used, roll20 always knows which row the worker is being triggered from (its the one where you just manually chnaged an attribute),so it supplies the row id for you - you don't need to know it. Thi is why sheet:opened cant be used with this kind of worker (well, it can, but it willr eport an error). shet:opened tries to run the worker on every row in the section, but this syntax only works with one row at a time. If you want to learn more: <a href="https://cybersphere.me/roll20-sheet-author-master-list/" rel="nofollow">https://cybersphere.me/roll20-sheet-author-master-list/</a> (I really need to shorten that url), Hi GiGs, thank you always for your input, it's very much appreciated! I accidently forgot to delete the part about attr_ when I was creating the example. I managed to get this working by referencing the repeating section article and by trial and error. I know my code will look messy to programmers, but here is my final result (leaving this here in case anyone else has the same question!): Code for non-repeating section <select class="spell-type" name="attr_spell_type">
<option value="7"></option>
<option value="0">SP</option>
<option value="1">STR</option>
<option value="2">DEX</option>
<option value="3">CON</option>
<option value="4">INT</option>
<option value="5">WIS</option>
<option value="6">CHA</option>
<option value="7">ETC</option>
</select>
on("change:spell_type_01 sheet:opened", function() {
getAttrs(["spell_type_01"], function(values) {
let spell_type_01 = parseInt(values.spell_type_01) || 0;
let spl_atk, spl_dc;
switch (spell_type_01) {
case 0:
spl_atk = "@{spell_atk}";
spl_dc = "";
break;
case 1:
spl_atk = "0";
spl_dc = "DC STR @{spell_dc}";
break;
case 2:
spl_atk = "0";
spl_dc = "DC DEX @{spell_dc}";
break;
case 3:
spl_atk = "0";
spl_dc = "DC CON @{spell_dc}";
break;
case 4:
spl_atk = "0";
spl_dc = "DC INT @{spell_dc}";
break;
case 5:
spl_atk = "0";
spl_dc = "DC WIS @{spell_dc}";
break;
case 6:
spl_atk = "0";
spl_dc = "DC CHA @{spell_dc}";
break;
case 7:
spl_atk = "0";
spl_dc = "";
break;
default:
spl_atk = "@{spell_atk}";
spl_dc = "";
break;
}
setAttrs({
"foo_spl_atk": spl_atk,
"foo_spl_dc": spl_dc
});
});
}); code for repeating section under fieldset class "repeating_spell" <input class='hidden' type='text' name='attr_rep_atk' readonly />
<input class='hidden' type='text' name='attr_rep_dc' readonly />
<select class="spell-type" name="attr_spell_type">
<option value="7"></option>
<option value="0">SP</option>
<option value="1">STR</option>
<option value="2">DEX</option>
<option value="3">CON</option>
<option value="4">INT</option>
<option value="5">WIS</option>
<option value="6">CHA</option>
<option value="7">ETC</option>
</select>
on('sheet:opened change:repeating_spell:spell_type', function() {
getSectionIDs('spell', function(idarray) {
// first get the attribute names for all rows in put in one array
const fieldnames = [];
idarray.forEach(id => fieldnames.push(`repeating_spell_${id}_spell_type`));
getAttrs(fieldnames, values => {
// create a variable to hold all the attribute values youre going to create.
const attr = {};
// now loop through the rows again
idarray.forEach(id => {
let row = 'repeating_spell_' + id;
let sptype = values[`${row}_spell_type`] || 0;
if (sptype == 0) {
attr[`${row}_rep_atk`] = "@{spell_atk}";
attr[`${row}_rep_dc`] = "";
}
else if (sptype == 1) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC STR @{spell_dc}";
}
else if (sptype == 2) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC DEX @{spell_dc}";
}
else if (sptype == 3) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC CON @{spell_dc}";
}
else if (sptype == 4) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC INT @{spell_dc}";
}
else if (sptype == 5) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC WIS @{spell_dc}";
}
else if (sptype == 6) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "DC CHA @{spell_dc}";
}
else if (sptype == 7) {
attr[`${row}_rep_atk`] = "0";
attr[`${row}_rep_dc`] = "";
}
else {
attr[`${row}_rep_atk`] = "@{spell_atk}";
attr[`${row}_rep_dc`] = "";
}
});
console.log(values,attr)
setAttrs(attr);
});
});
});