preserve expanded state across node re-render
introduce a module-level expandedNodeIds set that tracks which nodes the user has manually expanded. renderTree consults the set when deciding initial visibility (falling back to the depth-based default for a fresh load), the toggle click handler keeps the set in sync, and both add-child save handlers add the parent's id before triggering the re-fetch. on a fresh load the set starts empty so root-only-open behavior is unchanged and the existing toggle tests keep passing.
This commit is contained in:
parent
dce4e4a4f6
commit
1342a67cf3
1 changed files with 14 additions and 1 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
const expandedNodeIds = new Set();
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const textId = window.location.pathname.split('/').pop();
|
const textId = window.location.pathname.split('/').pop();
|
||||||
|
|
||||||
|
|
@ -69,7 +71,11 @@ function renderTree(nodes, textId, depth = 0) {
|
||||||
|
|
||||||
if (node.children.length > 0) {
|
if (node.children.length > 0) {
|
||||||
const childUl = renderTree(node.children, textId, depth + 1);
|
const childUl = renderTree(node.children, textId, depth + 1);
|
||||||
const childrenVisible = depth === 0;
|
const childrenVisible =
|
||||||
|
expandedNodeIds.has(node.id) || depth === 0;
|
||||||
|
if (childrenVisible) {
|
||||||
|
expandedNodeIds.add(node.id);
|
||||||
|
}
|
||||||
childUl.style.display = childrenVisible ? '' : 'none';
|
childUl.style.display = childrenVisible ? '' : 'none';
|
||||||
|
|
||||||
const toggleBtn = document.createElement('button');
|
const toggleBtn = document.createElement('button');
|
||||||
|
|
@ -79,6 +85,11 @@ function renderTree(nodes, textId, depth = 0) {
|
||||||
const isHidden = childUl.style.display === 'none';
|
const isHidden = childUl.style.display === 'none';
|
||||||
childUl.style.display = isHidden ? '' : 'none';
|
childUl.style.display = isHidden ? '' : 'none';
|
||||||
toggleBtn.textContent = isHidden ? '▼' : '▶';
|
toggleBtn.textContent = isHidden ? '▼' : '▶';
|
||||||
|
if (isHidden) {
|
||||||
|
expandedNodeIds.add(node.id);
|
||||||
|
} else {
|
||||||
|
expandedNodeIds.delete(node.id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
li.appendChild(toggleBtn);
|
li.appendChild(toggleBtn);
|
||||||
|
|
@ -110,6 +121,7 @@ function toggleAddForm(li, parentNodeId, textId) {
|
||||||
const title = input.value.trim();
|
const title = input.value.trim();
|
||||||
if (!title) return;
|
if (!title) return;
|
||||||
|
|
||||||
|
expandedNodeIds.add(parentNodeId);
|
||||||
fetch('/api/nodes', {
|
fetch('/api/nodes', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|
@ -155,6 +167,7 @@ function toggleBulkAddForm(li, parentNodeId, textId) {
|
||||||
const count = parseInt(countInput.value);
|
const count = parseInt(countInput.value);
|
||||||
if (!titlePrefix || !count || count < 1) return;
|
if (!titlePrefix || !count || count < 1) return;
|
||||||
|
|
||||||
|
expandedNodeIds.add(parentNodeId);
|
||||||
fetch('/api/nodes/bulk', {
|
fetch('/api/nodes/bulk', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue