diff --git a/03_dom/agenda.md b/03_dom/agenda.md
index dcbbbf8..fb467d2 100644
--- a/03_dom/agenda.md
+++ b/03_dom/agenda.md
@@ -400,14 +400,14 @@ Projektarbeit
- Import von Modulen in JS (Browserseitig)
- Separation of Concerns
-- Projekt: Produktmanager II mit JSON
+- Projekt: Produktmanager final
- DOM Traversal Befehle & alle DOM Bereiche
-- insertBefore(), appendChil(), append(), prepend(), before(), after()
+- insertBefore(), appendChild(), append(), prepend(), before(), after()
- Refactoring von Produktmanager mit Template
**Übungen:**
-Übung 17 - 18 + optionale Übungen
+Übung 18 + optionale Übungen
**Projektarbeit / Content Factory**
---
diff --git a/03_dom/uebungen/u15_tasse-01001/index.html b/03_dom/uebungen/u15_tasse-01001/index.html
index 78bb0f8..88da7b7 100644
--- a/03_dom/uebungen/u15_tasse-01001/index.html
+++ b/03_dom/uebungen/u15_tasse-01001/index.html
@@ -1,4 +1,4 @@
-
+
@@ -97,13 +97,38 @@
const $ = (qs) => document.querySelector(qs);
const $$ = (qs) => Array.from(document.querySelectorAll(qs));
+ const productList = $('#product_specification');
+ const orderedList = $('.model');
+ const selectBox = $('#buy_form select');
+
// Übung 15: — Teil 7
// Verändere die Produktseite der Binär-Tasse mithilfe von JavaScript. Du kannst wieder die JS-Konsole verwenden.
// 1. Füge in der Liste der Product Specifications mithilfe von JavaScript folgenden Listenpunkt hinzu:
// Capacity: 11 oz.
+ $('#product_specification').innerHTML += 'Capacity: 11 oz.';
+
+ const newListItem = document.createElement('li');
+ newListItem.textContent = 'Capacity: 11 oz.';
+ newListItem.style.color = 'orange';
+ newListItem.style.backgroundColor = 'black';
+
+ productList.appendChild(newListItem); //productList.append(newListItem)
// 2. Erweitere die Select-Box neben dem buy-Button mithilfe von JavaScript um den Eintrag: 5 items.
+ const newOption = document.createElement('option');
+ newOption.textContent = '5 items';
+ selectBox.append(newOption);
+ // newOption.style.textContent = 'red';
+
+ $('#buy_form select').innerHTML += '';
+
+ // optional Listenpunkt in ordered List (.model) hinzugefügt
+ const listItem2 = document.createElement('li');
+ listItem2.textContent = 'fuente item hinzugefügt als Newitem';
+ listItem2.style.color = 'orange';
+ listItem2.style.backgroundColor = 'black';
+ orderedList.append(listItem2);
}
diff --git a/03_dom/uebungen/u16_tasse-01001/index.html b/03_dom/uebungen/u16_tasse-01001/index.html
index 58d8753..f8aecee 100644
--- a/03_dom/uebungen/u16_tasse-01001/index.html
+++ b/03_dom/uebungen/u16_tasse-01001/index.html
@@ -1,4 +1,4 @@
-
+
@@ -101,8 +101,14 @@
// Verändere erneut die Produktseite der Binär-Tasse mithilfe von JavaScript. Du kannst auch hier wieder die JS-Konsole verwenden.
// 1. Entferne die Überschrift Description mit der remove-Methode.
+ const firstH2El = $('h2');
+ firstH2El.remove(); // IE 11
+ // firstH2El.parentNode.removeChild(firstH2El)
// 2. Entferne mit der remove-Methode den Text "010010000100111101010100" aus der Hauptüberschrift.
+ const remSpan0100 = $('h1.article > span.keyword'); // $('h1 .keyword');
+ remSpan0100.remove();
+ // remSpan0100.parentNode.removeChild(remSpan0100);
}
diff --git a/03_dom/uebungen/u17_tasse-01001/index.html b/03_dom/uebungen/u17_tasse-01001/index.html
index 5b9ded8..ee50087 100644
--- a/03_dom/uebungen/u17_tasse-01001/index.html
+++ b/03_dom/uebungen/u17_tasse-01001/index.html
@@ -1,4 +1,4 @@
-
+
@@ -105,6 +105,34 @@
// Capacity: 11 oz.
// Füge den Listenpunkt aber dieses Mal nicht am Ende der Liste ein, sondern vor dem Eintrag Materials: Ceramic.
+ const list = $('#product_specification');
+ const item5 = $$('#product_specification li')[4];
+ // const listItem5 = $('#product_specification li:nth-child(5)');
+ // const listItem5 = $('#product_specification').lastElementChild.previousElementSibling; // DOM Traversal
+
+ console.log(item5);
+
+ const newList = document.createElement('li');
+ newList.textContent = 'Capacity: 11 oz.';
+
+ list.insertBefore(newList, item5);
+
+ // ======================
+
+ const prodSpecEl = $('#product_specification');
+ const prodSpecLiEls = $$('#product_specification li');
+
+ // einzufügenden Listenpunkt erstellen
+ const liCapacity = document.createElement('li');
+ liCapacity.textContent = 'Capacity: 11 oz.';
+
+ // Nu suchen an welcher Stelle - also den listenpunkt mit dem text Materials: Ceramic
+ const refLi = prodSpecLiEls.find((el) => {
+ return el.textContent === 'Materials: Ceramic';
+ });
+
+ // und einfügen
+ prodSpecEl.insertBefore(liCapacity, refLi);
}
diff --git a/03_dom/unterricht/tag25/01_product-manager/assets/js/main.js b/03_dom/unterricht/tag25/01_product-manager/assets/js/main.js
index ab8e54b..e43a210 100644
--- a/03_dom/unterricht/tag25/01_product-manager/assets/js/main.js
+++ b/03_dom/unterricht/tag25/01_product-manager/assets/js/main.js
@@ -41,7 +41,7 @@
const onClickRemove = (e) => {
const btnEl = e.currentTarget;
- const currentRowEl = btnEl.parentNode.parentNode;
+ const currentRowEl = btnEl.parentNode.parentNode; // parentNode -> td - parentNode -> tr
currentRowEl.remove(); // kein IE11 support
// DOM.tBody.removeChild(currentRowEl);
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/.gitignore b/03_dom/unterricht/tag26/01_product-manager-final/.gitignore
new file mode 100644
index 0000000..4073eac
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/.gitignore
@@ -0,0 +1,11 @@
+node_modules/
+dist/
+.env
+.env.local
+.env.*.local
+.DS_Store
+*.log
+.vite/
+coverage/
+.idea/
+# .vscode/
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/assets/css/main.css b/03_dom/unterricht/tag26/01_product-manager-final/assets/css/main.css
new file mode 100644
index 0000000..1a93676
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/assets/css/main.css
@@ -0,0 +1,34 @@
+*,
+html {
+ box-sizing: border-box;
+}
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+}
+
+body {
+ background-color: #efefef;
+}
+
+/* Mobile first */
+.product-manager table tfoot .row > * {
+ margin-bottom: 1rem;
+}
+
+@media (min-width: 992px) {
+ .product-manager table tfoot .row > * {
+ margin-bottom: 0;
+ }
+}
+
+.product-manager table .th-actions {
+ width: 150px;
+}
+
+.product-manager table tbody td button {
+ margin: 3px;
+}
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/assets/js/main.js b/03_dom/unterricht/tag26/01_product-manager-final/assets/js/main.js
new file mode 100644
index 0000000..e43a210
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/assets/js/main.js
@@ -0,0 +1,181 @@
+'use strict';
+
+(() => {
+ // === DOM & VARS =======
+
+ const module = document.querySelector('.product-manager') || console.error('Product Manager not found');
+
+ if (!module) return;
+
+ const DOM = {
+ module,
+ 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; // parentNode -> td - parentNode -> tr
+
+ 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();
+})();
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/data/products.js b/03_dom/unterricht/tag26/01_product-manager-final/data/products.js
new file mode 100644
index 0000000..940c04c
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/data/products.js
@@ -0,0 +1,7 @@
+// Konfigurationsvariable
+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 },
+];
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/data/products.json b/03_dom/unterricht/tag26/01_product-manager-final/data/products.json
new file mode 100644
index 0000000..67e8369
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/data/products.json
@@ -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 }
+]
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/index.html b/03_dom/unterricht/tag26/01_product-manager-final/index.html
new file mode 100644
index 0000000..a10c3ad
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/index.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+ Product Manager
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | Name |
+ Price in € |
+ Actions |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
diff --git a/03_dom/unterricht/tag26/01_product-manager-final/package.json b/03_dom/unterricht/tag26/01_product-manager-final/package.json
new file mode 100644
index 0000000..26b0799
--- /dev/null
+++ b/03_dom/unterricht/tag26/01_product-manager-final/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "01_product-manager",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "type": "module"
+}