Thank you. To clarify (I often have difficulty communicating effectively) I do not at all think you are being luddites or that you are wrong. I was only trying to say that it is the only tool I have to help me do this, other than to pester you all with all my myriad ideas, and I didn't want to pass myself off as if I personally am writing all this script by hand, or as if I can answer all of your questions using my own knowledge, when in fact I have been reliant on the AI to help me. That's all, and I do not doubt that you know more about how roll20 works. I appreciate your help and insights more than you can know. I feel bad asking someone to write code for me from whole cloth.
So based on the excellent advice you have given, I now have it correctly detecting that a checkbox has been ticked to "on" (true/1), it is able to extract the selected row ID from the sourceAttribute, and it moves the newly ticked row to the top (more or less). Already-ticked rows remain ticked and at/near the top (excellent), while unticked rows remain below all the ticked rows (excellent). That is nearly working as intended, the problem I have been trying to solve for several hours now is why the reordering within groups of ticked and unticked seems unexpected. Ticked rows might go to the very top of the list or might go to the bottom of the other ticked rows. Unticked rows do stay below all the ticked ones as intended, but they get reordered oddly instead of merely being pushed down one row. It is difficult to find a pattern. I wonder if it is applying something like alphabetical order based on row ID or something, clumping them into the two groups but unnecessarily reordering them within their own groups.
For example, I will start with the weapons ordered Pistol 1, Pistol 2, Pistol 3, Pistol 4, and Pistol 5. I will tick "on" Pistol 3, and the expected order should be 3 (ticked), 1, 2, 4, 5 (so #3 rises to the top, all the others get pushed down but otherwise in the same order they had previously been in). But what I actually get is 3 (ticked), 4, 5, 2, 1. This weirdness is repeatable whenever no rows are already checked. If I start with 1, 2, 3, 4, 5 and tick row #4, I would expect the new order to be 4 (ticked), 1, 2, 3, 5 but instead I get 4 (ticked), 3, 5, 2, 1. If I untick and reorder all the weapons, close the sheet and refresh the roll20 game, when I click #4 again I get the exact same results (so they're not entirely random). If I leave a row ticked and at the top, when I tick a new row it will move up to the top, but whether it gets moved to the very top of the list or merely above the unticked rows is a gamble. I'm sure there is a pattern but I can't find it.
The code below is what I am using, I am sure it is not up to snuff but it's where I am at. If you're able to see where it has gone awry, I'd be very grateful, as always.
on("change:repeating_weapons:weapon_selected", function(eventInfo) {
getAttrs([eventInfo.sourceAttribute], function(values) {
console.log("Checkbox Changed - Raw Value:", values[eventInfo.sourceAttribute]);
if (values[eventInfo.sourceAttribute] !== "on") {
console.log("Checkbox was unchecked; no reordering needed.");
return;
}
// Extract the row ID manually
let sourceSectionID = eventInfo.sourceAttribute.split("_")[2];
console.log("Checkbox checked for:", sourceSectionID); // Debugging
getSectionIDs("weapons", function(idArray) {
console.log("Original Weapon Order:", idArray);
// Get checked state for all rows
let attrNames = idArray.map(id => `repeating_weapons_${id}_weapon_selected`);
getAttrs(attrNames, function(allValues) {
let weaponData = idArray.map(id => ({
id: id,
checked: allValues[`repeating_weapons_${id}_weapon_selected`] === "on"
}));
// Sort: Checked items first, but maintain relative order
let sortedArray = weaponData
.sort((a, b) => b.checked - a.checked) // Move checked rows up
.map(w => w.id); // Extract only the IDs
console.log("New Weapon Order:", sortedArray);
setSectionOrder("weapons", sortedArray);
});
});
});
});
I did try dozens of fixes, some of them were improvements but none of them quite worked so I won't bore you with them all. I did find that changing sorting of b.checked - a.checked to a more complex method, variations on something like this:
let sortedArray = [
sourceSectionID, // Always put the newly checked row at the top
...checkedRows.filter(id => id !== sourceSectionID), // Keep previously checked rows below
...idArray.filter(id => !checkedRows.includes(id)) // Keep unchecked rows in original order
];
made it more predictable but still not quite right, it was still reordering rows that should have essentially just been pushed down.
Having everything reorder instead of merely being pushed down the order seems like unwanted behavior that hopefully we can stop. My goal now is to move a newly ticked row to the bottom of any already-ticked rows (i.e. the top of the unticked rows). Each newly ticked row would then appear under any already ticked rows, and all unticked rows would maintain their current relative order below those, merely being pushed down, rather than further reordering themselves as they currently are doing.
Thank you in advance for any insights.