лаба3

This commit is contained in:
a.puchkina 2023-12-08 15:57:31 +04:00
parent 900f12a227
commit 84dcce8921
9 changed files with 366 additions and 217 deletions

View File

@ -32,44 +32,145 @@
</a>
</nav>
</header>
<script type="module">
import validation from "./js/validation";
import { linesFormOnIndex } from "./js/lines";
import { linesForm } from "./js/lines";
document.addEventListener("DOMContentLoaded", () => {
validation();
linesFormOnIndex();
linesForm();
});
</script>
<catalog>
<p class="title">КАТАЛОГ</p>
<div class="text-center">
<p class="text-catalog">Столы</p>
<a href="products/productTable1.html"
><img src="images/table1.png" class="rounded" alt="..."
/></a>
<a href="products/productTable2.html"
><img src="images/table2.png" class="rounded" alt="..." />
</a>
<a href="products/productTable3.html"
><img src="images/table3.png" class="rounded" alt="..."
/></a>
</div>
<div class="text-center">
<p class="text-catalog">Стулья</p>
<a href="products/productChair1.html"
><img src="images/chair1.png" class="rounded" alt="..."
/></a>
<a href="products/productChair2.html"
><img src="images/chair2.png" class="rounded" alt="..." />
</a>
<a href="products/productChair3.html"
><img src="images/chair3.png" class="rounded" alt="..."
/></a>
</div>
<div class="text-center">
<p class="text-catalog">Диваны</p>
<a href="products/productSofa1.html"
><img src="images/sofa1.png" class="rounded" alt="..."
/></a>
<a href="products/productSofa2.html"
><img src="images/sofa2.png" class="rounded" alt="..." />
</a>
<a href="products/productSofa3.html"
><img src="images/sofa3.png" class="rounded" alt="..."
/></a>
<div class="container-catalog">
<div id="my-id-for-text" class="container table"></div>
</div>
</catalog>
<div
id="items-update"
class="modal fade"
tabindex="-1"
data-bs-backdrop="static"
data-bs-keyboard="false"
>
<div class="modal-dialog modal-dialog-scrollable">
<form id="items-form" class="needs-validation" novalidate>
<div class="modal-content">
<div class="modal-header fixed-header">
<h1 class="modal-title fs-5" id="items-update-title"></h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<div class="text-center">
<img
id="image-preview"
src="https://via.placeholder.com/200"
class="rounded rounded-circle"
alt="placeholder"
/>
</div>
<input id="items-line-id" type="number" hidden />
<div class="mb-2">
<label for="item" class="form-label">Категория</label>
<select
id="item"
class="form-select"
name="selected"
required
></select>
</div>
<div class="mb-2">
<label class="form-label" for="description">Название</label>
<input
id="name"
name="name"
class="form-control"
type="text"
maxlength="100"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="price">Цена</label>
<input
id="price"
name="price"
class="form-control"
type="number"
value="0"
min="1000"
step="100"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="count">Количество</label>
<input
id="count"
name="count"
class="form-control"
type="number"
value="0"
min="1"
step="1"
required
/>
<div class="mb-2">
<label class="form-label" for="color">Цвет</label>
<input
id="color"
name="color"
class="form-control"
type="color"
maxlength="100"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="size">Размеры</label>
<input
id="size"
name="size"
class="form-control"
type="text"
maxlength="100"
required
/>
</div>
</div>
<div class="mb-2">
<label class="form-label" for="image">Изображение</label>
<input
id="image"
type="file"
name="image"
class="form-control"
accept="image/*"
/>
</div>
</div>
<div class="modal-footer fixed-footer">
<button
type="submit-grey"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Закрыть
</button>
<button type="submit" class="btn btn-success">Сохранить</button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>

View File

@ -267,10 +267,6 @@ orders .container-products {
right: 0;
margin-bottom: 3%;
}
.container-products img {
width: 30%;
padding: 2%;
}
cart .card,
orders .card {
background-color: rgba(191, 180, 161, 1);
@ -426,3 +422,15 @@ add .container {
#image-preview {
width: 200px;
}
.container-catalog {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
flex-direction: column;
}
.container-catalog {
margin-left: 15%;
margin-right: 15%;
}

File diff suppressed because one or more lines are too long

View File

@ -50,7 +50,6 @@ export function showUpdateModal(item) {
} else {
resetValues();
}
myModal.show();
}

View File

@ -110,7 +110,8 @@ export async function updateLine(
if (!response.ok) {
throw response.statusText;
}
return response.json();
await response.json();
location.reload();
}
// обращение к серверу для удаления записи по id (delete)
@ -124,5 +125,6 @@ export async function deleteLine(id) {
if (!response.ok) {
throw response.statusText;
}
return response.json();
await response.json();
location.reload();
}

View File

@ -4,6 +4,7 @@
// при обращении к атрибуту объекта вызывается
// нужная функция для поиска элемента
export const cntrls = {
container: document.getElementById("my-id-for-text"),
button: document.getElementById("items-add"),
table: document.querySelector("#items-table tbody"),
form: document.getElementById("items-form"),
@ -98,9 +99,78 @@ export function createTableRow(
row.appendChild(createTableColumn(parseFloat(item.sum).toFixed(2)));
// редактировать в модальном окне
row.appendChild(createTableAnchor("fa-pencil", editCallback));
// редактировать на странице page-edit
row.appendChild(createTableAnchor("fa-pen-to-square", editPageCallback));
// удаление
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
return row;
}
export function createTableRowOnIndex(
item,
index,
editCallback,
editPageCallback,
deleteCallback
) {
console.log(item);
const img = document.createElement("img");
img.classList.add("objects");
img.src = item.image;
img.alt = "object";
img.style.height = "300px";
img.style.display = "block";
img.style.marginLeft = "auto";
img.style.marginRight = "auto";
const name = document.createElement("div");
name.classList.add("caption");
name.innerText = item.name;
name.style.padding = "0px";
name.style.fontSize = "22px";
name.style.color = "#533908";
name.style.fontFamily = "Montserrat Alternates";
name.style.fontWeight = 500;
const price = document.createElement("div");
price.classList.add("caption_2");
price.innerText = parseInt(item.price) + "₽";
price.style.padding = "0";
price.style.marginBottom = "40px";
price.style.fontSize = "28px";
price.style.color = "#533908";
price.style.fontFamily = "Montserrat Alternates";
price.style.fontWeight = 400;
const a = document.createElement("a");
a.href = "products/productTable1.html";
a.style.textDecoration = "none";
a.appendChild(img);
a.appendChild(name);
a.appendChild(price);
const buttonsContainer = document.createElement("div");
buttonsContainer.style.display = "flex";
buttonsContainer.style.justifyContent = "center";
const editButton = createTableAnchor("fa-pencil", editCallback);
const deleteButton = createTableAnchor("fa-trash", deleteCallback);
deleteButton.style.marginLeft = "1.2vw";
buttonsContainer.appendChild(editButton);
buttonsContainer.appendChild(deleteButton);
buttonsContainer.style.marginTop = "-40px";
buttonsContainer.style.marginBottom = "40px";
a.appendChild(buttonsContainer);
const div = document.createElement("div");
div.classList.add("col");
div.classList.add("clear-float");
div.appendChild(a);
const uniqueId = `div-${index + 1}`;
div.id = uniqueId;
div.style.float = "left";
div.style.boxSizing = "border-box";
return div;
}

View File

@ -13,6 +13,7 @@ import {
cntrls,
createItemsOption,
createTableRow,
createTableRowOnIndex,
imagePlaceholder,
} from "./lines-ui";
@ -22,8 +23,8 @@ async function drawItemsSelect() {
// очистка содержимого select
// удаляется все, что находится между тегами <select></select>
// но не атрибуты
if (cntrls.itemsType) {
cntrls.itemsType.innerHTML = "";
// пустое значение
cntrls.itemsType.appendChild(
createItemsOption("Выберите значение", "", true)
);
@ -34,6 +35,7 @@ async function drawItemsSelect() {
cntrls.itemsType.appendChild(createItemsOption(item.name, item.id));
});
}
}
async function drawLinesTable() {
console.info("Try to load data");
@ -64,7 +66,35 @@ async function drawLinesTable() {
);
});
}
async function drawLinesTableOnIndex() {
console.info("Try to load data On Index");
if (!cntrls.container) {
return;
}
// вызов метода REST API для получения всех записей
const data = await getAllLines();
// очистка содержимого table
// удаляется все, что находится между тегами <table></table>
// но не атрибуты
cntrls.container.innerHTML = "";
// цикл по результату ответа от сервера
// используется лямбда-выражение
// (item, index) => {} аналогично function(item, index) {}
data.forEach((item, index) => {
cntrls.container.appendChild(
createTableRowOnIndex(
item,
index,
// функции передаются в качестве параметра
// это очень удобно, так как аргументы функций доступны только
// в данном месте кода и не передаются в сервисные модули
() => showUpdateModal(item),
() => location.assign(`catalog.html?id=${item.id}`),
() => removeLine(item.id)
)
);
});
}
async function addLine(item, name, price, count, color, size, image) {
console.info("Try to add item");
// вызов метода REST API для добавления записи
@ -231,7 +261,76 @@ export function linesForm() {
hideUpdateModal();
});
}
export async function linesFormOnIndex() {
console.info("linesFormOnIndex");
await drawItemsSelect();
await drawLinesTableOnIndex();
// обработчик события отправки формы
// возникает при нажатии на кнопку (button) с типом submit
// кнопка должна находится внутри тега form
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
// Получение выбранного пользователем изображения в виде base64 строки
// Если пользователь ничего не выбрал, то не нужно сохранять в БД
// дефолтное изображение
if (cntrls.imagePreview.src !== imagePlaceholder) {
// Загрузка содержимого атрибута src тэга img с id image-preview
// Здесь выполняется HTTP запрос с типом GET
const result = await fetch(cntrls.imagePreview.src);
// Получение из HTTP-ответа бинарного содержимого
const blob = await result.blob();
// Получение base64 строки для файла
// Здесь выполняется Promise из функции readFile
// Promise позволяет писать линейный код для работы с асинхронными методами
// без использования обработчиков (callback) с помощью await
imageBase64 = await readFile(blob);
}
// получение id строки для редактирования
// это значение содержится в скрытом input
const currentId = cntrls.lineId.value;
// если значение id не задано,
// то необходимо выполнить добавление записи
// иначе обновление записи
if (!currentId) {
await addLine(
cntrls.itemsType.value,
cntrls.name.value,
cntrls.price.value,
cntrls.count.value,
cntrls.color.value,
cntrls.size.value,
imageBase64
);
} else {
await editLine(
currentId,
cntrls.itemsType.value,
cntrls.name.value,
cntrls.price.value,
cntrls.count.value,
cntrls.color.value,
cntrls.size.value,
imageBase64
);
}
// после выполнения добавления/обновления модальное окно скрывается
hideUpdateModal();
});
}
// Функция для обработки создания и редактирования элементов таблицы через страницу page-edit.html
// Если хотите делать через модальное окно, то удалите эту функцию
export async function linesPageForm() {

View File

@ -1,138 +0,0 @@
<html lang="ru">
<head>
<meta charset="utf-8" />
<title>Добавить товар</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script
type="module"
src="./node_modules/bootstrap/dist/js/bootstrap.min.js"
></script>
<link
href="./node_modules/bootstrap/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<link
href="./node_modules/@fortawesome/fontawesome-free/css/all.min.css"
rel="stylesheet"
/>
<link rel="stylesheet" href="./css/style.css" />
</head>
<body class="h-100 d-flex flex-column">
<header>
<a class="navbar-brand p-0" href="catalog.html">
<img src="images/iconCatalog.png" alt="Каталог" width="45" />
</a>
<a class="nav-link active" aria-current="page" href="index.html">ANNA</a>
<nav>
<a class="navbar-brand p-0" href="cart.html">
<img src="images/iconsCor.png" alt="Корзина" width="37" />
</a>
<a class="navbar-brand p-0" href="account.html">
<img src="images/iconsAcc.png" alt="Аккаунт" width="38" />
</a>
</nav>
</header>
<main class="container-fluid p-2">
<div class="text-center">
<img
id="image-preview"
src="https://via.placeholder.com/200"
class="rounded rounded-circle"
alt="placeholder"
/>
</div>
<form id="items-form" class="needs-validation" novalidate>
<div class="mb-2">
<label for="item" class="form-label">Категория</label>
<select
id="item"
class="form-select"
name="selected"
required
></select>
</div>
<div class="mb-2">
<label class="form-label" for="description">Название</label>
<input
id="name"
name="name"
class="form-control"
type="text"
maxlength="100"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="price">Цена</label>
<input
id="price"
name="price"
class="form-control"
type="number"
value="0.00"
min="1000.00"
step="0.50"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="count">Количество</label>
<input
id="count"
name="count"
class="form-control"
type="number"
value="0"
min="1"
step="1"
required
/>
<div class="mb-2">
<label class="form-label" for="color">Цвет</label>
<input
id="color"
name="color"
class="form-control"
type="text"
maxlength="100"
required
/>
</div>
<div class="mb-2">
<label class="form-label" for="size">Размеры</label>
<input
id="size"
name="size"
class="form-control"
type="text"
maxlength="100"
required
/>
</div>
</div>
<div class="mb-2">
<label class="form-label" for="image">Изображение</label>
<input
id="image"
type="file"
name="image"
class="form-control"
accept="image/*"
/>
</div>
<a href="/page4.html" class="btn btn-secondary">Назад</a>
<button type="submit" class="btn btn-primary">Сохранить</button>
</form>
</main>
<script type="module">
import validation from "./js/validation";
import { linesPageForm } from "./js/lines";
document.addEventListener("DOMContentLoaded", () => {
validation();
linesPageForm();
});
</script>
</body>
</html>

View File

@ -37,9 +37,7 @@
<button id="items-add" type="submit" class="btn btn-success">
Добавить товар (диалог)
</button>
<a class="btn btn-secondary" href="/page-edit.html"
>Добавить товар (страница)</a
>
<div>
<table id="items-table" class="table table-light table-striped">
<thead>
@ -53,7 +51,6 @@
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</thead>
<tbody></tbody>
</table>
@ -66,10 +63,10 @@
data-bs-backdrop="static"
data-bs-keyboard="false"
>
<div class="modal-dialog">
<div class="modal-dialog modal-dialog-scrollable">
<form id="items-form" class="needs-validation" novalidate>
<div class="modal-content">
<div class="modal-header">
<div class="modal-header fixed-header">
<h1 class="modal-title fs-5" id="items-update-title"></h1>
<button
type="button"
@ -115,9 +112,9 @@
name="price"
class="form-control"
type="number"
value="0.00"
min="1000.00"
step="0.50"
value="0"
min="1000"
step="100"
required
/>
</div>
@ -139,7 +136,7 @@
id="color"
name="color"
class="form-control"
type="text"
type="color"
maxlength="100"
required
/>
@ -167,7 +164,7 @@
/>
</div>
</div>
<div class="modal-footer">
<div class="modal-footer fixed-footer">
<button
type="submit-grey"
class="btn btn-secondary"