Problem/Motivation
Reordering terms by drag-and-drop persists the weight of the dragged term only. Displaced siblings get their new weight in the DOM but are never staged, so on "Save Order" they keep their old weight.
Result: moving the 2nd term (weight 1) to the top saves it as weight 0 while the previous top term stays weight 0 — two terms share weight 0 and ordering breaks. "Normalize Weights" fixes it once, but the next drag re-introduces the collision. Up/down buttons are unaffected (they stage both swapped terms).
Steps to reproduce
1. Open a vocabulary with 3+ root terms in the manager.
2. Drag the 2nd term to the top.
3. Click "Save Order".
4. Inspect weights → moved term and former top term both = 0.
Proposed resolution
In the drag onEnd handlers (etm-sortable.js, etm-drilldown.js), stage every displaced sibling, not just the dragged term. Stage only siblings whose weight actually changed, so the unsaved-changes count stays accurate. Add a side-effect-free Drupal.etm.stageTermPosition() helper (no DOM relocation) and keep the data-weight attribute in sync for change detection across successive drags. Server saveOrderBatch() already handles multi-term batches — no backend change needed.
Issue fork etm-3601278
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
hanoiiComment #4
hanoiiFollow-up UX refinements on top of the weight-staging fix:
1. Unsaved-changes count reflects intent. Staging the moved term plus every reweighted sibling meant the counter showed all shifted weights (e.g. moving position 10 → 1 reported ~10 changes). Added a separate Drupal.etm._movedTids set that tracks only the term the user actually moved — anything routed through updateTermPosition (drag, up/down, nest, move-modal), not the siblings staged via stageTermPosition. The counter and warning bar now read from this set, while _pendingChanges still carries all weights so the batch save stays correct. Cleared on save/discard.
2. Changed-row indicator (like core tabledrag). The moved term gets a persistent etm-term-changed class → amber left-border + dot, in both tree and drill-down views. Only the dragged/moved row is marked, not the reweighted siblings.
3. Single visual cue. A moved row previously got the transient green success flash and the new amber indicator, producing a green→amber transition. The green highlight-success flash is now suppressed on rows that also carry etm-term-changed (scoped so clone/add/search success flashes are unaffected).
Files: js/etm-core.js, css/etm-tree.css, css/etm-drilldown.css.
Comment #5
hanoiiThe saving/success messages used the server's saved-row count (every
reweighted sibling), so moving position 10 to 1 reported ~10 saved
while the unsaved counter showed 1. Build the messages client-side
from _movedTids.size, captured before the set is cleared on success.
Comment #6
hanoiiComment #10
thronedigital commentedThanks!