This commit is contained in:
Philippe Torrel
2026-10-07 14:34:48 +02:00
parent 1fe62103a8
commit 7e6ec5b9ef
35 changed files with 1601 additions and 17 deletions
@@ -20,3 +20,15 @@ body {
margin-bottom: 0;
}
}
.product-manager table td {
vertical-align: middle;
}
.product-manager table td button {
margin: 0 3px;
}
.product-manager table .th-actions {
width: 180px;
}
@@ -34,7 +34,32 @@
};
addProduct(product);
disableNonFunctionalButtons();
};
const onClickRemove = (e) => {
const btn = e.currentTarget;
const currentRow = parents(btn, 'tr')[0]; // btn.closest('tr'); // btn.parentNode.parentNode;
currentRow.remove();
// currentRow.parentNode.removeChild(currentRow); // IE11 support
disableNonFunctionalButtons();
};
const onClickMoveUp = (e) => {
const btn = e.currentTarget;
const currentRow = parents(btn, 'tr')[0];
DOM.tbody.insertBefore(currentRow, currentRow.previousElementSibling);
disableNonFunctionalButtons();
};
const onClickMoveDown = (e) => {
const btn = e.currentTarget;
const currentRow = parents(btn, 'tr')[0];
DOM.tbody.insertBefore(currentRow, currentRow.nextElementSibling.nextElementSibling);
disableNonFunctionalButtons();
};
// === XHR/FETCH ========
// === FUNCTIONS ========
@@ -43,6 +68,7 @@
// addProduct(product);
// });
PRODUCTS.forEach(addProduct);
disableNonFunctionalButtons();
};
const addProduct = (product) => {
@@ -60,21 +86,108 @@
const td = document.createElement('td');
td.classList.add('td-actions');
const btnRemove = document.createElement('button');
const btnRemove = createBtn({
classNames: ['btn-danger', 'button-product-remove'],
iconName: 'trash-can',
label: 'Remove product',
clickHandler: onClickRemove,
});
const btnMoveUp = createBtn({
classNames: ['btn-secondary', 'button-product-move-up'],
iconName: 'chevron-up',
label: 'Move up',
clickHandler: onClickMoveUp,
});
const btnMoveDown = createBtn({
classNames: ['btn-secondary', 'button-product-move-down'],
iconName: 'chevron-down',
label: 'Move down',
clickHandler: onClickMoveDown,
});
td.append(btnRemove, btnMoveUp, btnMoveDown);
return td;
};
// const createBtnRemove = () => {
// const btn = document.createElement('button');
// const icon = document.createElement('i');
// const span = document.createElement('span');
// btn.classList.add('btn', 'btn-danger', 'button-product-remove');
// icon.classList.add('fas', 'fa-trash-can');
// span.classList.add('visually-hidden');
// span.textContent = 'Remove Product';
// btn.addEventListener('click', onClickRemove);
// btn.appendChild(icon);
// btn.appendChild(span);
// return btn;
// };
// const createBtnMoveUp = () => {
// const btn = document.createElement('button');
// const icon = document.createElement('i');
// const span = document.createElement('span');
// btn.classList.add('btn', 'btn-secondary', 'button-product-move-up');
// icon.classList.add('fas', 'fa-chevron-up');
// span.classList.add('visually-hidden');
// span.textContent = 'Move up';
// btn.addEventListener('click', onClickMoveUp);
// btn.appendChild(icon);
// btn.appendChild(span);
// return btn;
// };
// const createBtnMoveDown = () => {
// const btn = document.createElement('button');
// const icon = document.createElement('i');
// const span = document.createElement('span');
// btn.classList.add('btn', 'btn-secondary', 'button-product-move-down');
// icon.classList.add('fas', 'fa-chevron-down');
// span.classList.add('visually-hidden');
// span.textContent = 'Move down';
// btn.addEventListener('click', onClickMoveDown);
// btn.appendChild(icon);
// btn.appendChild(span);
// return btn;
// };
const createBtn = (options = {}) => {
const {
classNames = [],
iconName = 'circle',
label,
clickHandler = (e) => {
console.log('no click action');
},
} = options;
const btn = document.createElement('button');
const icon = document.createElement('i');
const span = document.createElement('span');
btnRemove.classList.add('btn', 'btn-danger', 'button-product-remove');
icon.classList.add('fas', 'fa-trash-can');
btn.classList.add('btn', ...classNames);
icon.classList.add('fas', `fa-${iconName}`);
span.classList.add('visually-hidden');
span.textContent = 'Remove Product';
span.textContent = label;
btnRemove.appendChild(icon);
btnRemove.appendChild(span);
btn.addEventListener('click', clickHandler);
td.appendChild(btnRemove);
btn.appendChild(icon);
btn.appendChild(span);
return td;
return btn;
};
const createTd = (text, ...classNames) => {
@@ -95,5 +208,21 @@
return tr;
};
const disableNonFunctionalButtons = () => {
DOM.tbody.querySelectorAll('tr').forEach((tr) => {
tr.querySelector('.button-product-move-up').disabled = !tr.previousElementSibling;
tr.querySelector('.button-product-move-down').disabled = !tr.nextElementSibling;
});
};
// Helper
function parents(el, selector) {
const parents = [];
while ((el = el.parentNode) && el !== document) {
if (!selector || el.matches(selector)) parents.push(el);
}
return parents;
}
init();
})();
@@ -34,6 +34,14 @@
<i class="fas fa-trash-can"></i>
<span class="visually-hidden">Remove Product</span>
</button>
<button class="btn btn-secondary button-product-move-up">
<i class="fas fa-chevron-up"></i>
<span class="visually-hidden">Move up</span>
</button>
<button class="btn btn-secondary button-product-move-down">
<i class="fas fa-chevron-down"></i>
<span class="visually-hidden">Move down</span>
</button>
</td>
</tr> -->
</tbody>