This commit is contained in:
24
03_dom/unterricht/tag29/o03_website-with-plugins/README.md
Normal file
24
03_dom/unterricht/tag29/o03_website-with-plugins/README.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Optionale Übungen
|
||||||
|
|
||||||
|
## 1. Integration eines weiteren Moduls
|
||||||
|
|
||||||
|
- Intergriere ein weiteres Modul deiner Wahl in die Webseite. (Splide, GlideJS, photoswipe, tiny-slider)
|
||||||
|
|
||||||
|
## 2. Tooltip als Modul verwenden
|
||||||
|
|
||||||
|
Intergriere das Plugin [`popper.js`](https://popper.js.org/docs/v2/) oder die neuere Version [`floating-ui`](https://floating-ui.com/)
|
||||||
|
in die Webseite.
|
||||||
|
|
||||||
|
## 3. Formularvalidierung als Modul
|
||||||
|
|
||||||
|
Erstelle ein Modul für die Validierung von einem Formular (`FormValidator`) mit folgenden Feldern
|
||||||
|
|
||||||
|
- Vor- und Nachname
|
||||||
|
- E-Mail
|
||||||
|
- Adresse bestehend aus:
|
||||||
|
- Strasse, Hausnummer
|
||||||
|
- PLZ, Ort
|
||||||
|
- Land
|
||||||
|
- Nachricht
|
||||||
|
|
||||||
|
Die Validierung soll direkt während (`input`) oder nach der Eingabe (`blur`) der Felder stattfinden. Die Verwendung von Validierungsmodulen wie `validator` dürfen dabei verwenden werden.
|
||||||
@@ -53,6 +53,7 @@ const ProductModel = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const update = (product) => {
|
const update = (product) => {
|
||||||
|
console.log(product);
|
||||||
const foundIdx = products.findIndex((obj) => {
|
const foundIdx = products.findIndex((obj) => {
|
||||||
return obj._id === product._id;
|
return obj._id === product._id;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ app.post('/api/products', (req, res) => {
|
|||||||
return res.status(400).send({ msg: 'Could not add product', status: 400, success: false });
|
return res.status(400).send({ msg: 'Could not add product', status: 400, success: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send({ msg: 'Product added', status: 200, success: true, data: product });
|
return res.send({ msg: 'Product added', status: 200, success: true, data: product });
|
||||||
});
|
});
|
||||||
|
|
||||||
// HTTP - Methode - GET
|
// HTTP - Methode - GET
|
||||||
@@ -69,7 +69,7 @@ app.post('/api/products', (req, res) => {
|
|||||||
// (B)READ - browse
|
// (B)READ - browse
|
||||||
app.get('/api/products', (req, res) => {
|
app.get('/api/products', (req, res) => {
|
||||||
const data = products.getAll();
|
const data = products.getAll();
|
||||||
res.send(data);
|
return res.send(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
// HTTP - Methode - GET
|
// HTTP - Methode - GET
|
||||||
@@ -83,7 +83,7 @@ app.get('/api/products/:id', (req, res) => {
|
|||||||
return res.status(400).send({ msg: 'Could not get product', status: 400, success: false });
|
return res.status(400).send({ msg: 'Could not get product', status: 400, success: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send(product);
|
return res.send(product);
|
||||||
});
|
});
|
||||||
|
|
||||||
// HTTP - Methode - PUT/PATCH
|
// HTTP - Methode - PUT/PATCH
|
||||||
@@ -98,7 +98,7 @@ app.put('/api/products', (req, res) => {
|
|||||||
return res.status(400).send({ msg: 'Could not update product', status: 400, success: false });
|
return res.status(400).send({ msg: 'Could not update product', status: 400, success: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send({ msg: 'Product updated', status: 200, success: true, data: product });
|
return res.send({ msg: 'Product updated', status: 200, success: true, data: product });
|
||||||
});
|
});
|
||||||
|
|
||||||
// HTTP - Methode - DELETE
|
// HTTP - Methode - DELETE
|
||||||
@@ -111,7 +111,7 @@ app.delete('/api/products/:id', (req, res) => {
|
|||||||
return res.status(400).send({ msg: 'Could not delete product', status: 400, success: false });
|
return res.status(400).send({ msg: 'Could not delete product', status: 400, success: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send({ msg: 'Product deleted', status: 200, success: true, data: id });
|
return res.send({ msg: 'Product deleted', status: 200, success: true, data: id });
|
||||||
});
|
});
|
||||||
|
|
||||||
// =========
|
// =========
|
||||||
|
|||||||
@@ -5179,6 +5179,7 @@
|
|||||||
templateRow: module.querySelector(".template-row"),
|
templateRow: module.querySelector(".template-row"),
|
||||||
// Modal
|
// Modal
|
||||||
modalEdit: module.querySelector(".modal-edit"),
|
modalEdit: module.querySelector(".modal-edit"),
|
||||||
|
formEdit: module.querySelector(".form-product-edit"),
|
||||||
inputEditName: module.querySelector(".input-edit-name"),
|
inputEditName: module.querySelector(".input-edit-name"),
|
||||||
inputEditPrice: module.querySelector(".input-edit-price"),
|
inputEditPrice: module.querySelector(".input-edit-price"),
|
||||||
inputEditId: module.querySelector(".input-edit-id"),
|
inputEditId: module.querySelector(".input-edit-id"),
|
||||||
@@ -5194,6 +5195,23 @@
|
|||||||
console.log("init");
|
console.log("init");
|
||||||
initProducts();
|
initProducts();
|
||||||
DOM.btnAdd.addEventListener("click", onClickAdd);
|
DOM.btnAdd.addEventListener("click", onClickAdd);
|
||||||
|
DOM.formEdit.addEventListener("submit", onSubmitEdit);
|
||||||
|
};
|
||||||
|
const onSubmitEdit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const product = {
|
||||||
|
name: DOM.inputEditName.value,
|
||||||
|
price: Number(DOM.inputEditPrice.value),
|
||||||
|
_id: DOM.inputEditId.value,
|
||||||
|
position: DOM.inputEditPosition.value
|
||||||
|
};
|
||||||
|
updateProduct(product).then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.success) {
|
||||||
|
loadProducts();
|
||||||
|
bsModalEdit.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const onClickAdd = (e) => {
|
const onClickAdd = (e) => {
|
||||||
console.log("click");
|
console.log("click");
|
||||||
@@ -5201,7 +5219,13 @@
|
|||||||
name: DOM.inputName.value,
|
name: DOM.inputName.value,
|
||||||
price: Number(DOM.inputPrice.value)
|
price: Number(DOM.inputPrice.value)
|
||||||
};
|
};
|
||||||
addProduct(product);
|
createProduct(product).then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.success) {
|
||||||
|
console.log("add");
|
||||||
|
loadProducts();
|
||||||
|
}
|
||||||
|
});
|
||||||
disableNonFunctionalButtons();
|
disableNonFunctionalButtons();
|
||||||
};
|
};
|
||||||
const onClickEdit = (e) => {
|
const onClickEdit = (e) => {
|
||||||
@@ -5268,7 +5292,26 @@
|
|||||||
}
|
}
|
||||||
disableNonFunctionalButtons();
|
disableNonFunctionalButtons();
|
||||||
};
|
};
|
||||||
const fetchProducts = async () => {
|
const createProduct = async (product) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${BASE_URL}/api/products`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(product)
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Fetch went wrong.");
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const getProducts = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${BASE_URL}/api/products`);
|
const response = await fetch(`${BASE_URL}/api/products`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -5294,14 +5337,42 @@
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const updateProduct = async (product) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${BASE_URL}/api/products`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(product)
|
||||||
|
});
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Fetch went wrong.");
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
const initProducts = () => {
|
const initProducts = () => {
|
||||||
fetchProducts().then((products) => {
|
getProducts().then((products) => {
|
||||||
products.forEach((product) => {
|
products.forEach((product) => {
|
||||||
addProduct(product);
|
addProduct(product);
|
||||||
});
|
});
|
||||||
disableNonFunctionalButtons();
|
disableNonFunctionalButtons();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
const loadProducts = () => {
|
||||||
|
DOM.tBody.innerHTML = "";
|
||||||
|
getProducts().then((data) => {
|
||||||
|
data.forEach((product) => {
|
||||||
|
addProduct(product);
|
||||||
|
});
|
||||||
|
disableNonFunctionalButtons();
|
||||||
|
});
|
||||||
|
};
|
||||||
const addProduct = (product) => {
|
const addProduct = (product) => {
|
||||||
const { name, price, _id: id, position } = product;
|
const { name, price, _id: id, position } = product;
|
||||||
const trEl = DOM.templateRow.content.firstElementChild.cloneNode(true);
|
const trEl = DOM.templateRow.content.firstElementChild.cloneNode(true);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -24,6 +24,7 @@ const ProductManager = (el = null) => {
|
|||||||
|
|
||||||
// Modal
|
// Modal
|
||||||
modalEdit: module.querySelector('.modal-edit'),
|
modalEdit: module.querySelector('.modal-edit'),
|
||||||
|
formEdit: module.querySelector('.form-product-edit'),
|
||||||
inputEditName: module.querySelector('.input-edit-name'),
|
inputEditName: module.querySelector('.input-edit-name'),
|
||||||
inputEditPrice: module.querySelector('.input-edit-price'),
|
inputEditPrice: module.querySelector('.input-edit-price'),
|
||||||
inputEditId: module.querySelector('.input-edit-id'),
|
inputEditId: module.querySelector('.input-edit-id'),
|
||||||
@@ -45,9 +46,30 @@ const ProductManager = (el = null) => {
|
|||||||
|
|
||||||
// Event-Lauscher zu beginn der Anwendung
|
// Event-Lauscher zu beginn der Anwendung
|
||||||
DOM.btnAdd.addEventListener('click', onClickAdd);
|
DOM.btnAdd.addEventListener('click', onClickAdd);
|
||||||
|
DOM.formEdit.addEventListener('submit', onSubmitEdit);
|
||||||
};
|
};
|
||||||
|
|
||||||
// === EVENTHANDLER =====
|
// === EVENTHANDLER =====
|
||||||
|
const onSubmitEdit = (e) => {
|
||||||
|
e.preventDefault(); // Standardverhalten unterbinden (Formular nicht an action versenden)
|
||||||
|
|
||||||
|
const product = {
|
||||||
|
name: DOM.inputEditName.value,
|
||||||
|
price: Number(DOM.inputEditPrice.value),
|
||||||
|
_id: DOM.inputEditId.value,
|
||||||
|
position: DOM.inputEditPosition.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
// update async process
|
||||||
|
updateProduct(product).then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.success) {
|
||||||
|
loadProducts(); // All Produkte auslesen
|
||||||
|
bsModalEdit.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const onClickAdd = (e) => {
|
const onClickAdd = (e) => {
|
||||||
console.log('click');
|
console.log('click');
|
||||||
|
|
||||||
@@ -56,7 +78,15 @@ const ProductManager = (el = null) => {
|
|||||||
price: Number(DOM.inputPrice.value),
|
price: Number(DOM.inputPrice.value),
|
||||||
};
|
};
|
||||||
|
|
||||||
addProduct(product);
|
createProduct(product).then((data) => {
|
||||||
|
console.log(data);
|
||||||
|
if (data.success) {
|
||||||
|
console.log('add');
|
||||||
|
loadProducts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// addProduct(product);
|
||||||
|
|
||||||
disableNonFunctionalButtons();
|
disableNonFunctionalButtons();
|
||||||
};
|
};
|
||||||
@@ -171,10 +201,34 @@ const ProductManager = (el = null) => {
|
|||||||
|
|
||||||
// === XHR/FETCH ========
|
// === XHR/FETCH ========
|
||||||
|
|
||||||
|
// HTTP - Methode - POST
|
||||||
|
// (C)RUD - create
|
||||||
|
// BRE(A)D - add - neues Produkt hinzufügen
|
||||||
|
const createProduct = async (product) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${BASE_URL}/api/products`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(product),
|
||||||
|
}); // HTTP Request URL
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Fetch went wrong.');
|
||||||
|
}
|
||||||
|
const data = await response.json(); // HTTP-Response
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// HTTP - Methode - GET
|
// HTTP - Methode - GET
|
||||||
// C(R)UD - Read
|
// C(R)UD - Read
|
||||||
// (B)READ - Browse - auslesen aller Produkte
|
// (B)READ - Browse - auslesen aller Produkte
|
||||||
const fetchProducts = async () => {
|
const getProducts = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${BASE_URL}/api/products`); // HTTP Request URL
|
const response = await fetch(`${BASE_URL}/api/products`); // HTTP Request URL
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -207,10 +261,34 @@ const ProductManager = (el = null) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// HTTP - Methode - PUT
|
||||||
|
// CR(U)D - update
|
||||||
|
// BR(E)AD - edit - Produkt aktualisieren
|
||||||
|
const updateProduct = async (product) => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${BASE_URL}/api/products`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(product),
|
||||||
|
}); // HTTP Request URL
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Fetch went wrong.');
|
||||||
|
}
|
||||||
|
const data = await response.json(); // HTTP-Response
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// === FUNCTIONS ========
|
// === FUNCTIONS ========
|
||||||
|
|
||||||
const initProducts = () => {
|
const initProducts = () => {
|
||||||
fetchProducts().then((products) => {
|
getProducts().then((products) => {
|
||||||
products.forEach((product) => {
|
products.forEach((product) => {
|
||||||
addProduct(product);
|
addProduct(product);
|
||||||
});
|
});
|
||||||
@@ -224,6 +302,16 @@ const ProductManager = (el = null) => {
|
|||||||
// PRODUCTS.forEach(addProduct);
|
// PRODUCTS.forEach(addProduct);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadProducts = () => {
|
||||||
|
DOM.tBody.innerHTML = '';
|
||||||
|
getProducts().then((data) => {
|
||||||
|
data.forEach((product) => {
|
||||||
|
addProduct(product);
|
||||||
|
});
|
||||||
|
disableNonFunctionalButtons();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const addProduct = (product) => {
|
const addProduct = (product) => {
|
||||||
const { name, price, _id: id, position } = product;
|
const { name, price, _id: id, position } = product;
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,8 @@
|
|||||||
type="number"
|
type="number"
|
||||||
name="price"
|
name="price"
|
||||||
id="input-edit-price"
|
id="input-edit-price"
|
||||||
|
min="0"
|
||||||
|
step="0.01"
|
||||||
class="form-control input-edit-price" />
|
class="form-control input-edit-price" />
|
||||||
<span class="input-group-text">€</span>
|
<span class="input-group-text">€</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user