It sounds like you are trying to have a dynamic list of skills and reference those skills in another dynamic list (your abilities). This unfortunately is not doable without quite a bit of legwork with javascript. The way you could do this is to have the two repeating sections, have each of them contain a name attribute along with whatever bonus is going to be used. Then Use a text input for the user to enter the name of the skill that they want to associate with their ability. The sheetworker will then pick up the name and compare it to the names of the skills and then grab the appropriate bonus. It might look something like this (untested, likely doesn't address all edge cases, and very inefficient): HTML <fieldset class="repeating_skill">
<input type='text' name='attr_name'>
<input type='number' name='attr_bonus'>
</fieldset><fieldset class="repeating_ability">
<input type='text' name='attr_name'>
<input type='text' name='attr_skill'>
<input type='number' name='attr_bonus'>
<input type='number' name="attr_skill_bonus">
<input type='number' readonly name='attr_total'>
</fieldset> Sheetworker on('change:repeating_ability:skill change:repeating_skill:name change:repeating_skill:bonus',()=>{
// Get the row IDs for all of our skills
getSectionIDs('repeating_skill',(skillIDs) => {
// Assemble the complete skill row names
const skillRows = skillIDs.map(id => `repeating_skill_${id}`)
// Get all ability ids
getSectionIDs('repeating_ability',(abilityIDs) => {
// Assemble the complte ability row names
const abilityRows = abilityIDs.map(id => `repeating_skill_${id}`);
// Assemble an array of attribute names to get that will include all of our skill attributes and all the attributes necessary to calculate our ability totals
const getArray = [...skillRows,...abilityRows].reduce((arr,row) => {
arr.push(`${row}_name`);
if(row.startsWith('repeating_ability')){
arr.push(`${row}_skill`,`${row}_bonus`);
}else{
arr.push(`${row}_bonus`);
}
return arr;
},[])
// Finally get the attributes from the database
getAttrs(getArray,(attributes) => {
// empty object that will store our changes so that we can apply them all at once.
const setObj = {};
// Iterate over each ability row. Find the skill
// that matches its skill entry and add that bonus
// to the ability's bonus to get the total for
// that ability
abilityRows.forEach(abilityRow => {
const skillRow = skillRows.find(sRow => attributes[`${sRow}_name`].toLowerCase() === attributes[`${abilityRow}_skill`].toLowerCase());
const skillBonus = +attributes[`${skillRow}_bonus`] || 0;
setObj[`${abilityRow}_skill_bonus`] = skillBonus
setObj[`${abilityRow}_total`] = skillBonus + (+attributes[`${abilityRow}_bonus`] || 0);
});
// Apply our changes. I nearly always apply changes
// silently to avoid unwanted setAttrs cascades.
setAttrs(setObj,{silent:true});
});
});
});
}); This was thrown together pretty quick and is probably the most inefficient way to do this (or damn close). Some ways to improve the efficiency would be: Have a separate listener for each of ability skill entry change, ability bonus change, skill bonus change, and the skill name change. There's probably a better way to filter through all abilities and all skills to find the ones that match. (although doing the optimization above mostly negates the need for this)