Compare commits

...

4 Commits

Author SHA1 Message Date
Philippe Torrel
af6de5618b feat: added Actions 2026-07-17 14:47:58 +02:00
Philippe Torrel
ddc774e0dd feat: added initProduct 2026-07-17 13:25:58 +02:00
Philippe Torrel
b23ee7e29b added js 2026-07-17 13:09:44 +02:00
Philippe Torrel
87c6fc71ff added gitignore 2026-07-17 11:35:10 +02:00
7 changed files with 265 additions and 16 deletions

View File

@@ -0,0 +1,11 @@
node_modules/
dist/
.env
.env.local
.env.*.local
.DS_Store
*.log
.vite/
coverage/
.idea/
# .vscode/

View File

@@ -24,3 +24,11 @@ body {
margin-bottom: 0;
}
}
.product-manager table .th-actions {
width: 150px;
}
.product-manager table tbody td button {
margin: 3px;
}

View File

@@ -2,18 +2,176 @@
(() => {
// === DOM & VARS =======
const DOM = {};
const module = document.querySelector('.product-manager') || console.error('Product Manager not found');
const DOM = {
table: module.querySelector('.table-products'),
tBody: module.querySelector('tbody'),
inputName: module.querySelector('.input-product-name'),
inputPrice: module.querySelector('.input-product-price'),
btnAdd: module.querySelector('.button-product-add'),
};
console.log(DOM);
// === INIT =============
const init = () => {
console.log('init');
// Funktionaufrufe zu beginn der Anwendung
initProducts();
// Event-Lauscher zu beginn der Anwendung
DOM.btnAdd.addEventListener('click', onClickAdd);
};
// === EVENTHANDLER =====
const onClickAdd = (e) => {
console.log('click');
const product = {
name: DOM.inputName.value,
price: Number(DOM.inputPrice.value),
};
addProduct(product);
};
const onClickRemove = (e) => {
const btnEl = e.currentTarget;
const currentRowEl = btnEl.parentNode.parentNode;
currentRowEl.remove(); // kein IE11 support
// DOM.tBody.removeChild(currentRowEl);
};
const onClickMoveUp = (e) => {
const btnEl = e.currentTarget;
const currentRowEl = btnEl.parentNode.parentNode; // aktuelle Zeile (tr) mit dem Button
// ParentNode.insertBefore(referenceElement, targetElement)
DOM.tBody.insertBefore(currentRowEl, currentRowEl.previousElementSibling);
console.log('move up');
};
const onClickMoveDown = (e) => {
const btnEl = e.currentTarget;
const currentRowEl = btnEl.parentNode.parentNode; // aktuelle Zeile (tr) mit dem Button
// ParentNode.insertBefore(referenceElement, targetElement)
DOM.tBody.insertBefore(currentRowEl, currentRowEl.nextElementSibling.nextElementSibling);
console.log('move down');
};
// === XHR/FETCH ========
// === FUNCTIONS ========
const initProducts = () => {
PRODUCTS.forEach((product) => {
addProduct(product);
});
// PRODUCTS.forEach(addProduct);
};
const addProduct = (product) => {
const { name, price } = product;
const tdName = createTd(name, 'td-name');
const tdPrice = createTd(price, 'td-price');
const tdActions = createTdWithActions();
const trEl = createTr(tdName, tdPrice, tdActions);
DOM.tBody.appendChild(trEl); // Im DOM hinzufügen
};
const createTdWithActions = () => {
const td = document.createElement('td');
td.classList.add('td-actions');
const btnRemove = createButtonRemove();
const btnMoveUp = createButtonMoveUp();
const btnMoveDown = createButtonMoveDown();
// td.append(btnRemove, btnMoveUp, btnMoveDown)
td.appendChild(btnRemove);
td.appendChild(btnMoveUp);
td.appendChild(btnMoveDown);
return td;
};
const createButtonRemove = () => {
const btn = document.createElement('button');
const icon = document.createElement('i');
const span = document.createElement('span');
btn.classList.add('btn', 'btn-sm', '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.append(icon,span)
btn.appendChild(icon);
btn.appendChild(span);
return btn;
};
const createButtonMoveUp = () => {
const btn = document.createElement('button');
const icon = document.createElement('i');
const span = document.createElement('span');
btn.classList.add('btn', 'btn-sm', 'btn-secondary', 'button-product-move-up');
icon.classList.add('fas', 'fa-caret-up');
span.classList.add('visually-hidden');
span.textContent = 'Move Up';
btn.addEventListener('click', onClickMoveUp);
// btn.append(icon,span)
btn.appendChild(icon);
btn.appendChild(span);
return btn;
};
const createButtonMoveDown = () => {
const btn = document.createElement('button');
const icon = document.createElement('i');
const span = document.createElement('span');
btn.classList.add('btn', 'btn-sm', 'btn-secondary', 'button-product-move-down');
icon.classList.add('fas', 'fa-caret-down');
span.classList.add('visually-hidden');
span.textContent = 'Move Down';
btn.addEventListener('click', onClickMoveDown);
// btn.append(icon,span)
btn.appendChild(icon);
btn.appendChild(span);
return btn;
};
const createTd = (text, className = '') => {
const td = document.createElement('td');
td.classList.add(className);
td.textContent = text;
return td;
};
const createTr = (...tds) => {
const tr = document.createElement('tr');
tr.append(...tds);
// tds.forEach((td) => {
// tr.appendChild(td);
// });
return tr;
};
init();
})();

View File

@@ -0,0 +1,6 @@
const PRODUCTS = [
{ name: '3Doodler 3D Printing Pen', price: 29.99 },
{ name: 'Powerstation 5- E. Maximus Chargus', price: 44.95 },
{ name: '8-Bit Legendary Hero Heat-Change Mug', price: 6.99 },
{ name: '16-Bit Legendary Hero Heat-Change Mug', price: 10.99 },
];

View File

@@ -0,0 +1,5 @@
[
{ "name": "3Doodler 3D Printing Pen", "price": 29.99 },
{ "name": "Powerstation 5- E. Maximus Chargus", "price": 44.95 },
{ "name": "8-Bit Legendary Hero Heat-Change Mug", "price": 6.99 }
]

View File

@@ -7,6 +7,7 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" />
<link rel="stylesheet" href="assets/css/main.css" />
<script src="data/products.js"></script>
<script src="assets/js/main.js" defer></script>
</head>
<body>
@@ -17,27 +18,34 @@
<table class="table table-striped table-products">
<thead class="table-dark">
<tr>
<th>Name</th>
<th>Price in &euro;</th>
<th class="th-name">Name</th>
<th class="th-price">Price in &euro;</th>
<th class="th-actions">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>3Doodler 3D Printing Pen</td>
<td>29.99</td>
</tr>
<tr>
<td>Powerstation 5- E. Maximus Chargus</td>
<td>44.95</td>
</tr>
<tr>
<td>8-Bit Legendary Hero Heat-Change Mug</td>
<td>6.99</td>
</tr>
<!-- <tr>
<td class="td-name">[PRODUCT_NAME]</td>
<td class="td-price">[PRODUCT_PRICE]</td>
<td class="td-actions">
<button class="btn btn-sm btn-danger button-product-remove">
<i class="fas fa-trash-can"></i>
<span class="visually-hidden">Remove Product</span>
</button>
<button class="btn btn-sm btn-secondary button-product-move-up">
<i class="fas fa-caret-up"></i>
<span class="visually-hidden">Move Up</span>
</button>
<button class="btn btn-sm btn-secondary button-product-move-down">
<i class="fas fa-caret-down"></i>
<span class="visually-hidden">Move Down</span>
</button>
</td>
</tr> -->
</tbody>
<tfoot>
<tr>
<td colspan="2">
<td colspan="3">
<div class="row">
<div class="col-12 col-md-6 col-lg-6">
<input

View File

@@ -0,0 +1,53 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DOM Creation</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/4.0.0/jquery.min.js"></script>
</head>
<body>
<main>
<div class="container py-5">
<h1>DOM Creation</h1>
<hr />
<ul class="list">
<li>Listenpunkt 01</li>
<li>Listenpunkt 02</li>
<li>Listenpunkt 03</li>
<li>Listenpunkt 04</li>
</ul>
</div>
</main>
<script>
'use strict';
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
// Node.innerHTML
$('ul.list').innerHTML += '<li>Listenpunkt 05</li>';
// Node.innerText & Node.textContent
$('ul.list li').textContent = 'Listenpunkt 001';
$('ul.list li:nth-child(2)').innerText = 'Listenpunkt 002';
// document.createElement('HTML_ELEMENT')
const liEl = document.createElement('li');
liEl.textContent = 'Listenpunkt 06';
// Node.cloneNode(true)
const liCloneEl = $('ul.list li').cloneNode(true);
// DOM Manipulation ==========
$('ul.list').appendChild(liEl);
$('ul.list').appendChild(liCloneEl);
// jQuery ====================
// jQuery('<p>test</p>').insertAfter(document.body);
// jQuery('<p></p>', { text: 'ich bin der Inhalt' }).insertAfter(document.body);
// jQuery('<p></p>', { text: 'ich bin der Inhalt' }).insertBefore(document.body);
</script>
</body>
</html>