Maybe it works
This commit is contained in:
parent
ded9e916a0
commit
ada7d99c43
@ -67,7 +67,6 @@
|
|||||||
import validation from "./js/validation";
|
import validation from "./js/validation";
|
||||||
import { linesPageForm } from "./js/lines";
|
import { linesPageForm } from "./js/lines";
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
validation();
|
|
||||||
linesPageForm();
|
linesPageForm();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"items": [
|
"categories": [
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"name": "Ода"
|
"name": "Ода"
|
||||||
@ -13,35 +13,35 @@
|
|||||||
"name": "Лирическое стихотворение"
|
"name": "Лирическое стихотворение"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lines": [
|
"books": [
|
||||||
{
|
{
|
||||||
"itemsId": "3",
|
"categoriesId": "3",
|
||||||
|
"authorsId": "1",
|
||||||
"name": "Зимний вечер",
|
"name": "Зимний вечер",
|
||||||
"authorId": "1",
|
|
||||||
"year": "1830",
|
"year": "1830",
|
||||||
"image": "",
|
"image": "",
|
||||||
"id": 2
|
"id": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"itemsId": "1",
|
"categoriesId": "1",
|
||||||
|
"authorsId": "2",
|
||||||
"name": "Властителям и судиям",
|
"name": "Властителям и судиям",
|
||||||
"authorId": "2",
|
|
||||||
"year": "1780",
|
"year": "1780",
|
||||||
"image": "",
|
"image": "",
|
||||||
"id": 3
|
"id": 3
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"itemsId": "1",
|
"categoriesId": "1",
|
||||||
|
"authorsId": "3",
|
||||||
"name": "Exegi monumentum",
|
"name": "Exegi monumentum",
|
||||||
"authorId": "3",
|
|
||||||
"year": "23 до н. э.",
|
"year": "23 до н. э.",
|
||||||
"image": "",
|
"image": "",
|
||||||
"id": 4
|
"id": 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"itemsId": "2",
|
"categoriesId": "2",
|
||||||
|
"authorsId": "4",
|
||||||
"name": "К бедному поэту",
|
"name": "К бедному поэту",
|
||||||
"authorId": "4",
|
|
||||||
"year": "1796",
|
"year": "1796",
|
||||||
"image": "",
|
"image": "",
|
||||||
"id": 5
|
"id": 5
|
||||||
|
@ -3,19 +3,8 @@
|
|||||||
// адрес сервера
|
// адрес сервера
|
||||||
const serverUrl = "http://localhost:8081";
|
const serverUrl = "http://localhost:8081";
|
||||||
|
|
||||||
// функция возвращает объект нужной структуры для отправки на сервер
|
// обращение к серверу для получения всех типов авторов (get)
|
||||||
function createLineObject(item, name, authorId, year, image) {
|
export async function getAllAuthors() {
|
||||||
return {
|
|
||||||
itemsId: item,
|
|
||||||
name,
|
|
||||||
authorId,
|
|
||||||
year,
|
|
||||||
image,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// обращение к серверу для получения всех типов товара (get)
|
|
||||||
export async function getAllAuthorsTypes() {
|
|
||||||
const response = await fetch(`${serverUrl}/authors`);
|
const response = await fetch(`${serverUrl}/authors`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response.statusText;
|
throw response.statusText;
|
||||||
@ -23,9 +12,9 @@ export async function getAllAuthorsTypes() {
|
|||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
// обращение к серверу для получения всех типов товара (get)
|
// обращение к серверу для получения всех категорий книг (get)
|
||||||
export async function getAllItemTypes() {
|
export async function getAllCategories() {
|
||||||
const response = await fetch(`${serverUrl}/items`);
|
const response = await fetch(`${serverUrl}/categories`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response.statusText;
|
throw response.statusText;
|
||||||
}
|
}
|
||||||
@ -33,8 +22,8 @@ export async function getAllItemTypes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// обращение к серверу для получения всех записей (get)
|
// обращение к серверу для получения всех записей (get)
|
||||||
export async function getAllLines() {
|
export async function getAllBooks() {
|
||||||
const response = await fetch(`${serverUrl}/lines?_expand=items`);
|
const response = await fetch(`${serverUrl}/books?_expand=categories&_expand=authors`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response.statusText;
|
throw response.statusText;
|
||||||
}
|
}
|
||||||
@ -43,8 +32,8 @@ export async function getAllLines() {
|
|||||||
|
|
||||||
// обращение к серверу для получения записи по первичному ключу (id) (get)
|
// обращение к серверу для получения записи по первичному ключу (id) (get)
|
||||||
// id передается в качестве части пути URL get-запроса
|
// id передается в качестве части пути URL get-запроса
|
||||||
export async function getLine(id) {
|
export async function getBook(id) {
|
||||||
const response = await fetch(`${serverUrl}/lines/${id}?_expand=items`);
|
const response = await fetch(`${serverUrl}/books/${id}?_expand=categories&_expand=authors`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw response.statusText;
|
throw response.statusText;
|
||||||
}
|
}
|
||||||
@ -107,3 +96,14 @@ export async function deleteLine(id) {
|
|||||||
}
|
}
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// функция возвращает объект нужной структуры для отправки на сервер
|
||||||
|
function createLineObject(item, name, authorId, year, image) {
|
||||||
|
return {
|
||||||
|
itemsId: item,
|
||||||
|
name,
|
||||||
|
authorId,
|
||||||
|
year,
|
||||||
|
image,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -72,23 +72,18 @@ function createTableColumn(value) {
|
|||||||
// <td><a href="#" onclick="editPageCallback()"><i class="fa-solid fa-pen-to-square"></i></a></td>
|
// <td><a href="#" onclick="editPageCallback()"><i class="fa-solid fa-pen-to-square"></i></a></td>
|
||||||
// <td><a href="#" onclick="deleteCallback()"><i class="fa-solid fa-trash"></i></a></td>
|
// <td><a href="#" onclick="deleteCallback()"><i class="fa-solid fa-trash"></i></a></td>
|
||||||
// </tr>
|
// </tr>
|
||||||
export function createTableRow(item, author, index, editPageCallback, deleteCallback) {
|
export function createTableRow(book, index, editPageCallback, deleteCallback) {
|
||||||
const rowNumber = document.createElement("th");
|
const rowNumber = document.createElement("th");
|
||||||
rowNumber.scope = "row";
|
rowNumber.scope = "row";
|
||||||
rowNumber.textContent = index + 1;
|
rowNumber.textContent = index + 1;
|
||||||
|
|
||||||
const row = document.createElement("tr");
|
const row = document.createElement("tr");
|
||||||
row.id = `line-${item.id}`;
|
row.id = `line-${book.id}`;
|
||||||
|
|
||||||
row.appendChild(rowNumber);
|
row.appendChild(rowNumber);
|
||||||
row.appendChild(createTableColumn(item.items.name));
|
row.appendChild(createTableColumn(book.categories.name));
|
||||||
row.appendChild(createTableColumn(item.name));
|
row.appendChild(createTableColumn(book.name));
|
||||||
// row.appendChild(createTableColumn(item.authors.name));
|
row.appendChild(createTableColumn(book.authors.name));
|
||||||
row.appendChild(createTableColumn("item.authors.name"));
|
row.appendChild(createTableColumn(book.year));
|
||||||
row.appendChild(createTableColumn(item.year));
|
|
||||||
// редактировать на странице page-edit
|
|
||||||
row.appendChild(createTableAnchor("fa-pen-to-square", editPageCallback));
|
row.appendChild(createTableAnchor("fa-pen-to-square", editPageCallback));
|
||||||
// удаление
|
|
||||||
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
|
row.appendChild(createTableAnchor("fa-trash", deleteCallback));
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,21 @@
|
|||||||
|
/* eslint-disable import/prefer-default-export */
|
||||||
// модуль с логикой
|
// модуль с логикой
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createLine, deleteLine, getAllItemTypes, getAllAuthorsTypes, getAllLines, getLine, updateLine,
|
createLine, deleteLine, getAllCategories, getAllAuthors, getAllBooks, getBook, updateLine,
|
||||||
} from "./lines-rest-api";
|
} from "./lines-rest-api";
|
||||||
import {
|
import {
|
||||||
cntrls, createItemsOption, createTableRow, imagePlaceholder,
|
cntrls, createItemsOption, createTableRow, imagePlaceholder,
|
||||||
} from "./lines-ui";
|
} from "./lines-ui";
|
||||||
|
|
||||||
async function drawItemsSelect() {
|
// функция для заполнения списков авторов и категорий книг
|
||||||
// вызов метода REST API для получения списка типов товаров
|
async function drawLists() {
|
||||||
const data = await getAllItemTypes();
|
const data = await getAllCategories();
|
||||||
// вызов метода REST API для получения списка авторов
|
const authors = await getAllAuthors();
|
||||||
const authors = await getAllAuthorsTypes();
|
|
||||||
// очистка содержимого select
|
|
||||||
// удаляется все, что находится между тегами <select></select>
|
|
||||||
// но не атрибуты
|
|
||||||
cntrls.itemsType.innerHTML = "";
|
cntrls.itemsType.innerHTML = "";
|
||||||
cntrls.authorType.innerHTML = "";
|
cntrls.authorType.innerHTML = "";
|
||||||
// пустое значение
|
|
||||||
cntrls.itemsType.appendChild(createItemsOption("Выберите значение", "", true));
|
cntrls.itemsType.appendChild(createItemsOption("Выберите значение", "", true));
|
||||||
cntrls.authorType.appendChild(createItemsOption("Выберите значение", "", true));
|
cntrls.authorType.appendChild(createItemsOption("Выберите значение", "", true));
|
||||||
// цикл по результату ответа от сервера
|
|
||||||
// используется лямбда-выражение
|
|
||||||
// (item) => {} аналогично function(item) {}
|
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
cntrls.itemsType.appendChild(createItemsOption(item.name, item.id));
|
cntrls.itemsType.appendChild(createItemsOption(item.name, item.id));
|
||||||
});
|
});
|
||||||
@ -31,31 +24,21 @@ async function drawItemsSelect() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function drawLinesTable() {
|
// функция отрисовки таблицы
|
||||||
|
async function drawTable() {
|
||||||
console.info("Try to load data");
|
console.info("Try to load data");
|
||||||
if (!cntrls.table) {
|
if (!cntrls.table) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// вызов метода REST API для получения всех записей
|
const data = await getAllBooks();
|
||||||
const data = await getAllLines();
|
|
||||||
// очистка содержимого table
|
|
||||||
// удаляется все, что находится между тегами <table></table>
|
|
||||||
// но не атрибуты
|
|
||||||
cntrls.table.innerHTML = "";
|
cntrls.table.innerHTML = "";
|
||||||
// цикл по результату ответа от сервера
|
data.forEach((book, index) => {
|
||||||
// используется лямбда-выражение
|
|
||||||
// (item, index) => {} аналогично function(item, index) {}
|
|
||||||
data.forEach((item, author, index) => {
|
|
||||||
cntrls.table.appendChild(
|
cntrls.table.appendChild(
|
||||||
createTableRow(
|
createTableRow(
|
||||||
item,
|
book,
|
||||||
author,
|
|
||||||
index,
|
index,
|
||||||
// функции передаются в качестве параметра
|
() => location.assign(`page-edit.html?id=${book.id}`),
|
||||||
// это очень удобно, так как аргументы функций доступны только
|
() => removeLine(book.id),
|
||||||
// в данном месте кода и не передаются в сервисные модули
|
|
||||||
() => location.assign(`page-edit.html?id=${item.id}`),
|
|
||||||
() => removeLine(item.id),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -68,7 +51,7 @@ async function addLine(item, name, authorId, year, image) {
|
|||||||
console.info("Added");
|
console.info("Added");
|
||||||
console.info(data);
|
console.info(data);
|
||||||
// загрузка и заполнение table
|
// загрузка и заполнение table
|
||||||
drawLinesTable();
|
drawTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function editLine(id, item, name, authorId, year, image) {
|
async function editLine(id, item, name, authorId, year, image) {
|
||||||
@ -78,7 +61,7 @@ async function editLine(id, item, name, authorId, year, image) {
|
|||||||
console.info("Updated");
|
console.info("Updated");
|
||||||
console.info(data);
|
console.info(data);
|
||||||
// загрузка и заполнение table
|
// загрузка и заполнение table
|
||||||
drawLinesTable();
|
drawTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeLine(id) {
|
async function removeLine(id) {
|
||||||
@ -91,7 +74,7 @@ async function removeLine(id) {
|
|||||||
const data = await deleteLine(id);
|
const data = await deleteLine(id);
|
||||||
console.info(data);
|
console.info(data);
|
||||||
// загрузка и заполнение table
|
// загрузка и заполнение table
|
||||||
drawLinesTable();
|
drawTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// функция для получения содержимого файла в виде base64 строки
|
// функция для получения содержимого файла в виде base64 строки
|
||||||
@ -142,9 +125,9 @@ export async function linesPageForm() {
|
|||||||
console.info("linesPageForm");
|
console.info("linesPageForm");
|
||||||
|
|
||||||
// загрузка и заполнение select со списком товаров
|
// загрузка и заполнение select со списком товаров
|
||||||
drawItemsSelect();
|
drawLists();
|
||||||
// загрузка и заполнение table
|
// загрузка и заполнение table
|
||||||
drawLinesTable();
|
drawTable();
|
||||||
|
|
||||||
// func1 = (id) => {} аналогично function func1(id) {}
|
// func1 = (id) => {} аналогично function func1(id) {}
|
||||||
const goBack = () => location.assign("./admin-page.html");
|
const goBack = () => location.assign("./admin-page.html");
|
||||||
@ -164,107 +147,7 @@ export async function linesPageForm() {
|
|||||||
if (currentId) {
|
if (currentId) {
|
||||||
try {
|
try {
|
||||||
// вызов метода REST API для получения записи по первичному ключу(id)
|
// вызов метода REST API для получения записи по первичному ключу(id)
|
||||||
const line = await getLine(currentId);
|
const line = await getBook(currentId);
|
||||||
// заполнение формы для редактирования
|
|
||||||
cntrls.itemsType.value = line.itemsId;
|
|
||||||
cntrls.name.value = line.name;
|
|
||||||
cntrls.authorType.value = line.authorId;
|
|
||||||
cntrls.year.value = line.year;
|
|
||||||
// заполнение превью
|
|
||||||
// Если пользователь выбрал изображение, то оно загружается
|
|
||||||
// в тэг image с id image - preview
|
|
||||||
// иначе устанавливается заглушка, адрес которой указан в imagePlaceholder
|
|
||||||
cntrls.imagePreview.src = line.image ? line.image : imagePlaceholder;
|
|
||||||
} catch {
|
|
||||||
// в случае ошибки происходит возврат к admin-page
|
|
||||||
goBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// обработчик события отправки формы
|
|
||||||
// возникает при нажатии на кнопку (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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// если значение параметра запроса не задано,
|
|
||||||
// то необходимо выполнить добавление записи
|
|
||||||
// иначе обновление записи
|
|
||||||
if (!currentId) {
|
|
||||||
await addLine(
|
|
||||||
cntrls.itemsType.value,
|
|
||||||
cntrls.name.value,
|
|
||||||
cntrls.authorType.value,
|
|
||||||
cntrls.year.value,
|
|
||||||
imageBase64,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
await editLine(
|
|
||||||
currentId,
|
|
||||||
cntrls.itemsType.value,
|
|
||||||
cntrls.name.value,
|
|
||||||
cntrls.authorType.value,
|
|
||||||
cntrls.year.value,
|
|
||||||
imageBase64,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// возврат к странице admin-page
|
|
||||||
goBack();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function linesUserForm() {
|
|
||||||
console.info("linesPageForm");
|
|
||||||
|
|
||||||
// загрузка и заполнение select со списком товаров
|
|
||||||
drawItemsSelect();
|
|
||||||
// загрузка и заполнение table
|
|
||||||
drawLinesTable();
|
|
||||||
|
|
||||||
// func1 = (id) => {} аналогично function func1(id) {}
|
|
||||||
const goBack = () => location.assign("./admin-page.html");
|
|
||||||
|
|
||||||
// Вызов функции обновления превью изображения при возникновении
|
|
||||||
// события onchange в тэге input с id image
|
|
||||||
cntrls.image.addEventListener("change", () => updateImagePreview());
|
|
||||||
|
|
||||||
// получение параметров GET-запроса из URL
|
|
||||||
// параметры перечислены после символа ? (?id=1&color=black&...)
|
|
||||||
const urlParams = new URLSearchParams(location.search);
|
|
||||||
|
|
||||||
// получение значения конкретного параметра (id)
|
|
||||||
// указан только при редактировании
|
|
||||||
const currentId = urlParams.get("id");
|
|
||||||
// если id задан
|
|
||||||
if (currentId) {
|
|
||||||
try {
|
|
||||||
// вызов метода REST API для получения записи по первичному ключу(id)
|
|
||||||
const line = await getLine(currentId);
|
|
||||||
// заполнение формы для редактирования
|
// заполнение формы для редактирования
|
||||||
cntrls.itemsType.value = line.itemsId;
|
cntrls.itemsType.value = line.itemsId;
|
||||||
cntrls.name.value = line.name;
|
cntrls.name.value = line.name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user