This commit is contained in:
@@ -420,11 +420,10 @@ Projektarbeit
|
||||
- **Rest API erstellen mit Express**
|
||||
- JS DOM Projektvorstellung
|
||||
- Abschlussquiz JS DOM
|
||||
- **Routing in JS**
|
||||
|
||||
**Übungen:**
|
||||
|
||||
Projekte + optionale Übungen.
|
||||
Projekte
|
||||
|
||||
---
|
||||
|
||||
@@ -433,6 +432,7 @@ Projekte + optionale Übungen.
|
||||
**Inhalt:**
|
||||
|
||||
- **Exkurs: DOM Inhalte über REST API mit Express Part I**
|
||||
- **Routing in JS**
|
||||
- CRUD - Create - Read - Update - Delete
|
||||
- Object Methoden.
|
||||
- Verwendung von Modulen (Bootstrap)
|
||||
|
||||
@@ -106,3 +106,7 @@
|
||||
## JS Plugins
|
||||
|
||||
- [Floating UI](https://floating-ui.com/)
|
||||
|
||||
## KI Tools
|
||||
|
||||
- [AI Models](https://artificialanalysis.ai/models)
|
||||
|
||||
@@ -2,16 +2,54 @@
|
||||
|
||||
(() => {
|
||||
// === DOM & VARS =======
|
||||
const DOM = {};
|
||||
const module = document.querySelector('.m-cutey-cat') || console.error('Element: ".m-cutey-cat" not found');
|
||||
|
||||
if (!module) return;
|
||||
|
||||
const DOM = {
|
||||
listItemsCatVote: Array.from(module.querySelectorAll('.list-cat-vote li')),
|
||||
listCatSelection: module.querySelector('.list-cat-selection'),
|
||||
};
|
||||
|
||||
// console.log(module);
|
||||
// console.log('listItemsCatVote: ', DOM.listItemsCatVote);
|
||||
// console.log('listCatSelection', DOM.listCatSelection);
|
||||
|
||||
// === INIT =============
|
||||
const init = () => {};
|
||||
const init = () => {
|
||||
// Eventhandler für die vorhandenen Katzen
|
||||
DOM.listItemsCatVote.forEach((el) => {
|
||||
el.addEventListener('click', onClickCatVoteAdd);
|
||||
});
|
||||
};
|
||||
|
||||
// === EVENTHANDLER =====
|
||||
const onClickCatVoteAdd = (e) => {
|
||||
const selCat = e.currentTarget.cloneNode(true);
|
||||
const altSelCat = selCat.querySelector('img').alt;
|
||||
|
||||
//console.log(DOM.listCatSelection.childElementCount);
|
||||
// Guard
|
||||
if (isCastInSelection(altSelCat) || DOM.listCatSelection.childElementCount === 3) return;
|
||||
|
||||
// if (!isCastInSelection(altSelCat) && DOM.listCatSelection.childElementCount < 3) {
|
||||
selCat.addEventListener('click', onClickCatSelRemove);
|
||||
DOM.listCatSelection.appendChild(selCat);
|
||||
// }
|
||||
};
|
||||
|
||||
const onClickCatSelRemove = (e) => {
|
||||
e.currentTarget.remove();
|
||||
};
|
||||
|
||||
// === XHR/FETCH ========
|
||||
|
||||
// === FUNCTIONS ========
|
||||
const isCastInSelection = (alt) => {
|
||||
const votedCats = Array.from(DOM.listCatSelection.querySelectorAll('li img'));
|
||||
|
||||
return votedCats.some((el) => alt === el.alt);
|
||||
};
|
||||
|
||||
init();
|
||||
})();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
|
||||
@@ -88,158 +88,6 @@
|
||||
</template>
|
||||
</div>
|
||||
<!-- ▲ /product-manager ▲ -->
|
||||
<!-- ▼ product-manager ▼ -->
|
||||
<div class="product-manager my-5">
|
||||
<div class="container">
|
||||
<!-- table.table.table-striped.table-products>(thead.table-dark>tr>th{Name}+th{Price in €})+tbody>tr>td*2 -->
|
||||
<table class="table table-striped table-products">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th class="th-name">Name</th>
|
||||
<th class="th-price">Price in €</th>
|
||||
<th class="th-actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control input-product-name"
|
||||
name="product-name"
|
||||
placeholder="Insert product name"
|
||||
aria-label="Product Name" />
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="product-price"
|
||||
class="form-control input-product-price"
|
||||
placeholder="00.00"
|
||||
aria-label="Product Price"
|
||||
step="0.01"
|
||||
min="0" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6 col-lg">
|
||||
<button class="btn btn-dark button-product-add">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add product
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /row ▲ -->
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<template class="template-row">
|
||||
<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>
|
||||
</template>
|
||||
</div>
|
||||
<!-- ▲ /product-manager ▲ -->
|
||||
<!-- ▼ product-manager ▼ -->
|
||||
<div class="product-manager my-5">
|
||||
<div class="container">
|
||||
<!-- table.table.table-striped.table-products>(thead.table-dark>tr>th{Name}+th{Price in €})+tbody>tr>td*2 -->
|
||||
<table class="table table-striped table-products">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th class="th-name">Name</th>
|
||||
<th class="th-price">Price in €</th>
|
||||
<th class="th-actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control input-product-name"
|
||||
name="product-name"
|
||||
placeholder="Insert product name"
|
||||
aria-label="Product Name" />
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6 col-lg-3">
|
||||
<div class="input-group">
|
||||
<input
|
||||
type="number"
|
||||
name="product-price"
|
||||
class="form-control input-product-price"
|
||||
placeholder="00.00"
|
||||
aria-label="Product Price"
|
||||
step="0.01"
|
||||
min="0" />
|
||||
<span class="input-group-text">€</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6 col-lg">
|
||||
<button class="btn btn-dark button-product-add">
|
||||
<i class="fas fa-plus"></i>
|
||||
Add product
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ▲ /row ▲ -->
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<template class="template-row">
|
||||
<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>
|
||||
</template>
|
||||
</div>
|
||||
<!-- ▲ /product-manager ▲ -->
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
99
03_dom/unterricht/tag27/01_drag-drop/index.html
Normal file
99
03_dom/unterricht/tag27/01_drag-drop/index.html
Normal file
@@ -0,0 +1,99 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Drag 'n Drop Example</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
.box {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: tomato;
|
||||
border: 10px solid #222;
|
||||
}
|
||||
|
||||
.target-box {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 1rem;
|
||||
left: 50%;
|
||||
margin: 0 0 0 -100px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: orange;
|
||||
border: 10px solid #222;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="container py-5">
|
||||
<h1>Drag 'n Drop Example</h1>
|
||||
<hr />
|
||||
<div class="box" id="source-box"></div>
|
||||
<div class="target-box"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
const box = document.querySelector('.box');
|
||||
const targetBox = document.querySelector('.target-box');
|
||||
|
||||
// MouseEvent - mousedown & mouseup
|
||||
box.addEventListener('mousedown', (e) => {
|
||||
console.log('MouseEvent:', e);
|
||||
const el = e.currentTarget;
|
||||
el.draggable = true; // => <div class="box" draggable="true">...</div>
|
||||
});
|
||||
|
||||
box.addEventListener('mouseup', (e) => {
|
||||
console.log('MouseEvent:', e);
|
||||
const el = e.currentTarget;
|
||||
el.draggable = false; // => <div class="box" draggable="false">...</div>
|
||||
});
|
||||
|
||||
// DragEvent
|
||||
box.addEventListener('dragstart', (e) => {
|
||||
console.log('DragEvent:', e);
|
||||
console.log('DRAG START');
|
||||
const sourceEl = e.currentTarget;
|
||||
const idx = [...sourceEl.parentNode.children].indexOf(sourceEl); // Trick um schnell den Index (die Position) eines Elementes herauszufinden
|
||||
const className = sourceEl.classList.value; // "box"
|
||||
const id = sourceEl.id;
|
||||
|
||||
console.log({ idx, className, id });
|
||||
|
||||
e.dataTransfer.setData('application/json', JSON.stringify({ idx, className, id }));
|
||||
});
|
||||
|
||||
// NOTWENDIG
|
||||
targetBox.addEventListener('dragover', (e) => {
|
||||
// console.log('DragEvent:', e);
|
||||
e.preventDefault(); // Standardverhalten unterbinden. Notwendig, damit "drop"-Event greift
|
||||
});
|
||||
|
||||
targetBox.addEventListener('drop', (e) => {
|
||||
console.log('DragEvent:', e);
|
||||
console.log('DROP');
|
||||
const { idx, className, id } = JSON.parse(e.dataTransfer.getData('application/json'));
|
||||
|
||||
const sourceEl = document.querySelector('.box');
|
||||
const newIdx = [...sourceEl.parentNode.children].indexOf(sourceEl);
|
||||
|
||||
console.log({ idx, className, newIdx, id });
|
||||
document.querySelector(`.${className}`).style.backgroundColor = 'limegreen';
|
||||
// document.querySelector(`.container > *:nth-child(${idx})`).style.width = `${targetBox.offsetWidth}px`;
|
||||
document.querySelector(`.${className}`).style.width = `${targetBox.offsetWidth}px`;
|
||||
document.getElementById(id).style.height = `${targetBox.offsetHeight}px`;
|
||||
|
||||
document.querySelector(`.${className}`).style.top = `${targetBox.getBoundingClientRect().top}px`;
|
||||
document.querySelector(`.${className}`).style.left = `${targetBox.getBoundingClientRect().left}px`;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
03_dom/unterricht/tag27/02_README.md
Normal file
1
03_dom/unterricht/tag27/02_README.md
Normal file
@@ -0,0 +1 @@
|
||||
# ProductManager in Webseite integrieren und erweitern (CRUD)
|
||||
Reference in New Issue
Block a user