At least I feel a little better knowing that I am not alone in my struggle. At this point my brain is mush and I'm going to take a break. Here is the last snippet I have been working with, but ever since trying to target each weapon's <select> menu by its row ID, the whole thing has stopped working. <fieldset class="repeating_guncombatspec">
...
<input type="text" class="sheet-input" name="attr_skillSpeciality-GunCombatspec" placeholder="Specialty Name"/>
...
</fieldset> <fieldset class="repeating_weapons">
...
<select class="sheet-input dynamicWeaponSkillMenu" name="attr_dynamicWeaponSkillMenu"></select>
...
</fieldset> <script type="text/worker">
/**
* updateWeaponSkillMenus
*
* This function intends to gather all the gun combat skill names from the Skills section
* and use those names to populate the options in the <select> menu of the Weapons section.
* In this way, each weapon row will have a <select> menu that is only populated with gun skills
* that the PC actually has, they can choose the appropriate skill from the list, and if that skill's
* level is changed in the future, or they gain new gun skills, they only need update it on the Skills page
* and the weapon rows will be automatically updated (rather than need to manually update in two places).
*
* The skill names are stored as repeating_guncombatspec_{rowID}_skillSpeciality-GunCombatspec
* and the <select> element that we want to populate is repeating_weapons_{rowID}_dynamicWeaponSkillMenu.
* Once a skill name has been selected for any weapon row, it should persist so it can later be used
* to automatically calculate their skill bonus for that weapon.
*
* It assumes:
* - Each row in the Skills fieldset "repeating_guncombatspec" has an input with the name:
* repeating_guncombatspec_{rowID}_skillSpeciality-GunCombatspec
* - Each row in the Weapons fieldset "repeating_weapons" has a <select> element with class "dynamicWeaponSkillMenu"
* and name "attr_dynamicWeaponSkillMenu", and the row container’s id is of the form:
* repeating_weapons_{rowID}
*
* Note: In sheet worker calls, attribute names are referenced without the "attr_" prefix.
*
* This approach had worked for populating a more global <select> menu, it correctly gathered the skill names
* and populated all the weapon rows' <select> menu with those skill names. However, having realized that
* this was creating one global <select> menu rather than one for each weapon row, I am now trying to populate
* each <select> menu by using its repeating_weapons_{rowID} but that has failed. It no longer populates any
* <select> menu options at all.
*
* Note: I found a tip to remove all capital letters and dashes, however, as this had been working
* globally before I tried to target <select> row IDs, and all other references to row IDs have worked,
* I'm not sure that is the issue. Something to keep in mind if all else fails, and for future naming conventions.
*/
const updateWeaponSkillMenus = () => {
// Step 1: Build a global options array from the gun combat skills.
getSectionIDs("repeating_guncombatspec", function(skillIDs) {
let skillAttrNames = [];
skillIDs.forEach(function(id) {
// Build full attribute name as it appears on your sheet.
skillAttrNames.push("repeating_guncombatspec_" + id + "_skillSpeciality-GunCombatspec");
});
getAttrs(skillAttrNames, function(skillValues) {
let globalOptions = [];
skillIDs.forEach(function(id) {
let attrName = "repeating_guncombatspec_" + id + "_skillSpeciality-GunCombatspec";
let skillName = skillValues[attrName] || "";
// Only add non-empty skill names.
if (skillName) {
globalOptions.push({
label: skillName,
value: skillName
});
}
});
log("Global Options Array: " + JSON.stringify(globalOptions));
// Step 2: Update each row in the repeating_weapons section.
getSectionIDs("repeating_weapons", function(weaponIDs) {
weaponIDs.forEach(function(weaponID) {
// Build the attribute name for this row's dynamic menu.
const menuAttr = "repeating_weapons_" + weaponID + "_dynamicWeaponSkillMenu";
// Retrieve the current stored value for this row.
getAttrs([menuAttr], function(weaponVals) {
const currentValue = String(weaponVals[menuAttr] || "");
log("Row " + weaponID + " current stored value: " + currentValue);
// Create a row-specific options array.
// Mark an option as selected if it equals the current stored value.
let rowOptions = globalOptions.map(function(opt) {
return {
label: opt.label,
value: opt.value,
selected: (opt.value === currentValue && currentValue !== "")
};
});
// Construct a selector for the <select> element in this row.
// We assume the row container's id is "repeating_weapons_" + weaponID.
const sel = "#repeating_weapons_" + weaponID + " .dynamicWeaponSkillMenu";
log("Updating row " + weaponID + " using selector: " + sel);
// Populate the select element using populateListOptions.
populateListOptions({
elemSelector: sel,
optionsArray: rowOptions,
overwrite: true,
callback: function() {
log("Row " + weaponID + " dynamicWeaponSkillMenu updated. Current value: " + currentValue);
}
});
});
});
});
});
});
};
// Run the update function when the sheet is opened and when the repeating_weapons section changes.
on("sheet:opened", updateWeaponSkillMenus);
on("change:repeating_weapons", updateWeaponSkillMenus);
</script>