Internet-programming_PIbd-2.../Library/js/lines.js

188 lines
8.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-disable import/prefer-default-export */
// модуль с логикой
import {
addBook, deleteLine, getAllCategoriesAndAuthors, getAllBooks, getBook, updateBook,
} from "./lines-rest-api";
import {
cntrls, createOption, createTableRow, imagePlaceholder,
} from "./lines-ui";
// функция для заполнения списков авторов и категорий книг
async function drawSelects() {
const [categories, authors] = await getAllCategoriesAndAuthors();
cntrls.categoryInput.innerHTML = "";
cntrls.authorInput.innerHTML = "";
cntrls.categoryInput.appendChild(createOption("Выберите значение", "", true));
cntrls.authorInput.appendChild(createOption("Выберите значение", "", true));
categories.forEach((category) => {
cntrls.categoryInput.appendChild(createOption(category.name, category.id));
});
authors.forEach((author) => {
cntrls.authorInput.appendChild(createOption(author.name, author.id));
});
}
// функция отрисовки таблицы
async function drawTable() {
console.info("Try to load data");
if (!cntrls.table) {
return;
}
const data = await getAllBooks();
cntrls.table.innerHTML = "";
data.forEach((book, index) => {
cntrls.table.appendChild(
createTableRow(
book,
index,
() => location.assign(`page-edit.html?id=${book.id}`),
() => removeLine(book.id),
),
);
});
}
async function addLine(categoriesId, name, authorsId, year, image) {
console.info("Try to add item");
// вызов метода REST API для добавления записи
const data = await addBook(categoriesId, name, authorsId, year, image);
console.info("Added");
console.info(data);
// загрузка и заполнение table
drawTable();
}
async function editLine(id, categoriesId, name, authorsId, year, image) {
console.info("Try to update item");
// вызов метода REST API для обновления записи
const data = await updateBook(id, categoriesId, name, authorsId, year, image);
console.info("Updated");
console.info(data);
// загрузка и заполнение table
drawTable();
}
async function removeLine(id) {
if (!confirm("Do you really want to remove this item?")) {
console.info("Canceled");
return;
}
console.info("Try to remove item");
// вызов метода REST API для удаления записи
const data = await deleteLine(id);
console.info(data);
// загрузка и заполнение table
drawTable();
}
// функция для обновления блока с превью выбранного изображения
async function updateImagePreview() {
// получение выбранного файла
// возможен выбор нескольких файлов, поэтому необходимо получить только первый
const file = cntrls.imageInput.files[0];
// чтение содержимого файла в виде base64 строки
const fileContent = await readFile(file);
console.info("base64 ", fileContent);
// обновление атрибута src для тега img с id image-preview
cntrls.imagePreview.src = fileContent;
}
// Функция для обработки создания и редактирования элементов таблицы через страницу
export async function linesPageForm() {
console.info("linesPageForm");
drawSelects();
drawTable();
const goBack = () => location.assign("./admin-page.html");
cntrls.imageInput.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 {
const book = await getBook(currentId);
cntrls.categoryInput.value = book.categoriesId;
cntrls.nameInput.value = book.name;
cntrls.authorInput.value = book.authorsId;
cntrls.yearInput.value = book.year;
cntrls.imagePreview.src = book.image ? book.image : imagePlaceholder;
} catch {
goBack();
}
}
cntrls.form.addEventListener("submit", async (event) => {
console.info("Form onSubmit");
// отключение стандартного поведения формы при отправке
// при отправке страница обновляется и JS перестает работать
event.preventDefault();
event.stopPropagation();
// если форма не прошла валидацию, то ничего делать не нужно
if (!cntrls.form.checkValidity()) {
return;
}
let imageBase64 = "";
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 строки для файла
imageBase64 = await readFile(blob);
}
if (!currentId) {
await addLine(
cntrls.categoryInput.value,
cntrls.nameInput.value,
cntrls.authorInput.value,
cntrls.yearInput.value,
imageBase64,
);
} else {
await editLine(
currentId,
cntrls.categoryInput.value,
cntrls.nameInput.value,
cntrls.authorInput.value,
cntrls.yearInput.value,
imageBase64,
);
}
goBack();
});
}
// функция для получения содержимого файла в виде base64 строки
// https://ru.wikipedia.org/wiki/Base64
async function readFile(file) {
const reader = new FileReader();
// создание Promise-объекта для использования функции
// с помощью await (асинхронно) без коллбэков (callback)
// https://learn.javascript.ru/promise
return new Promise((resolve, reject) => {
// 2. "Возвращаем" содержимое когда файл прочитан
// через вызов resolve
// Если не использовать Promise, то всю работу по взаимодействию
// с REST API пришлось бы делать в обработчике (callback) функции
// onloadend
reader.onloadend = () => {
const fileContent = reader.result;
// Здесь могла бы быть работа с REST API
// Чтение заканчивает выполняться здесь
resolve(fileContent);
};
// 3. Возвращаем ошибку
reader.onerror = () => {
// Или здесь в случае ошибки
reject(new Error("oops, something went wrong with the file reader."));
};
// Шаг 1. Сначала читаем файл
// Чтение начинает выполняться здесь
reader.readAsDataURL(file);
});
}