import { createLine, deleteLine, updateLine, getAllGenreTypes, getAllLines, getLine, } from "./lines-rest-api"; import { controls, createGenresOption, createTableRow, imagePlaceholder, } from "./lines-ui"; // ОТОБРАЖЕНИЕ ВОЗМОЖНЫХ ЖАНРОВ ИГРЫ ПРИ СОЗДАНИИ/ИЗМЕНЕНИИ В SELECT async function drawGenresSelect() { // вызов метода REST API для получения списка жанров const data = await getAllGenreTypes(); // очистка содержимого select, удаление всего между тегами controls.genresType.innerHTML = ''; // пустое значение controls.genresType.appendChild(createGenresOption("Выберите жанр", "", true)); // цикл по результату ответа от сервера // используется лямбда-выражение // (item) => {} аналогично function(item) {} data.forEach((genre) => { controls.genresType.appendChild(createGenresOption(genre.name, genre.id)); }); } // ОБНОВЛЕНИЕ СОДЕРЖИМОГО TABLE ПРИ СОЗДАНИИ, РЕДАКТИРОВАНИИ, УДАЛЕНИИ export async function drawLinesTable() { console.info("Try to load data"); if (!controls.table) { return; } // вызов метода REST API для получения всех записей const data = await getAllLines(); // очистка содержимого table, удаление всего между тегами
controls.table.innerHTML = ""; // цикл по результату ответа от сервера с лямбда выражением (сокращение от function) // ДОБАВИЛ async И await data.forEach(async (item) => { // добавление строки в конец таблицы controls.table.appendChild( await createTableRow( item, // функции в качестве параметра // location - адрес текущей страницы, ей меняем адрес на страницу админки () => location.assign(`admin.html?id=${item.id}`), () => removeLine(item.id), ), ); }); } // ДОБАВЛЕНИЕ НОВОЙ ЗАПИСИ НА СЕРВЕР, ОБНОВЛЕНИЕ ТАБЛИЦЫ async function addLine(genre, name, price, image) { console.info("Try to add item"); // вызов метода REST API для добавления записи const data = await createLine(genre, name, price, image); console.info("Added"); console.info(data); // загрузка и заполнение table drawLinesTable(); } // РЕДАКТИРОВАНИЕ ЗАПИСИ НА СЕРВЕРЕ, ОБНОВЛЕНИЕ ТАБЛИЦЫ async function editLine(id, genre, name, price, image) { console.info("Try to update item"); // вызов метода REST API для обновления записи const data = await updateLine(id, genre, name, price, image); console.info("Updated"); console.info(data); // загрузка и заполнение table drawLinesTable(); } // УДАЛЕНИЕ ЗАПИСИ НА СЕРВЕРЕ, ОБНОВЛЕНИЕ ТАБЛИЦЫ async function removeLine(id) { if (!confirm("Удалить игру?")) { console.info("Canceled"); return; } console.info("Try to remove item"); // вызов метода REST API для удаления записи const data = await deleteLine(id); console.info(data); // загрузка и заполнение table drawLinesTable(); } // ПОЛУЧЕНИЕ ДАННЫХ ФАЙЛА (ФОТКИ) async function readFile(file) { const reader = new FileReader(); return new Promise((resolve, reject) => { // Шаг 1. Чтение файла reader.readAsDataURL(file); // Шаг 2. "Возвращение" содержимого, если файл нормально прочитан, через вызов resolve reader.onloadend = () => { const fileContent = reader.result; resolve(fileContent); }; // 3. Возвращение ошибки, если файл был прочитан с ошбикой reader.onerror = () => { // Или здесь в случае ошибки reject(new Error("Something went wrong with the file reader.")); }; }); } // Обновление превью выбранного изображения при изменении/создании async function updateImagePreview() { // получение выбранного файла // возможен выбор нескольких файлов, поэтому надо получить только первый const file = controls.image.files[0]; // чтение содержимого файла в виде base64 строки const fileContent = await readFile(file); console.info("base64 ", fileContent); // обновление источника src для тега img с id image-preview controls.imagePreview.src = fileContent; } // Функция для обработки создания и редактирования элементов таблицы через страницу admin.html export async function linesPageForm() { console.info("linesPageForm"); // загрузка и заполнение select со списком товаров drawGenresSelect(); // аналог function goBack() {} const goBack = () => location.assign("/index.html"); // Вызов функции обновления превью изображения при возникновении // события onchange в тэге input с id image controls.image.addEventListener("change", () => updateImagePreview()); // получение параметров GET-запроса из URL // параметры перечислены после символа ? const urlParams = new URLSearchParams(location.search); // получение значения конкретного параметра (id) // указан только при редактировании const currentId = urlParams.get("id"); // если id задан if (currentId) { try { // вызов метода REST API для получения записи по первичному ключу(id) const line = await getLine(currentId); // заполнение формы для редактирования controls.genresType.value = line.genresId; controls.price.value = line.price; controls.name.value = line.name; // заполнение превью // Если пользователь выбрал изображение, то оно загружается // в тэг image с id image - preview // иначе устанавливается заглушка, адрес которой указан в imagePlaceholder controls.imagePreview.src = line.image ? line.image : imagePlaceholder; } catch { // в случае ошибки происходит возврат к странице index goBack(); } } // обработчик события отправки формы // возникает при нажатии на кнопку (button) с типом submit // кнопка должна находится внутри тега form controls.form.addEventListener("submit", async (event) => { console.info("Form onSubmit"); // отключение стандартного поведения формы при отправке // при отправке страница обновляется и JS перестает работать event.preventDefault(); event.stopPropagation(); // если форма не прошла валидацию, то ничего делать не нужно if (!controls.form.checkValidity()) { return; } let imageBase64 = ""; // Получение выбранного пользователем изображения в виде base64 строки // Если пользователь ничего не выбрал, то не нужно сохранять в БД // дефолтное изображение if (controls.imagePreview.src !== imagePlaceholder) { // Загрузка содержимого атрибута src тэга img с id image-preview // Здесь выполняется HTTP запрос с типом GET const result = await fetch(controls.imagePreview.src); // Получение из HTTP-ответа бинарного содержимого const blob = await result.blob(); // Получение base64 строки для файла // Здесь выполняется Promise из функции readFile // Promise позволяет писать линейный код для работы с асинхронными методами // без использования обработчиков (callback) с помощью await imageBase64 = await readFile(blob); } // если значение параметра запроса не задано, // то значит сейчас делается добавление записи // если не задано, значит это обновление записи if (!currentId) { await addLine( controls.genresType.value, controls.name.value, controls.price.value, imageBase64, ); } else { await editLine( currentId, controls.genresType.value, controls.name.value, controls.price.value, imageBase64, ); } // возврат к странице index goBack(); }); }