3545 lines
143 KiB
JavaScript
3545 lines
143 KiB
JavaScript
"use strict";
|
||
|
||
if (typeof window.markets !== "function") {
|
||
// Not initialized
|
||
|
||
// Initialize of the class in global namespace
|
||
window.markets = class markets {
|
||
/**
|
||
* Заблокировать функцию закрытия всплывающего окна?
|
||
*/
|
||
static freeze = false;
|
||
|
||
/**
|
||
* Тело всплывающего окна (массив)
|
||
*/
|
||
static body = {};
|
||
|
||
/**
|
||
* Инициализирован класс?
|
||
*/
|
||
static initialized = false;
|
||
|
||
/**
|
||
* Управление кнопками (escape, enter...)
|
||
*
|
||
* Содержит функцию инициализирующую обработчики событий keydown для document
|
||
* функция деинициализируется с document при закрытии окна
|
||
*/
|
||
static buttons;
|
||
|
||
/**
|
||
* Ожидание зависимости: ядро
|
||
*
|
||
* @param {function} execute Функция, которая будет встроена в демпфер
|
||
* @param {mixed} args Аргументы встраиваемой функции
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static core(execute, ...args) {
|
||
if (typeof execute === "function") {
|
||
// Получена функция
|
||
|
||
// Инициализация интервала для ожидания загрузки зависимостей
|
||
const interval = setInterval(() => {
|
||
if (typeof core === "function") {
|
||
// Инициализировано ядро
|
||
|
||
// Деинициализация интервала для ожидания загрузки записимостей
|
||
clearInterval(interval);
|
||
|
||
// Запуск выполнения
|
||
return execute(...args);
|
||
}
|
||
}, 100);
|
||
|
||
// Инициализация деинициализации интервала для ожидания загрузки зависимостей спустя большой срок времени
|
||
setTimeout(() => clearInterval(interval), 3000);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Ожидание зависимости: демпфер
|
||
*
|
||
* @param {function} execute Функция, которая будет встроена в демпфер
|
||
* @param {number} timer Количество миллисекунд для демпфера
|
||
* @param {mixed} args Аргументы встраиваемой функции
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static damper(execute, timer = 3000, ...args) {
|
||
if (typeof execute === "function") {
|
||
// Получена функция
|
||
|
||
// Инициализация интервала для ожидания загрузки зависимостей
|
||
const interval = setInterval(() => {
|
||
if (typeof damper === "function") {
|
||
// Инициализирован демпфер
|
||
|
||
// Деинициализация интервала для ожидания загрузки записимостей
|
||
clearInterval(interval);
|
||
|
||
// Запуск выполнения
|
||
return damper(() => execute(...args), timer);
|
||
}
|
||
}, 100);
|
||
|
||
// Инициализация деинициализации интервала для ожидания загрузки зависимостей спустя большой срок времени
|
||
setTimeout(() => clearInterval(interval), 3000);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Авторизация
|
||
*
|
||
* @param {function} execute Функция, которая будет встроена в демпфер
|
||
* @param {mixed} args Аргументы встраиваемой функции
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static authorization(execute, ...args) {
|
||
if (typeof execute === "function") {
|
||
// Получена функция
|
||
|
||
if (core.page === this.page) {
|
||
// Пройдена проверка на страницу
|
||
|
||
// Запуск выполнения
|
||
return execute(...args);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Создать аккаунт и магазин (вызов демпфера)
|
||
*
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} market_name_first Имя представителя магазина <input>
|
||
* @param {HTMLElement} market_name_second Фамилия представителя магазина <input>
|
||
* @param {HTMLElement} market_name_last Отчество представителя магазина <input>
|
||
* @param {HTMLElement} market_number SIM-номер представителя магазина <input>
|
||
* @param {HTMLElement} market_mail Почта представителя магазина <input>
|
||
* @param {HTMLElement} market_id Идентификатор магазина <input>
|
||
* @param {HTMLElement} market_type Тип магазина <select>
|
||
* @param {HTMLElement} market_city Город магазина <select>
|
||
* @param {HTMLElement} market_district Регион магазина <input>
|
||
* @param {HTMLElement} market_address Адрес магазина <input>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_name_last Отчество/Матчество аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта представителя <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта представителя <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static _create(
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_id,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) {
|
||
// Блокировка полей ввода
|
||
market_name_first.setAttribute("readonly", true);
|
||
market_name_second.setAttribute("readonly", true);
|
||
market_name_last.setAttribute("readonly", true);
|
||
market_number.setAttribute("readonly", true);
|
||
market_mail.setAttribute("readonly", true);
|
||
market_id.setAttribute("readonly", true);
|
||
market_type.setAttribute("readonly", true);
|
||
market_city.setAttribute("readonly", true);
|
||
market_district.setAttribute("readonly", true);
|
||
market_address.setAttribute("readonly", true);
|
||
account_name_first.setAttribute("readonly", true);
|
||
account_name_second.setAttribute("readonly", true);
|
||
account_name_last.setAttribute("readonly", true);
|
||
account_number.setAttribute("readonly", true);
|
||
account_mail.setAttribute("readonly", true);
|
||
account_password.setAttribute("readonly", true);
|
||
account_commentary.setAttribute("readonly", true);
|
||
|
||
// Блокировка кнопки
|
||
button.setAttribute("disabled", true);
|
||
|
||
// Запуск выполнения
|
||
this.__create(
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_id,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Создать аккаунт и магазин (демпфер)
|
||
*
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} market_name_first Имя представителя магазина <input>
|
||
* @param {HTMLElement} market_name_second Фамилия представителя магазина <input>
|
||
* @param {HTMLElement} market_name_last Отчество представителя магазина <input>
|
||
* @param {HTMLElement} market_number SIM-номер представителя магазина <input>
|
||
* @param {HTMLElement} market_mail Почта представителя магазина <input>
|
||
* @param {HTMLElement} market_id Идентификатор магазина <input>
|
||
* @param {HTMLElement} market_type Тип магазина <select>
|
||
* @param {HTMLElement} market_city Город магазина <select>
|
||
* @param {HTMLElement} market_district Регион магазина <input>
|
||
* @param {HTMLElement} market_address Адрес магазина <input>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_name_last Отчество/Матчество аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта представителя магазина <input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта представителя <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта представителя <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static __create = damper(
|
||
async (
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_id,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) => {
|
||
// Инициализация функции разблокировки
|
||
function unblock() {
|
||
// Разблокировка полей ввода
|
||
market_name_first.removeAttribute("readonly");
|
||
market_name_second.removeAttribute("readonly");
|
||
market_name_last.removeAttribute("readonly");
|
||
market_number.removeAttribute("readonly");
|
||
market_mail.removeAttribute("readonly");
|
||
market_id.removeAttribute("readonly");
|
||
market_type.removeAttribute("readonly");
|
||
market_city.removeAttribute("readonly");
|
||
market_district.removeAttribute("readonly");
|
||
market_address.removeAttribute("readonly");
|
||
account_name_first.removeAttribute("readonly");
|
||
account_name_second.removeAttribute("readonly");
|
||
account_name_last.removeAttribute("readonly");
|
||
account_number.removeAttribute("readonly");
|
||
account_mail.removeAttribute("readonly");
|
||
account_password.removeAttribute("readonly");
|
||
account_commentary.removeAttribute("readonly");
|
||
|
||
// Разблокировка кнопки
|
||
button.removeAttribute("disabled");
|
||
}
|
||
|
||
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||
const timeout = setTimeout(() => {
|
||
this.errors(["Сервер не отвечает"]);
|
||
unblock();
|
||
}, 5000);
|
||
|
||
// Запрос к серверу
|
||
return await fetch("/markets/create", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: `market_name_first=${market_name_first.value}&market_name_second=${market_name_second.value}&market_name_last=${market_name_last.value}&market_number=${market_number.mask.unmaskedValue}&market_mail=${market_mail.value}&market_id=${market_id.value}&market_type=${market_type.value}&market_city=${market_city.value}&market_district=${market_district.value}&market_address=${market_address.value}&account_name_first=${account_name_first.value}&account_name_second=${account_name_second.value}&account_name_last=${account_name_last.value}&account_number=${account_number.mask.unmaskedValue}&account_mail=${account_mail.value}&account_password=${account_password.value}&account_commentary=${account_commentary.value}`,
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Удаление отсрочки разблокировки
|
||
clearTimeout(timeout);
|
||
|
||
if (this.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
|
||
// Разблокировка полей ввода и кнопок
|
||
unblock();
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
if (data.clipboard.length > 0) {
|
||
// Получены данные для записи в буфер обмена
|
||
|
||
// Запись в буфер обмена (подразумеваются данные созданного аккаунта представителя)
|
||
navigator.clipboard.writeText(data.clipboard);
|
||
}
|
||
|
||
if (this.body.wrap instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
|
||
// Деинициализация активного окна
|
||
this.body.wrap.remove();
|
||
}
|
||
|
||
// Реинициализация строк
|
||
this.reinit();
|
||
}
|
||
});
|
||
},
|
||
300
|
||
);
|
||
|
||
/**
|
||
* Сгенерировать окно создания аккаунта и магазина
|
||
*
|
||
* @param {HTMLElement} row Строка
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static create = damper(() => {
|
||
// Инициализация оболочки всплывающего окна
|
||
this.body.wrap = document.createElement("div");
|
||
this.body.wrap.setAttribute("id", "popup");
|
||
|
||
// Инициализация всплывающего окна
|
||
const popup = document.createElement("section");
|
||
popup.classList.add("list", "extensive", "medium");
|
||
|
||
// Инициализация заголовка всплывающего окна
|
||
const title = document.createElement("h3");
|
||
title.classList.add("unselectable");
|
||
title.innerText = "Создание магазина";
|
||
|
||
// Инициализация оболочки с основной информацией
|
||
const main = document.createElement("section");
|
||
main.classList.add("main");
|
||
|
||
// Инициализация колонки
|
||
const market = document.createElement("div");
|
||
market.classList.add("column");
|
||
market.setAttribute("data-column", "market");
|
||
market.style.setProperty("width", "450px");
|
||
|
||
// Инициализация строки
|
||
const market_name_first = document.createElement("div");
|
||
market_name_first.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_first_label = document.createElement("label");
|
||
market_name_first_label.setAttribute("id", "market_first");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_first_title = document.createElement("b");
|
||
market_name_first_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_first_title.innerText = "Имя:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_first_input = document.createElement("input");
|
||
market_name_first_input.classList.add("large");
|
||
market_name_first_input.setAttribute("type", "text");
|
||
market_name_first_input.setAttribute("name", "first");
|
||
market_name_first_input.setAttribute("autocomplete", "given-name");
|
||
market_name_first_input.setAttribute("minlength", "0");
|
||
market_name_first_input.setAttribute("maxlength", "100");
|
||
market_name_first_input.setAttribute(
|
||
"oninput",
|
||
`this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="first"]').value = this.value`
|
||
);
|
||
market_name_first_input.setAttribute(
|
||
"title",
|
||
"Имя представителя магазина"
|
||
);
|
||
market_name_first_input.setAttribute("placeholder", "Иван");
|
||
|
||
// Инициализация строки
|
||
const market_name_second = document.createElement("div");
|
||
market_name_second.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_second_label = document.createElement("label");
|
||
market_name_second_label.setAttribute("id", "market_second");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_second_title = document.createElement("b");
|
||
market_name_second_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_second_title.innerText = "Фамилия:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_second_input = document.createElement("input");
|
||
market_name_second_input.classList.add("large");
|
||
market_name_second_input.setAttribute("autocomplete", "family-name");
|
||
market_name_second_input.setAttribute("name", "second");
|
||
market_name_second_input.setAttribute("type", "text");
|
||
market_name_second_input.setAttribute("minlength", "0");
|
||
market_name_second_input.setAttribute("maxlength", "100");
|
||
market_name_second_input.setAttribute(
|
||
"oninput",
|
||
`this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="second"]').value = this.value`
|
||
);
|
||
market_name_second_input.setAttribute(
|
||
"title",
|
||
"Фамилия представителя магазина"
|
||
);
|
||
market_name_second_input.setAttribute("placeholder", "Иванов");
|
||
|
||
// Инициализация строки
|
||
const market_name_last = document.createElement("div");
|
||
market_name_last.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_last_label = document.createElement("label");
|
||
market_name_last_label.setAttribute("id", "market_last");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_last_title = document.createElement("b");
|
||
market_name_last_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_last_title.innerText = "Отчество:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_last_input = document.createElement("input");
|
||
market_name_last_input.classList.add("large");
|
||
market_name_last_input.setAttribute("name", "last");
|
||
market_name_last_input.setAttribute("autocomplete", "additional-name");
|
||
market_name_last_input.setAttribute("type", "text");
|
||
market_name_last_input.setAttribute("minlength", "0");
|
||
market_name_last_input.setAttribute("maxlength", "100");
|
||
market_name_last_input.setAttribute(
|
||
"oninput",
|
||
`this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="last"]').value = this.value`
|
||
);
|
||
market_name_last_input.setAttribute(
|
||
"title",
|
||
"Отчество/Матчество представителя магазина"
|
||
);
|
||
market_name_last_input.setAttribute("placeholder", "Иванович");
|
||
|
||
// Инициализация строки
|
||
const market_number = document.createElement("div");
|
||
market_number.classList.add("row", "merged", "divided");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_number_label = document.createElement("label");
|
||
market_number_label.setAttribute("id", "market_number");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_number_title = document.createElement("b");
|
||
market_number_title.classList.add("separated", "right", "unselectable");
|
||
market_number_title.innerText = "SIM-номер:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_number_input = document.createElement("input");
|
||
market_number_input.classList.add("large");
|
||
market_number_input.setAttribute("name", "sim-number");
|
||
market_number_input.setAttribute("autocomplete", "tel");
|
||
market_number_input.setAttribute("type", "text");
|
||
market_number_input.setAttribute("minlength", "18");
|
||
market_number_input.setAttribute("maxlength", "18");
|
||
market_number_input.setAttribute(
|
||
"oninput",
|
||
`this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="sim-number"]').value = this.value`
|
||
);
|
||
market_number_input.setAttribute(
|
||
"title",
|
||
"SIM-номер представителя магазина"
|
||
);
|
||
market_number_input.setAttribute("placeholder", "+7 (000) 000-00-00");
|
||
|
||
// Инициализация строки
|
||
const market_mail = document.createElement("div");
|
||
market_mail.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_mail_label = document.createElement("label");
|
||
market_mail_label.setAttribute("id", "market_mail");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_mail_title = document.createElement("b");
|
||
market_mail_title.classList.add("separated", "right", "unselectable");
|
||
market_mail_title.innerText = "Почта:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_mail_input = document.createElement("input");
|
||
market_mail_input.classList.add("large");
|
||
market_mail_input.setAttribute("name", "mail");
|
||
market_mail_input.setAttribute("autocomplete", "email");
|
||
market_mail_input.setAttribute("type", "text");
|
||
market_mail_input.setAttribute("minlength", "3");
|
||
market_mail_input.setAttribute("maxlength", "300");
|
||
market_mail_input.setAttribute(
|
||
"oninput",
|
||
`this.parentElement.parentElement.parentElement.parentElement.children[1].querySelector('[name="mail"]').value = this.value`
|
||
);
|
||
market_mail_input.setAttribute("title", "Почта представителя магазина");
|
||
market_mail_input.setAttribute("placeholder", "name@server");
|
||
|
||
// Инициализация строки
|
||
const market_id = document.createElement("div");
|
||
market_id.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_id_label = document.createElement("label");
|
||
market_id_label.setAttribute("id", "market_id");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_id_title = document.createElement("b");
|
||
market_id_title.classList.add("separated", "right", "unselectable");
|
||
market_id_title.innerText = "Идентификатор:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_id_input = document.createElement("input");
|
||
market_id_input.classList.add("large");
|
||
market_id_input.setAttribute("name", "id");
|
||
market_id_input.setAttribute("type", "text");
|
||
market_id_input.setAttribute("minlength", "1");
|
||
market_id_input.setAttribute("maxlength", "3");
|
||
market_id_input.setAttribute("title", "Идентификатор магазина");
|
||
market_id_input.setAttribute("placeholder", "000");
|
||
|
||
// Инициализация строки
|
||
const market_type = document.createElement("div");
|
||
market_type.classList.add("row", "divided", "merged");
|
||
|
||
// Инициализация оболочки для выпадающего списка
|
||
const market_type_label = document.createElement("label");
|
||
market_type_label.setAttribute("id", "market_type");
|
||
|
||
// Инициализация заголовка для выпадающего списка
|
||
const market_type_title = document.createElement("b");
|
||
market_type_title.classList.add("separated", "right");
|
||
market_type_title.innerText = "Тип:";
|
||
|
||
// Инициализация выпадающего списка
|
||
const market_type_select = document.createElement("select");
|
||
market_type_select.classList.add("large");
|
||
market_type_select.setAttribute("autocomplete", "address-level2");
|
||
market_type_select.setAttribute("name", "type");
|
||
market_type_select.setAttribute("title", "Тип магазина");
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_1 = document.createElement("option");
|
||
market_type_option_1.classList.add("value", "Стандарт");
|
||
market_type_option_1.innerText = "Стандарт";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_2 = document.createElement("option");
|
||
market_type_option_2.classList.add("value", "Фрешмаркет");
|
||
market_type_option_2.innerText = "Фрешмаркет";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_3 = document.createElement("option");
|
||
market_type_option_3.classList.add("value", "Дискаунтер");
|
||
market_type_option_3.innerText = "Дискаунтер";
|
||
|
||
// Инициализация строки
|
||
const market_city = document.createElement("div");
|
||
market_city.classList.add("row", "divided", "merged");
|
||
|
||
// Инициализация оболочки для выпадающего списка
|
||
const market_city_label = document.createElement("label");
|
||
market_city_label.setAttribute("id", "market_city");
|
||
|
||
// Инициализация заголовка для выпадающего списка
|
||
const market_city_title = document.createElement("b");
|
||
market_city_title.classList.add("separated", "right");
|
||
market_city_title.innerText = "Город:";
|
||
|
||
// Инициализация выпадающего списка
|
||
const market_city_select = document.createElement("select");
|
||
market_city_select.classList.add("large");
|
||
market_city_select.setAttribute("autocomplete", "address-level2");
|
||
market_city_select.setAttribute("name", "city");
|
||
market_city_select.setAttribute("title", "Город магазина");
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_1 = document.createElement("option");
|
||
market_city_option_1.classList.add("value", "Красноярск");
|
||
market_city_option_1.innerText = "Красноярск";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_2 = document.createElement("option");
|
||
market_city_option_2.classList.add("value", "Железногорск");
|
||
market_city_option_2.innerText = "Железногорск";
|
||
/*
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_3 = document.createElement("option");
|
||
market_city_option_3.classList.add("value", "");
|
||
market_city_option_3.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_4 = document.createElement("option");
|
||
market_city_option_4.classList.add("value", "");
|
||
market_city_option_4.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_5 = document.createElement("option");
|
||
market_city_option_5.classList.add("value", "");
|
||
market_city_option_5.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_ = document.createElement("option");
|
||
market_city_option_.classList.add("value", "");
|
||
market_city_option_.innerText = ""; */
|
||
|
||
// Инициализация строки
|
||
const market_district = document.createElement("div");
|
||
market_district.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_district_label = document.createElement("label");
|
||
market_district_label.setAttribute("id", "market_district");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_district_title = document.createElement("b");
|
||
market_district_title.classList.add("separated", "right");
|
||
market_district_title.innerText = "Регион:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_district_input = document.createElement("input");
|
||
market_district_input.classList.add("large");
|
||
market_district_input.setAttribute("autocomplete", "address-level3");
|
||
market_district_input.setAttribute("name", "district");
|
||
market_district_input.setAttribute("type", "text");
|
||
market_district_input.setAttribute("minlength", "0");
|
||
market_district_input.setAttribute("maxlength", "80");
|
||
market_district_input.setAttribute("title", "Регион магазина");
|
||
market_district_input.setAttribute("placeholder", "Центральный");
|
||
|
||
// Инициализация строки
|
||
const market_address = document.createElement("div");
|
||
market_address.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_address_label = document.createElement("label");
|
||
market_address_label.setAttribute("id", "market_address");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_address_title = document.createElement("b");
|
||
market_address_title.classList.add("separated", "right");
|
||
market_address_title.innerText = "Адрес:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_address_input = document.createElement("input");
|
||
market_address_input.classList.add("large");
|
||
market_address_input.setAttribute("autocomplete", "street-address");
|
||
market_address_input.setAttribute("name", "address");
|
||
market_address_input.setAttribute("type", "text");
|
||
market_address_input.setAttribute("minlength", "0");
|
||
market_address_input.setAttribute("maxlength", "150");
|
||
market_address_input.setAttribute("title", "Адрес магазина");
|
||
market_address_input.setAttribute("placeholder", "ул. Пушкина 7");
|
||
|
||
// Инициализация колонки
|
||
const account = document.createElement("div");
|
||
account.classList.add("column");
|
||
account.setAttribute("data-column", "account");
|
||
account.style.setProperty("width", "300px");
|
||
|
||
// Инициализация строки
|
||
const account_name_first = document.createElement("div");
|
||
account_name_first.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_first_label = document.createElement("label");
|
||
account_name_first_label.setAttribute("id", "account_first");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_first_title = document.createElement("b");
|
||
account_name_first_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_first_title.innerText = "Имя:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_first_input = document.createElement("input");
|
||
account_name_first_input.classList.add("medium");
|
||
account_name_first_input.setAttribute("type", "text");
|
||
account_name_first_input.setAttribute("name", "first");
|
||
account_name_first_input.setAttribute("autocomplete", "given-name");
|
||
account_name_first_input.setAttribute("minlength", "0");
|
||
account_name_first_input.setAttribute("maxlength", "100");
|
||
account_name_first_input.setAttribute(
|
||
"onclick",
|
||
"this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"first\"]').focus()"
|
||
);
|
||
account_name_first_input.setAttribute(
|
||
"title",
|
||
"Имя аккаунта представителя магазина"
|
||
);
|
||
account_name_first_input.setAttribute("placeholder", "Иван");
|
||
account_name_first_input.setAttribute("readonly", "true");
|
||
|
||
// Инициализация строки
|
||
const account_name_second = document.createElement("div");
|
||
account_name_second.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_second_label = document.createElement("label");
|
||
account_name_second_label.setAttribute("id", "account_second");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_second_title = document.createElement("b");
|
||
account_name_second_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_second_title.innerText = "Фамилия:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_second_input = document.createElement("input");
|
||
account_name_second_input.classList.add("medium");
|
||
account_name_second_input.setAttribute("autocomplete", "family-name");
|
||
account_name_second_input.setAttribute("name", "second");
|
||
account_name_second_input.setAttribute("type", "text");
|
||
account_name_second_input.setAttribute("minlength", "0");
|
||
account_name_second_input.setAttribute("maxlength", "100");
|
||
account_name_second_input.setAttribute(
|
||
"onclick",
|
||
"this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"second\"]').focus()"
|
||
);
|
||
account_name_second_input.setAttribute(
|
||
"title",
|
||
"Фамилия аккаунта представителя магазина"
|
||
);
|
||
account_name_second_input.setAttribute("placeholder", "Иванов");
|
||
account_name_second_input.setAttribute("readonly", "true");
|
||
|
||
// Инициализация строки
|
||
const account_name_last = document.createElement("div");
|
||
account_name_last.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_last_label = document.createElement("label");
|
||
account_name_last_label.setAttribute("id", "account_last");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_last_title = document.createElement("b");
|
||
account_name_last_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_last_title.innerText = "Отчество:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_last_input = document.createElement("input");
|
||
account_name_last_input.classList.add("medium");
|
||
account_name_last_input.setAttribute("name", "last");
|
||
account_name_last_input.setAttribute("autocomplete", "additional-name");
|
||
account_name_last_input.setAttribute("type", "text");
|
||
account_name_last_input.setAttribute("minlength", "0");
|
||
account_name_last_input.setAttribute("maxlength", "100");
|
||
account_name_last_input.setAttribute(
|
||
"onclick",
|
||
"this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"last\"]').focus()"
|
||
);
|
||
account_name_last_input.setAttribute(
|
||
"title",
|
||
"Отчество/Матчество аккаунта представителя магазина"
|
||
);
|
||
account_name_last_input.setAttribute("placeholder", "Иванович");
|
||
account_name_last_input.setAttribute("readonly", "true");
|
||
|
||
// Инициализация строки
|
||
const account_number = document.createElement("div");
|
||
account_number.classList.add("row", "merged", "divided");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_number_label = document.createElement("label");
|
||
account_number_label.setAttribute("id", "account_number");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_number_title = document.createElement("b");
|
||
account_number_title.classList.add("separated", "right", "unselectable");
|
||
account_number_title.innerText = "SIM-номер:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_number_input = document.createElement("input");
|
||
account_number_input.classList.add("medium");
|
||
account_number_input.setAttribute("name", "sim-number");
|
||
account_number_input.setAttribute("autocomplete", "tel");
|
||
account_number_input.setAttribute("type", "text");
|
||
account_number_input.setAttribute("minlength", "18");
|
||
account_number_input.setAttribute("maxlength", "18");
|
||
account_number_input.setAttribute(
|
||
"onclick",
|
||
"this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"sim-number\"]').focus()"
|
||
);
|
||
account_number_input.setAttribute(
|
||
"title",
|
||
"SIM-номер аккаунта представителя магазина"
|
||
);
|
||
account_number_input.setAttribute("placeholder", "+7 (000) 000-00-00");
|
||
account_number_input.setAttribute("readonly", "true");
|
||
|
||
// Инициализация строки
|
||
const account_mail = document.createElement("div");
|
||
account_mail.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_mail_label = document.createElement("label");
|
||
account_mail_label.setAttribute("id", "account_mail");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_mail_title = document.createElement("b");
|
||
account_mail_title.classList.add("separated", "right", "unselectable");
|
||
account_mail_title.innerText = "Почта:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_mail_input = document.createElement("input");
|
||
account_mail_input.classList.add("medium");
|
||
account_mail_input.setAttribute("name", "mail");
|
||
account_mail_input.setAttribute("autocomplete", "email");
|
||
account_mail_input.setAttribute("type", "text");
|
||
account_mail_input.setAttribute("minlength", "3");
|
||
account_mail_input.setAttribute("maxlength", "300");
|
||
account_mail_input.setAttribute(
|
||
"onclick",
|
||
"this.parentElement.parentElement.parentElement.parentElement.children[0].querySelector('[name=\"mail\"]').focus()"
|
||
);
|
||
account_mail_input.setAttribute(
|
||
"title",
|
||
"Почта аккаунта представителя магазина"
|
||
);
|
||
account_mail_input.setAttribute("placeholder", "name@server");
|
||
account_mail_input.setAttribute("readonly", "true");
|
||
|
||
// Инициализация строки
|
||
const account_password = document.createElement("div");
|
||
account_password.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_password_label = document.createElement("label");
|
||
account_password_label.setAttribute("id", "account_password");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_password_title = document.createElement("b");
|
||
account_password_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_password_title.innerText = "Пароль:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_password_input = document.createElement("input");
|
||
account_password_input.classList.add("medium");
|
||
account_password_input.setAttribute("name", "password");
|
||
account_password_input.setAttribute("required", "true");
|
||
account_password_input.setAttribute("autocomplete", "new-password");
|
||
account_password_input.setAttribute("type", "password");
|
||
account_password_input.setAttribute("minlength", "6");
|
||
account_password_input.setAttribute("maxlength", "100");
|
||
account_password_input.setAttribute(
|
||
"title",
|
||
"Пароль аккаунта представителя магазина"
|
||
);
|
||
account_password_input.setAttribute("placeholder", "*********");
|
||
|
||
// Инициализация строки
|
||
const account_commentary = document.createElement("div");
|
||
account_commentary.classList.add("row", "endless");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_commentary_label = document.createElement("label");
|
||
account_commentary_label.setAttribute("id", "account_commentary");
|
||
|
||
// Инициализация поля ввода
|
||
const account_commentary_textarea = document.createElement("textarea");
|
||
account_commentary_textarea.classList.add("snow");
|
||
account_commentary_textarea.setAttribute("maxlength", "800");
|
||
account_commentary_textarea.setAttribute(
|
||
"title",
|
||
"Комментарий аккаунта представителя магазина"
|
||
);
|
||
account_commentary_textarea.setAttribute(
|
||
"placeholder",
|
||
"Дополнительная информация для администраторов и операторов"
|
||
);
|
||
|
||
// Инициализация строки
|
||
const account_buttons = document.createElement("div");
|
||
account_buttons.classList.add("row", "divided", "buttons");
|
||
|
||
// Инициализация оболочки для кнопок
|
||
const account_buttons_label = document.createElement("label");
|
||
|
||
// Инициализация кнопки подтверждения даты
|
||
const account_create_button = document.createElement("button");
|
||
account_create_button.classList.add("grass", "stretched");
|
||
account_create_button.innerText = "Создать";
|
||
account_create_button.setAttribute(
|
||
"onclick",
|
||
`markets._create(this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`
|
||
);
|
||
|
||
// Инициализация окна с ошибками
|
||
this.body.errors = document.createElement("section");
|
||
this.body.errors.classList.add(
|
||
"errors",
|
||
"window",
|
||
"list",
|
||
"calculated",
|
||
"hidden"
|
||
);
|
||
this.body.errors.setAttribute("data-errors", true);
|
||
|
||
// Инициализация элемента-тела (оболочки) окна с ошибками
|
||
const errors = document.createElement("section");
|
||
errors.classList.add("body");
|
||
|
||
// Инициализация элемента-списка ошибок
|
||
const dl = document.createElement("dl");
|
||
|
||
// Инициализация активного всплывающего окна
|
||
const old = document.getElementById("popup");
|
||
|
||
if (old instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
|
||
// Удаление активного окна
|
||
old.remove();
|
||
}
|
||
|
||
// Запись в документ
|
||
popup.appendChild(title);
|
||
|
||
market_name_first_label.appendChild(market_name_first_title);
|
||
market_name_first_label.appendChild(market_name_first_input);
|
||
market_name_first.appendChild(market_name_first_label);
|
||
market.appendChild(market_name_first);
|
||
|
||
market_name_second_label.appendChild(market_name_second_title);
|
||
market_name_second_label.appendChild(market_name_second_input);
|
||
market_name_second.appendChild(market_name_second_label);
|
||
market.appendChild(market_name_second);
|
||
|
||
market_name_last_label.appendChild(market_name_last_title);
|
||
market_name_last_label.appendChild(market_name_last_input);
|
||
market_name_last.appendChild(market_name_last_label);
|
||
market.appendChild(market_name_last);
|
||
|
||
market_number_label.appendChild(market_number_title);
|
||
market_number_label.appendChild(market_number_input);
|
||
market_number.appendChild(market_number_label);
|
||
market.appendChild(market_number);
|
||
|
||
market_mail_label.appendChild(market_mail_title);
|
||
market_mail_label.appendChild(market_mail_input);
|
||
market_mail.appendChild(market_mail_label);
|
||
market.appendChild(market_mail);
|
||
|
||
market_id_label.appendChild(market_id_title);
|
||
market_id_label.appendChild(market_id_input);
|
||
market_id.appendChild(market_id_label);
|
||
market.appendChild(market_id);
|
||
|
||
market_type_label.appendChild(market_type_title);
|
||
market_type_select.appendChild(market_type_option_1);
|
||
market_type_select.appendChild(market_type_option_2);
|
||
market_type_select.appendChild(market_type_option_3);
|
||
market_type_label.appendChild(market_type_select);
|
||
market_type.appendChild(market_type_label);
|
||
market.appendChild(market_type);
|
||
|
||
market_city_label.appendChild(market_city_title);
|
||
market_city_select.appendChild(market_city_option_1);
|
||
market_city_select.appendChild(market_city_option_2);
|
||
market_city_label.appendChild(market_city_select);
|
||
market_city.appendChild(market_city_label);
|
||
market.appendChild(market_city);
|
||
|
||
market_district_label.appendChild(market_district_title);
|
||
market_district_label.appendChild(market_district_input);
|
||
market_district.appendChild(market_district_label);
|
||
market.appendChild(market_district);
|
||
|
||
market_address_label.appendChild(market_address_title);
|
||
market_address_label.appendChild(market_address_input);
|
||
market_address.appendChild(market_address_label);
|
||
market.appendChild(market_address);
|
||
|
||
main.appendChild(market);
|
||
|
||
account_name_first_label.appendChild(account_name_first_title);
|
||
account_name_first_label.appendChild(account_name_first_input);
|
||
account_name_first.appendChild(account_name_first_label);
|
||
account.appendChild(account_name_first);
|
||
|
||
account_name_second_label.appendChild(account_name_second_title);
|
||
account_name_second_label.appendChild(account_name_second_input);
|
||
account_name_second.appendChild(account_name_second_label);
|
||
account.appendChild(account_name_second);
|
||
|
||
account_name_last_label.appendChild(account_name_last_title);
|
||
account_name_last_label.appendChild(account_name_last_input);
|
||
account_name_last.appendChild(account_name_last_label);
|
||
account.appendChild(account_name_last);
|
||
|
||
account_number_label.appendChild(account_number_title);
|
||
account_number_label.appendChild(account_number_input);
|
||
account_number.appendChild(account_number_label);
|
||
account.appendChild(account_number);
|
||
|
||
account_mail_label.appendChild(account_mail_title);
|
||
account_mail_label.appendChild(account_mail_input);
|
||
account_mail.appendChild(account_mail_label);
|
||
account.appendChild(account_mail);
|
||
|
||
account_password_label.appendChild(account_password_title);
|
||
account_password_label.appendChild(account_password_input);
|
||
account_password.appendChild(account_password_label);
|
||
account.appendChild(account_password);
|
||
|
||
account_commentary_label.appendChild(account_commentary_textarea);
|
||
account_commentary.appendChild(account_commentary_label);
|
||
account.appendChild(account_commentary);
|
||
|
||
account_buttons_label.appendChild(account_create_button);
|
||
account_buttons.appendChild(account_buttons_label);
|
||
account.appendChild(account_buttons);
|
||
|
||
main.appendChild(account);
|
||
|
||
popup.appendChild(main);
|
||
this.body.wrap.appendChild(popup);
|
||
|
||
errors.appendChild(dl);
|
||
this.body.errors.appendChild(errors);
|
||
this.body.wrap.appendChild(this.body.errors);
|
||
|
||
document.body.appendChild(this.body.wrap);
|
||
|
||
// Инициализация ширины окна с ошибками
|
||
this.body.errors.style.setProperty(
|
||
"--calculated-width",
|
||
popup.offsetWidth + "px"
|
||
);
|
||
|
||
// Инициалиация масок
|
||
account_number_input.mask = IMask(account_number_input, {
|
||
mask: "+{7} (000) 000-00-00",
|
||
});
|
||
market_number_input.mask = IMask(market_number_input, {
|
||
mask: "+{7} (000) 000-00-00",
|
||
});
|
||
|
||
// Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
|
||
function top(errors) {
|
||
errors.style.setProperty("transition", "0s");
|
||
errors.style.setProperty(
|
||
"--top",
|
||
popup.offsetTop + popup.offsetHeight + 12 + "px"
|
||
);
|
||
setTimeout(() => errors.style.removeProperty("transition"), 100);
|
||
}
|
||
top(this.body.errors);
|
||
const resize = new ResizeObserver(() => top(this.body.errors));
|
||
resize.observe(this.body.wrap);
|
||
|
||
// Инициализация функции блокировки кнопки
|
||
const block = () => {
|
||
if (account_password_input.value.length > 6)
|
||
account_create_button.removeAttribute("disabled");
|
||
else account_create_button.setAttribute("disabled", "true");
|
||
};
|
||
|
||
// Добавление функции блокировки кнопки по событиям
|
||
account_password_input.addEventListener("keyup", block);
|
||
|
||
// Первичная активация функции блокировки кнопки
|
||
block();
|
||
|
||
// Инициализация функции генерации пароля и записи в поле ввода и буфер обмена
|
||
const generate = (e) => {
|
||
// Блокировка выполнения при нажатии на поле для ввода
|
||
if (e.target.tagName === "INPUT") return;
|
||
|
||
// Инициализация поля ввода пароля
|
||
const input = e.currentTarget.getElementsByTagName("input")[0];
|
||
|
||
if (input instanceof HTMLElement) {
|
||
// Найдено поле для ввода пароля
|
||
|
||
// Инициализация буфера генерации пароля
|
||
let password = "";
|
||
|
||
// Инициализация используемых символов для генерируемого пароля
|
||
const symbols =
|
||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789------";
|
||
|
||
// Генерация пароля
|
||
for (let i = 0; i < Math.random() * 14 + 8; i++) {
|
||
password += symbols.charAt(
|
||
Math.floor(Math.random() * symbols.length)
|
||
);
|
||
}
|
||
|
||
// Запись пароля в поле для ввода пароля
|
||
input.value = password;
|
||
|
||
// Вызов функции инициализации генератора пароля
|
||
input.dispatchEvent(new KeyboardEvent("keyup"));
|
||
|
||
// Запиcь пароля в буфер обмена
|
||
navigator.clipboard.writeText(password);
|
||
|
||
// Фокусировка на поле для ввода пароля
|
||
input.focus();
|
||
}
|
||
};
|
||
|
||
// Инициализация функции инициализации генератора пароля
|
||
const generator = (e) => {
|
||
// Инициализация строки с полем для ввода пароля
|
||
const row = e.currentTarget.parentElement.parentElement;
|
||
|
||
if (row instanceof HTMLElement) {
|
||
// Найдено поле для ввода пароля
|
||
|
||
if (e.target.value.length === 0) {
|
||
// Не введён пароль
|
||
|
||
row.setAttribute("title", "Сгенерировать пароль");
|
||
row.setAttribute("data-interactive", "true");
|
||
row.addEventListener("click", generate);
|
||
} else {
|
||
// Введён пароль
|
||
|
||
row.removeAttribute("title");
|
||
row.removeAttribute("data-interactive");
|
||
row.removeEventListener("click", generate);
|
||
}
|
||
}
|
||
};
|
||
|
||
// Инициализация вызова функции инициализации генератора пароля по события нажатия клавиши
|
||
account_password_input.addEventListener("keyup", generator);
|
||
|
||
// Вызов функции инициализации генератора пароля (первичный)
|
||
account_password_input.dispatchEvent(new KeyboardEvent("keyup"));
|
||
|
||
// Инициализация функции закрытия всплывающего окна
|
||
const click = () => {
|
||
// Блокировка
|
||
if (this.freeze) return;
|
||
|
||
// Удаление всплывающего окна
|
||
this.body.wrap.remove();
|
||
|
||
// Удаление статуса активной строки
|
||
// row.removeAttribute("data-selected"); // Это окно создания строки, её ещё не существует
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
};
|
||
|
||
// Инициализация функции добавления функции закрытия всплывающего окна
|
||
const enable = () => this.body.wrap.addEventListener("click", click);
|
||
|
||
// Инициализация функции удаления функции закрытия всплывающего окна
|
||
const disable = () => this.body.wrap.removeEventListener("click", click);
|
||
|
||
// Первичная активация функции удаления всплывающего окна
|
||
enable();
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с select-элементом
|
||
for (const select of popup.getElementsByTagName("select")) {
|
||
// Перебор всех select-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
select.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.freeze = false), 100);
|
||
});
|
||
|
||
for (const option of select.getElementsByTagName("option")) {
|
||
// Перебор всех option-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
option.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.freeze = false), 100);
|
||
});
|
||
}
|
||
}
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
|
||
for (const textarea of popup.getElementsByTagName("textarea")) {
|
||
// Перебор всех textarea-элементов
|
||
|
||
// Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
|
||
new MutationObserver(() => top(this.body.errors)).observe(textarea, {
|
||
attributes: true,
|
||
attributeFilter: ["style"],
|
||
});
|
||
|
||
// Инициализация функции игнорирования блокировки для выбранных кнопок
|
||
textarea.addEventListener("keydown", (e) => {
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.buttons(e, true);
|
||
} else if (e.ctrlKey && e.keyCode === 13) {
|
||
// Нажаты кнопки: "control", "enter"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.buttons(e, true);
|
||
}
|
||
});
|
||
|
||
// Добавление функции блокировки удаления окна и клавиш по событиям
|
||
textarea.addEventListener("focus", () => (this.freeze = true));
|
||
textarea.addEventListener("focusout", () => (this.freeze = false));
|
||
}
|
||
|
||
// Инициализация функции управления кнопками
|
||
this.buttons = (e, force = false) => {
|
||
// Блокировка
|
||
if (!force && this.freeze) return;
|
||
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Удаление окна
|
||
click();
|
||
} else if (event.keyCode === 13) {
|
||
// Нажата кнопка: "enter"
|
||
|
||
// Инициализация буфера с текущим статусом блокировки закрытия окна
|
||
const freeze = this.freeze;
|
||
|
||
// Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
|
||
this.freeze = true;
|
||
|
||
// Активация виртуальной кнопки "создать"
|
||
account_create_button.click();
|
||
|
||
// Возвращение статуса блокировки закрытия окна
|
||
this.freeze = freeze;
|
||
}
|
||
};
|
||
|
||
// Инициализация быстрых действий по кнопкам
|
||
document.addEventListener("keydown", this.buttons);
|
||
|
||
// Добавление функции удаления всплывающего окна по событиям
|
||
popup.addEventListener("mouseenter", disable);
|
||
popup.addEventListener("mouseleave", enable);
|
||
|
||
// Фокусировка
|
||
market_name_first_input.focus();
|
||
}, 300);
|
||
|
||
/**
|
||
* Переключить фильтр
|
||
*
|
||
* @param {string} name Название
|
||
* @param {string|number|null} value Значение
|
||
* @param {HTMLElement|null} button Кнопка
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static filter = damper(async (name, value, button) => {
|
||
if (typeof name === "string") {
|
||
// Получено название
|
||
|
||
// Инициализация сериализованного пути к директории
|
||
const path = `markets_filter_${name}`;
|
||
|
||
if (typeof value === "string" || typeof value === "number") {
|
||
// Получено значение
|
||
|
||
// Запись нового значения
|
||
buffer.write(path, value);
|
||
} else {
|
||
// Не получено значение
|
||
|
||
// Чтение текущего значения
|
||
value = +(await buffer.read(path));
|
||
|
||
// Инициализация значения по умолчанию
|
||
if (isNaN(value)) value = 0;
|
||
|
||
// Запись нового значения (инвертирование)
|
||
buffer.write(path, ++value < 3 ? value : 0);
|
||
|
||
if (button instanceof HTMLElement) {
|
||
// Получена кнопка
|
||
|
||
// Деинициализация классов статуса фильтра
|
||
button.classList.remove("earth", "sand", "river");
|
||
|
||
// Инициализация классов статуса фильтра
|
||
if (value === 1) button.classList.add("sand");
|
||
else if (value === 2) button.classList.add("river");
|
||
else button.classList.add("earth");
|
||
}
|
||
}
|
||
}
|
||
}, 300);
|
||
|
||
/**
|
||
* Записать фильтр поиска
|
||
*
|
||
* @param {HTMLElement} input Строка поиска
|
||
* @param {HTMLElement} button Кнопка отправки
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static search = (input, button) => {
|
||
input.setAttribute("readonly", true);
|
||
button.setAttribute("disabled", true);
|
||
|
||
this._search(input, button);
|
||
};
|
||
|
||
/**
|
||
* Записать фильтр поиска (системное)
|
||
*
|
||
* Используется как оболочка для большей временной задержки
|
||
*
|
||
* @param {HTMLElement} input Строка поиска
|
||
* @param {HTMLElement} button Кнопка отправки
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static _search = damper((input, button) => {
|
||
this.filter("search", input.value);
|
||
this.reinit(() => {
|
||
input.removeAttribute("readonly");
|
||
button.removeAttribute("disabled");
|
||
});
|
||
}, 1000);
|
||
|
||
/**
|
||
* Инициализация страниц
|
||
*
|
||
* @param {number} amount Количество страниц для генерации
|
||
* @param {number} iteration Номер итерации (системное)
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static async init(amount = 3, iteration = 0) {
|
||
if (
|
||
typeof amount === "number" &&
|
||
typeof iteration === "number" &&
|
||
this.initialized === false
|
||
) {
|
||
// Получены количество страниц и номер итерации
|
||
|
||
// Инициализация страницы (написал markets потому, что оптимизатор выдаёт ошибку, что this.read не найдено, хотя всё работает)
|
||
await markets.read(++iteration);
|
||
|
||
// Проверка условий и отложенный запуск следующей итерации
|
||
if (iteration < amount) setTimeout(this.init, 1500, amount, iteration);
|
||
else this.initialized = true;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Реинициализация страниц
|
||
*
|
||
* @param {function} postprocessing Функция которая будет исполнена после реинициализации
|
||
* @param {number} amount Количество страниц для генерации при инициализации
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static reinit = damper((postprocessing, amount = 3) => {
|
||
if (typeof amount === "number") {
|
||
// Получены количество страниц
|
||
|
||
// Деинициализация cookie с номером страницы
|
||
Cookies.remove("markets_page", { path: "/" });
|
||
|
||
// Инициализация оболочки
|
||
const tasks = document.getElementById("markets");
|
||
|
||
if (tasks instanceof HTMLElement) {
|
||
// Найдена оболочка
|
||
|
||
// Инициализация буфера активного элемента
|
||
const active = document.activeElement;
|
||
|
||
// Инициализация буфера элементов
|
||
const buffer = document.createElement("div");
|
||
|
||
// Перенос элементов в буфер
|
||
buffer.replaceChildren(...tasks.children);
|
||
|
||
// Удаление комментариев с индексами страниц
|
||
tasks.innerHTML = tasks.innerHTML.replace(
|
||
/<!--(?!>)[\S\s]*?-->/g,
|
||
""
|
||
);
|
||
|
||
// Перенос элементов из буфера
|
||
tasks.replaceChildren(...buffer.children);
|
||
|
||
// Деинициализация страниц
|
||
for (const element of tasks.querySelectorAll(
|
||
':scope > div[data-row="market"]'
|
||
))
|
||
element.remove();
|
||
|
||
// Сброс статуса инициализированности
|
||
this.initialized = false;
|
||
|
||
// Инициализация страниц
|
||
this.init(amount);
|
||
|
||
// Возвращение фокуса на активный элемент
|
||
active.focus();
|
||
|
||
// Постобработка
|
||
if (typeof postprocessing === "function") postprocessing();
|
||
}
|
||
}
|
||
}, 2000);
|
||
|
||
/**
|
||
* Прочитать
|
||
*
|
||
* Читает список и модифицирует документ (записывает в общий список)
|
||
*
|
||
* @param {number} page Страница
|
||
*
|
||
* @return {object} {(bool) exist, (array) errors}
|
||
*/
|
||
static read = damper(async (page) => {
|
||
if (typeof core === "function" && typeof page !== "number") {
|
||
// Не получена страница
|
||
|
||
// Инициализация страницы (если не получена, то брать из cookie и прибавлять 1)
|
||
page = Cookies.get(`markets_page`) ?? 0;
|
||
|
||
// Запись идентификатора следующей страницы
|
||
++page;
|
||
}
|
||
|
||
// Запрос к серверу
|
||
return await fetch("/markets/read", {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: `page=${page}`,
|
||
})
|
||
.then((response) => response.text())
|
||
.then((data) => {
|
||
// Инициализация буфера для записи в документ
|
||
const element = document.createElement("div");
|
||
|
||
// Запись пустого элемента из буфера в документ
|
||
document.getElementById("markets").appendChild(element);
|
||
|
||
// Запись в документ HTML-данных через буфер
|
||
element.outerHTML = data;
|
||
|
||
// Возврат (успех)
|
||
return data;
|
||
});
|
||
}, 50);
|
||
|
||
/**
|
||
* Сгенерировать список
|
||
*
|
||
* @return {array|null} Массив HTML-элементов <option>
|
||
*/
|
||
static async list() {
|
||
// Запрос к серверу
|
||
return await fetch(`/markets/list`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
})
|
||
.then((response) => response.text())
|
||
.then((data) => {
|
||
if (data.length > 0) {
|
||
// Получены данные
|
||
|
||
return data;
|
||
}
|
||
|
||
return null;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Обновить магазин (вызов демпфера)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} market_name_first Имя представителя магазина <input>
|
||
* @param {HTMLElement} market_name_second Фамилия представителя магазина <input>
|
||
* @param {HTMLElement} market_name_last Отчество представителя магазина <input>
|
||
* @param {HTMLElement} market_number SIM-номер представителя магазина <input>
|
||
* @param {HTMLElement} market_mail Почта представителя магазина <input>
|
||
* @param {HTMLElement} market_type Тип магазина <select>
|
||
* @param {HTMLElement} market_city Город магазина <select>
|
||
* @param {HTMLElement} market_district Регион магазина <input>
|
||
* @param {HTMLElement} market_address Адрес магазина <input>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static _update(
|
||
row,
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address
|
||
) {
|
||
// Блокировка полей ввода
|
||
market_name_first.setAttribute("readonly", true);
|
||
market_name_second.setAttribute("readonly", true);
|
||
market_name_last.setAttribute("readonly", true);
|
||
market_number.setAttribute("readonly", true);
|
||
market_mail.setAttribute("readonly", true);
|
||
market_type.setAttribute("readonly", true);
|
||
market_city.setAttribute("readonly", true);
|
||
market_district.setAttribute("readonly", true);
|
||
market_address.setAttribute("readonly", true);
|
||
|
||
// Блокировка кнопки
|
||
button.setAttribute("disabled", true);
|
||
|
||
// Запуск выполнения
|
||
this.__update(
|
||
row,
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Обновить сотрудника (демпфер)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} market_name_first Имя представителя магазина <input>
|
||
* @param {HTMLElement} market_name_second Фамилия представителя магазина <input>
|
||
* @param {HTMLElement} market_name_last Отчество представителя магазина <input>
|
||
* @param {HTMLElement} market_number SIM-номер представителя магазина <input>
|
||
* @param {HTMLElement} market_mail Почта представителя магазина <input>
|
||
* @param {HTMLElement} market_type Тип магазина <select>
|
||
* @param {HTMLElement} market_city Город магазина <select>
|
||
* @param {HTMLElement} market_district Регион магазина <input>
|
||
* @param {HTMLElement} market_address Адрес магазина <input>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static __update = damper(
|
||
async (
|
||
row,
|
||
button,
|
||
market_name_first,
|
||
market_name_second,
|
||
market_name_last,
|
||
market_number,
|
||
market_mail,
|
||
market_type,
|
||
market_city,
|
||
market_district,
|
||
market_address
|
||
) => {
|
||
// Инициализация функции разблокировки
|
||
function unblock() {
|
||
// Разблокировка полей ввода
|
||
market_name_first.removeAttribute("readonly");
|
||
market_name_second.removeAttribute("readonly");
|
||
market_name_last.removeAttribute("readonly");
|
||
market_number.removeAttribute("readonly");
|
||
market_mail.removeAttribute("readonly");
|
||
market_type.removeAttribute("readonly");
|
||
market_city.removeAttribute("readonly");
|
||
market_district.removeAttribute("readonly");
|
||
market_address.removeAttribute("readonly");
|
||
|
||
// Разблокировка кнопки
|
||
button.removeAttribute("disabled");
|
||
}
|
||
|
||
// Инициализация идентификатора сотрудника
|
||
const id = row.querySelector(['span[data-column="market"]']).innerText;
|
||
|
||
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||
const timeout = setTimeout(() => {
|
||
this.errors(["Сервер не отвечает"]);
|
||
unblock();
|
||
}, 5000);
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/market/${id}/update`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: `name_first=${market_name_first.value}&name_second=${market_name_second.value}&name_last=${market_name_last.value}&number=${market_number.mask.unmaskedValue}&mail=${market_mail.value}&type=${market_type.value}&city=${market_city.value}&district=${market_district.value}&address=${market_address.value}`,
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Удаление отсрочки разблокировки
|
||
clearTimeout(timeout);
|
||
|
||
if (this.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
|
||
// Разблокировка полей ввода и кнопок
|
||
unblock();
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
if (data.updated === true) {
|
||
// Записаны данные
|
||
|
||
// Инициализация буфера списка классов
|
||
// const buffer = [...row.classList];
|
||
|
||
// Инициализация статуса активной строки
|
||
const selected = row.getAttribute("data-selected");
|
||
|
||
// Реинициализация строки
|
||
row.outerHTML = data.row;
|
||
|
||
// Реинициализация строки (выражение странное, но правильное)
|
||
row = document.getElementById(row.getAttribute("id"));
|
||
|
||
// Копирование классов из буфера классов удалённой строки
|
||
// row.classList.add(...buffer);
|
||
|
||
// Копирование статуса активной строки
|
||
if (
|
||
typeof selected === "string" &&
|
||
selected === "true" &&
|
||
document.body.contains(document.getElementById("popup")) &&
|
||
!document.body.contains(
|
||
document.querySelector('[data-selected="true"]')
|
||
)
|
||
) {
|
||
row.setAttribute("data-selected", "true");
|
||
}
|
||
}
|
||
|
||
if (this.body.wrap instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
|
||
// Деинициализация активного окна
|
||
this.body.wrap.remove();
|
||
|
||
// Удаление статуса активной строки
|
||
row.removeAttribute("data-selected");
|
||
}
|
||
}
|
||
});
|
||
},
|
||
300
|
||
);
|
||
|
||
/**
|
||
* Сгенерировать окно для редактирования магазина
|
||
*
|
||
* @param {HTMLElement} row Строка
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static update = damper(async (row) => {
|
||
if (row instanceof HTMLElement) {
|
||
// Получена строка
|
||
|
||
// Инициализация идентификатора сотрудника
|
||
const id = row.querySelector(['span[data-column="market"]']).innerText;
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/market/${id}/fields`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Инициализация буфера выбранных строк
|
||
const buffer = [
|
||
...document.querySelectorAll('div[data-selected="true"]'),
|
||
];
|
||
|
||
// Удаление статуса активной строки у остальных строк
|
||
for (const element of buffer) {
|
||
element.removeAttribute("data-selected");
|
||
}
|
||
|
||
// Инициализация статуса активной строки (обрабатываемой в данный момент)
|
||
row.setAttribute("data-selected", "true");
|
||
|
||
// Инициализация оболочки всплывающего окна
|
||
this.body.wrap = document.createElement("div");
|
||
this.body.wrap.setAttribute("id", "popup");
|
||
|
||
// Инициализация всплывающего окна
|
||
const popup = document.createElement("section");
|
||
popup.classList.add("list", "extensive", "medium");
|
||
|
||
// Инициализация заголовка всплывающего окна
|
||
const title = document.createElement("h3");
|
||
title.innerText = id;
|
||
|
||
// Инициализация оболочки с основной информацией
|
||
const main = document.createElement("section");
|
||
main.classList.add("main");
|
||
|
||
// Инициализация колонки
|
||
const market = document.createElement("div");
|
||
market.classList.add("column");
|
||
market.setAttribute("data-column", "market");
|
||
market.style.setProperty("width", "450px");
|
||
|
||
// Инициализация строки
|
||
const market_name_first = document.createElement("div");
|
||
market_name_first.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_first_label = document.createElement("label");
|
||
market_name_first_label.setAttribute("id", "market_first");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_first_title = document.createElement("b");
|
||
market_name_first_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_first_title.innerText = "Имя:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_first_input = document.createElement("input");
|
||
market_name_first_input.classList.add("large");
|
||
market_name_first_input.setAttribute("type", "text");
|
||
market_name_first_input.setAttribute("name", "first");
|
||
market_name_first_input.setAttribute("autocomplete", "given-name");
|
||
market_name_first_input.setAttribute("minlength", "0");
|
||
market_name_first_input.setAttribute("maxlength", "100");
|
||
market_name_first_input.setAttribute(
|
||
"title",
|
||
"Имя представителя магазина"
|
||
);
|
||
market_name_first_input.setAttribute("placeholder", "Иван");
|
||
market_name_first_input.value = data.name.first ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_name_second = document.createElement("div");
|
||
market_name_second.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_second_label = document.createElement("label");
|
||
market_name_second_label.setAttribute("id", "market_second");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_second_title = document.createElement("b");
|
||
market_name_second_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_second_title.innerText = "Фамилия:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_second_input = document.createElement("input");
|
||
market_name_second_input.classList.add("large");
|
||
market_name_second_input.setAttribute(
|
||
"autocomplete",
|
||
"family-name"
|
||
);
|
||
market_name_second_input.setAttribute("name", "second");
|
||
market_name_second_input.setAttribute("type", "text");
|
||
market_name_second_input.setAttribute("minlength", "0");
|
||
market_name_second_input.setAttribute("maxlength", "100");
|
||
market_name_second_input.setAttribute(
|
||
"title",
|
||
"Фамилия представителя магазина"
|
||
);
|
||
market_name_second_input.setAttribute("placeholder", "Иванов");
|
||
market_name_second_input.value = data.name.second ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_name_last = document.createElement("div");
|
||
market_name_last.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_name_last_label = document.createElement("label");
|
||
market_name_last_label.setAttribute("id", "market_last");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_name_last_title = document.createElement("b");
|
||
market_name_last_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_name_last_title.innerText = "Отчество:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_name_last_input = document.createElement("input");
|
||
market_name_last_input.classList.add("large");
|
||
market_name_last_input.setAttribute("name", "last");
|
||
market_name_last_input.setAttribute(
|
||
"autocomplete",
|
||
"additional-name"
|
||
);
|
||
market_name_last_input.setAttribute("type", "text");
|
||
market_name_last_input.setAttribute("minlength", "0");
|
||
market_name_last_input.setAttribute("maxlength", "100");
|
||
market_name_last_input.setAttribute(
|
||
"title",
|
||
"Отчество/Матчество представителя магазина"
|
||
);
|
||
market_name_last_input.setAttribute("placeholder", "Иванович");
|
||
market_name_last_input.value = data.name.last ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_number = document.createElement("div");
|
||
market_number.classList.add("row", "merged", "divided");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_number_label = document.createElement("label");
|
||
market_number_label.setAttribute("id", "market_number");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_number_title = document.createElement("b");
|
||
market_number_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_number_title.innerText = "SIM-номер:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_number_input = document.createElement("input");
|
||
market_number_input.classList.add("large");
|
||
market_number_input.setAttribute("name", "sim-number");
|
||
market_number_input.setAttribute("autocomplete", "tel");
|
||
market_number_input.setAttribute("type", "text");
|
||
market_number_input.setAttribute("minlength", "18");
|
||
market_number_input.setAttribute("maxlength", "18");
|
||
market_number_input.setAttribute(
|
||
"title",
|
||
"SIM-номер представителя магазина"
|
||
);
|
||
market_number_input.setAttribute(
|
||
"placeholder",
|
||
"+7 (000) 000-00-00"
|
||
);
|
||
market_number_input.value = data.number ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_mail = document.createElement("div");
|
||
market_mail.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_mail_label = document.createElement("label");
|
||
market_mail_label.setAttribute("id", "market_mail");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_mail_title = document.createElement("b");
|
||
market_mail_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
market_mail_title.innerText = "Почта:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_mail_input = document.createElement("input");
|
||
market_mail_input.classList.add("large");
|
||
market_mail_input.setAttribute("name", "mail");
|
||
market_mail_input.setAttribute("autocomplete", "email");
|
||
market_mail_input.setAttribute("type", "text");
|
||
market_mail_input.setAttribute("minlength", "3");
|
||
market_mail_input.setAttribute("maxlength", "300");
|
||
market_mail_input.setAttribute(
|
||
"title",
|
||
"Почта представителя магазина"
|
||
);
|
||
market_mail_input.setAttribute("placeholder", "name@server");
|
||
market_mail_input.value = data.mail ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_type = document.createElement("div");
|
||
market_type.classList.add("row", "divided", "merged");
|
||
|
||
// Инициализация оболочки для выпадающего списка
|
||
const market_type_label = document.createElement("label");
|
||
market_type_label.setAttribute("id", "market_type");
|
||
|
||
// Инициализация заголовка для выпадающего списка
|
||
const market_type_title = document.createElement("b");
|
||
market_type_title.classList.add("separated", "right");
|
||
market_type_title.innerText = "Тип:";
|
||
|
||
// Инициализация выпадающего списка
|
||
const market_type_select = document.createElement("select");
|
||
market_type_select.classList.add("large");
|
||
market_type_select.setAttribute("autocomplete", "address-level2");
|
||
market_type_select.setAttribute("name", "type");
|
||
market_type_select.setAttribute("title", "Тип магазина");
|
||
market_type_select.value = data.type ?? "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_1 = document.createElement("option");
|
||
market_type_option_1.classList.add("value", "Стандарт");
|
||
market_type_option_1.innerText = "Стандарт";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_2 = document.createElement("option");
|
||
market_type_option_2.classList.add("value", "Фрешмаркет");
|
||
market_type_option_2.innerText = "Фрешмаркет";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_type_option_3 = document.createElement("option");
|
||
market_type_option_3.classList.add("value", "Дискаунтер");
|
||
market_type_option_3.innerText = "Дискаунтер";
|
||
|
||
// Инициализация строки
|
||
const market_city = document.createElement("div");
|
||
market_city.classList.add("row", "divided", "merged");
|
||
|
||
// Инициализация оболочки для выпадающего списка
|
||
const market_city_label = document.createElement("label");
|
||
market_city_label.setAttribute("id", "market_city");
|
||
|
||
// Инициализация заголовка для выпадающего списка
|
||
const market_city_title = document.createElement("b");
|
||
market_city_title.classList.add("separated", "right");
|
||
market_city_title.innerText = "Город:";
|
||
|
||
// Инициализация выпадающего списка
|
||
const market_city_select = document.createElement("select");
|
||
market_city_select.classList.add("large");
|
||
market_city_select.setAttribute("autocomplete", "address-level2");
|
||
market_city_select.setAttribute("name", "city");
|
||
market_city_select.setAttribute("title", "Город магазина");
|
||
market_city_select.value = data.city ?? "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_1 = document.createElement("option");
|
||
market_city_option_1.classList.add("value", "Красноярск");
|
||
market_city_option_1.innerText = "Красноярск";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_2 = document.createElement("option");
|
||
market_city_option_2.classList.add("value", "Железногорск");
|
||
market_city_option_2.innerText = "Железногорск";
|
||
|
||
/* // Инициализация варианта для выбора
|
||
const market_city_option_3 = document.createElement("option");
|
||
market_city_option_3.classList.add("value", "");
|
||
market_city_option_3.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_4 = document.createElement("option");
|
||
market_city_option_4.classList.add("value", "");
|
||
market_city_option_4.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_5 = document.createElement("option");
|
||
market_city_option_5.classList.add("value", "");
|
||
market_city_option_5.innerText = "";
|
||
|
||
// Инициализация варианта для выбора
|
||
const market_city_option_ = document.createElement("option");
|
||
market_city_option_.classList.add("value", "");
|
||
market_city_option_.innerText = ""; */
|
||
|
||
// Инициализация строки
|
||
const market_district = document.createElement("div");
|
||
market_district.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_district_label = document.createElement("label");
|
||
market_district_label.setAttribute("id", "market_district");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_district_title = document.createElement("b");
|
||
market_district_title.classList.add("separated", "right");
|
||
market_district_title.innerText = "Регион:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_district_input = document.createElement("input");
|
||
market_district_input.classList.add("large");
|
||
market_district_input.setAttribute(
|
||
"autocomplete",
|
||
"address-level3"
|
||
);
|
||
market_district_input.setAttribute("name", "district");
|
||
market_district_input.setAttribute("type", "text");
|
||
market_district_input.setAttribute("minlength", "0");
|
||
market_district_input.setAttribute("maxlength", "80");
|
||
market_district_input.setAttribute("title", "Регион магазина");
|
||
market_district_input.setAttribute("placeholder", "Центральный");
|
||
market_district_input.value = data.district ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_address = document.createElement("div");
|
||
market_address.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const market_address_label = document.createElement("label");
|
||
market_address_label.setAttribute("id", "market_address");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const market_address_title = document.createElement("b");
|
||
market_address_title.classList.add("separated", "right");
|
||
market_address_title.innerText = "Адрес:";
|
||
|
||
// Инициализация поля ввода
|
||
const market_address_input = document.createElement("input");
|
||
market_address_input.classList.add("large");
|
||
market_address_input.setAttribute("autocomplete", "street-address");
|
||
market_address_input.setAttribute("name", "address");
|
||
market_address_input.setAttribute("type", "text");
|
||
market_address_input.setAttribute("minlength", "0");
|
||
market_address_input.setAttribute("maxlength", "150");
|
||
market_address_input.setAttribute("title", "Адрес магазина");
|
||
market_address_input.setAttribute("placeholder", "ул. Пушкина 7");
|
||
market_address_input.value = data.address ?? "";
|
||
|
||
// Инициализация строки
|
||
const market_buttons = document.createElement("div");
|
||
market_buttons.classList.add("row", "divided", "buttons");
|
||
|
||
// Инициализация кнопки подтверждения даты
|
||
const market_update_button = document.createElement("button");
|
||
market_update_button.classList.add("grass", "stretched");
|
||
market_update_button.innerText = "Сохранить";
|
||
market_update_button.setAttribute(
|
||
"onclick",
|
||
`markets._update(document.getElementById(${
|
||
row.getAttribute("id") ?? ""
|
||
}), this, ...this.parentElement.parentElement.parentElement.parentElement.querySelectorAll(':is(select, input, textarea)'))`
|
||
);
|
||
|
||
// Инициализация окна с ошибками
|
||
this.body.errors = document.createElement("section");
|
||
this.body.errors.classList.add(
|
||
"errors",
|
||
"window",
|
||
"list",
|
||
"calculated",
|
||
"hidden"
|
||
);
|
||
this.body.errors.setAttribute("data-errors", true);
|
||
|
||
// Инициализация элемента-тела (оболочки) окна с ошибками
|
||
const errors = document.createElement("section");
|
||
errors.classList.add("body");
|
||
|
||
// Инициализация элемента-списка ошибок
|
||
const dl = document.createElement("dl");
|
||
|
||
// Инициализация активного всплывающего окна
|
||
const old = document.getElementById("popup");
|
||
|
||
if (old instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
|
||
// Удаление активного окна
|
||
old.remove();
|
||
}
|
||
|
||
// Запись в документ
|
||
popup.appendChild(title);
|
||
|
||
market_name_first_label.appendChild(market_name_first_title);
|
||
market_name_first_label.appendChild(market_name_first_input);
|
||
market_name_first.appendChild(market_name_first_label);
|
||
market.appendChild(market_name_first);
|
||
|
||
market_name_second_label.appendChild(market_name_second_title);
|
||
market_name_second_label.appendChild(market_name_second_input);
|
||
market_name_second.appendChild(market_name_second_label);
|
||
market.appendChild(market_name_second);
|
||
|
||
market_name_last_label.appendChild(market_name_last_title);
|
||
market_name_last_label.appendChild(market_name_last_input);
|
||
market_name_last.appendChild(market_name_last_label);
|
||
market.appendChild(market_name_last);
|
||
|
||
market_number_label.appendChild(market_number_title);
|
||
market_number_label.appendChild(market_number_input);
|
||
market_number.appendChild(market_number_label);
|
||
market.appendChild(market_number);
|
||
|
||
market_mail_label.appendChild(market_mail_title);
|
||
market_mail_label.appendChild(market_mail_input);
|
||
market_mail.appendChild(market_mail_label);
|
||
market.appendChild(market_mail);
|
||
|
||
market_type_label.appendChild(market_type_title);
|
||
market_type_select.appendChild(market_type_option_1);
|
||
market_type_select.appendChild(market_type_option_2);
|
||
market_type_select.appendChild(market_type_option_3);
|
||
market_type_label.appendChild(market_type_select);
|
||
market_type.appendChild(market_type_label);
|
||
market.appendChild(market_type);
|
||
|
||
market_city_label.appendChild(market_city_title);
|
||
market_city_select.appendChild(market_city_option_1);
|
||
market_city_select.appendChild(market_city_option_2);
|
||
market_city_label.appendChild(market_city_select);
|
||
market_city.appendChild(market_city_label);
|
||
market.appendChild(market_city);
|
||
|
||
market_district_label.appendChild(market_district_title);
|
||
market_district_label.appendChild(market_district_input);
|
||
market_district.appendChild(market_district_label);
|
||
market.appendChild(market_district);
|
||
|
||
market_address_label.appendChild(market_address_title);
|
||
market_address_label.appendChild(market_address_input);
|
||
market_address.appendChild(market_address_label);
|
||
market.appendChild(market_address);
|
||
|
||
market_buttons.appendChild(market_update_button);
|
||
market.appendChild(market_buttons);
|
||
|
||
main.appendChild(market);
|
||
|
||
popup.appendChild(main);
|
||
this.body.wrap.appendChild(popup);
|
||
|
||
errors.appendChild(dl);
|
||
this.body.errors.appendChild(errors);
|
||
this.body.wrap.appendChild(this.body.errors);
|
||
|
||
document.body.appendChild(this.body.wrap);
|
||
|
||
// Инициализация ширины окна с ошибками
|
||
this.body.errors.style.setProperty(
|
||
"--calculated-width",
|
||
popup.offsetWidth + "px"
|
||
);
|
||
|
||
// Инициалиация масок
|
||
market_number_input.mask = IMask(market_number_input, {
|
||
mask: "+{7} (000) 000-00-00",
|
||
});
|
||
|
||
// Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
|
||
function top(errors) {
|
||
errors.style.setProperty("transition", "0s");
|
||
errors.style.setProperty(
|
||
"--top",
|
||
popup.offsetTop + popup.offsetHeight + 12 + "px"
|
||
);
|
||
setTimeout(() => errors.style.removeProperty("transition"), 100);
|
||
}
|
||
top(this.body.errors);
|
||
const resize = new ResizeObserver(() => top(this.body.errors));
|
||
resize.observe(this.body.wrap);
|
||
|
||
// Инициализация функции закрытия всплывающего окна
|
||
const click = () => {
|
||
// Блокировка
|
||
if (this.freeze) return;
|
||
|
||
// Удаление всплывающего окна
|
||
this.body.wrap.remove();
|
||
|
||
// Инициализация буфера выбранных строк
|
||
const buffer = [
|
||
...document.querySelectorAll('div[data-selected="true"]'),
|
||
];
|
||
|
||
// Удаление статуса активной строки у остальных строк
|
||
for (const element of buffer) {
|
||
element.removeAttribute("data-selected");
|
||
}
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
};
|
||
|
||
// Инициализация функции добавления функции закрытия всплывающего окна
|
||
const enable = () =>
|
||
this.body.wrap.addEventListener("click", click);
|
||
|
||
// Инициализация функции удаления функции закрытия всплывающего окна
|
||
const disable = () =>
|
||
this.body.wrap.removeEventListener("click", click);
|
||
|
||
// Первичная активация функции удаления всплывающего окна
|
||
enable();
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с select-элементом
|
||
for (const select of popup.getElementsByTagName("select")) {
|
||
// Перебор всех select-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
select.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.freeze = false), 100);
|
||
});
|
||
|
||
for (const option of select.getElementsByTagName("option")) {
|
||
// Перебор всех option-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
option.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.freeze = false), 100);
|
||
});
|
||
}
|
||
}
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
|
||
for (const textarea of popup.getElementsByTagName("textarea")) {
|
||
// Перебор всех textarea-элементов
|
||
|
||
// Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
|
||
new MutationObserver(() => top(this.body.errors)).observe(
|
||
textarea,
|
||
{
|
||
attributes: true,
|
||
attributeFilter: ["style"],
|
||
}
|
||
);
|
||
|
||
// Инициализация функции игнорирования блокировки для выбранных кнопок
|
||
textarea.addEventListener("keydown", (e) => {
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.buttons(e, true);
|
||
} else if (e.ctrlKey && e.keyCode === 13) {
|
||
// Нажаты кнопки: "control", "enter"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.buttons(e, true);
|
||
}
|
||
});
|
||
|
||
// Добавление функции блокировки удаления окна и клавиш по событиям
|
||
textarea.addEventListener("focus", () => (this.freeze = true));
|
||
textarea.addEventListener(
|
||
"focusout",
|
||
() => (this.freeze = false)
|
||
);
|
||
}
|
||
|
||
// Инициализация функции управления кнопками
|
||
this.buttons = (e, force = false) => {
|
||
// Блокировка
|
||
if (!force && this.freeze) return;
|
||
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Удаление окна
|
||
click();
|
||
} else if (event.keyCode === 13) {
|
||
// Нажата кнопка: "enter"
|
||
|
||
// Инициализация буфера с текущим статусом блокировки закрытия окна
|
||
const freeze = this.freeze;
|
||
|
||
// Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
|
||
this.freeze = true;
|
||
|
||
// Активация виртуальной кнопки "сохранить"
|
||
market_update_button.click();
|
||
|
||
// Возвращение статуса блокировки закрытия окна
|
||
this.freeze = freeze;
|
||
}
|
||
};
|
||
|
||
// Инициализация быстрых действий по кнопкам
|
||
document.addEventListener("keydown", this.buttons);
|
||
|
||
// Инициализация функции удаления всплывающего окна по событиям
|
||
popup.addEventListener("mouseenter", disable);
|
||
popup.addEventListener("mouseleave", enable);
|
||
|
||
// Фокусировка
|
||
market_name_first_input.focus();
|
||
});
|
||
}
|
||
}, 300);
|
||
|
||
static account = class {
|
||
/**
|
||
* Ядро (родительский класс)
|
||
*/
|
||
static core;
|
||
|
||
/**
|
||
* Обновить аккаунт (вызов демпфера)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта <input>
|
||
* @param {HTMLElement} account_name_last Отчество аккаунта <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта<input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static _update(
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) {
|
||
// Блокировка полей ввода
|
||
account_name_first.setAttribute("readonly", true);
|
||
account_name_second.setAttribute("readonly", true);
|
||
account_name_last.setAttribute("readonly", true);
|
||
account_number.setAttribute("readonly", true);
|
||
account_mail.setAttribute("readonly", true);
|
||
account_password.setAttribute("readonly", true);
|
||
account_commentary.setAttribute("readonly", true);
|
||
|
||
// Блокировка кнопки
|
||
button.setAttribute("disabled", true);
|
||
|
||
// Запуск выполнения
|
||
this.__update(
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Обновить аккаунт (демпфер)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта <input>
|
||
* @param {HTMLElement} account_name_last Отчество аккаунта <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта<input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static __update = damper(
|
||
async (
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) => {
|
||
// Инициализация функции разблокировки
|
||
function unblock() {
|
||
// Разблокировка полей ввода
|
||
account_name_first.removeAttribute("readonly");
|
||
account_name_second.removeAttribute("readonly");
|
||
account_name_last.removeAttribute("readonly");
|
||
account_number.removeAttribute("readonly");
|
||
account_mail.removeAttribute("readonly");
|
||
account_password.removeAttribute("readonly");
|
||
account_commentary.removeAttribute("readonly");
|
||
|
||
// Разблокировка кнопки
|
||
button.removeAttribute("disabled");
|
||
}
|
||
|
||
// Инициализация идентификатора
|
||
const id = row.getAttribute("id");
|
||
|
||
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||
const timeout = setTimeout(() => {
|
||
this.core.errors(["Сервер не отвечает"]);
|
||
unblock();
|
||
}, 5000);
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/${id}/update`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
body: `name_first=${account_name_first.value}&name_second=${account_name_second.value}&name_last=${account_name_last.value}&number=${account_number.mask.unmaskedValue}&mail=${account_mail.value}&password=${account_password.value}&commentary=${account_commentary.value}`,
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Удаление отсрочки разблокировки
|
||
clearTimeout(timeout);
|
||
|
||
if (this.core.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
|
||
// Разблокировка полей ввода и кнопок
|
||
unblock();
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
if (data.updated === true) {
|
||
// Записаны данные
|
||
|
||
// Инициализация буфера списка классов
|
||
// const buffer = [...row.classList];
|
||
|
||
// Инициализация статуса активной строки
|
||
const selected = row.getAttribute("data-selected");
|
||
|
||
// Реинициализация строки
|
||
row.outerHTML = data.row;
|
||
|
||
// Реинициализация строки (выражение странное, но правильное)
|
||
row = document.getElementById(row.getAttribute("id"));
|
||
|
||
// Копирование классов из буфера классов удалённой строки
|
||
// row.classList.add(...buffer);
|
||
|
||
// Копирование статуса активной строки
|
||
if (
|
||
typeof selected === "string" &&
|
||
selected === "true" &&
|
||
document.body.contains(document.getElementById("popup")) &&
|
||
!document.body.contains(
|
||
document.querySelector('[data-selected="true"]')
|
||
)
|
||
) {
|
||
row.setAttribute("data-selected", "true");
|
||
}
|
||
}
|
||
|
||
if (
|
||
typeof data.clipboard !== "undefined" &&
|
||
data.clipboard.length > 0
|
||
) {
|
||
// Получены данные для записи в буфер обмена
|
||
|
||
// Запись в буфер обмена (подразумеваются данные созданного аккаунта)
|
||
navigator.clipboard.writeText(data.clipboard);
|
||
}
|
||
|
||
if (this.core.body.wrap instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.core.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.core.freeze = false;
|
||
|
||
// Деинициализация активного окна
|
||
this.core.body.wrap.remove();
|
||
|
||
// Удаление статуса активной строки
|
||
row.removeAttribute("data-selected");
|
||
}
|
||
}
|
||
});
|
||
},
|
||
300
|
||
);
|
||
|
||
/**
|
||
* Сгенерировать окно с данными аккаунта магазина
|
||
*
|
||
* @param {HTMLElement} row Строка
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static update = damper(async (row) => {
|
||
if (row instanceof HTMLElement) {
|
||
// Получена строка
|
||
|
||
// Инициализация идентификатора аккаунта
|
||
const id = row.getAttribute("id");
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/${id}/fields`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Инициализация буфера выбранных строк
|
||
const buffer = [
|
||
...document.querySelectorAll('div[data-selected="true"]'),
|
||
];
|
||
|
||
// Удаление статуса активной строки у остальных строк
|
||
for (const element of buffer) {
|
||
element.removeAttribute("data-selected");
|
||
}
|
||
|
||
// Инициализация статуса активной строки (обрабатываемой в данный момент)
|
||
row.setAttribute("data-selected", "true");
|
||
|
||
// Инициализация оболочки всплывающего окна
|
||
this.core.body.wrap = document.createElement("div");
|
||
this.core.body.wrap.setAttribute("id", "popup");
|
||
|
||
// Инициализация оболочки всплывающего окна
|
||
const popup = document.createElement("section");
|
||
popup.classList.add("list", "small");
|
||
|
||
// Инициализация заголовка всплывающего окна
|
||
const title = document.createElement("h3");
|
||
title.innerText = id;
|
||
|
||
// Инициализация оболочки с основной информацией
|
||
const main = document.createElement("section");
|
||
main.classList.add("main");
|
||
|
||
// Инициализация колонки
|
||
const account = document.createElement("div");
|
||
account.classList.add("column");
|
||
|
||
// Инициализация строки
|
||
const account_name_first = document.createElement("div");
|
||
account_name_first.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_first_label = document.createElement("label");
|
||
account_name_first_label.setAttribute("id", "account_first");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_first_title = document.createElement("b");
|
||
account_name_first_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_first_title.innerText = "Имя:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_first_input = document.createElement("input");
|
||
account_name_first_input.classList.add("medium");
|
||
account_name_first_input.setAttribute("type", "text");
|
||
account_name_first_input.setAttribute("name", "first");
|
||
account_name_first_input.setAttribute(
|
||
"autocomplete",
|
||
"given-name"
|
||
);
|
||
account_name_first_input.setAttribute("minlength", "0");
|
||
account_name_first_input.setAttribute("maxlength", "100");
|
||
account_name_first_input.setAttribute("title", "Имя аккаунта");
|
||
account_name_first_input.setAttribute("placeholder", "Иван");
|
||
account_name_first_input.value = data.name.first ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_name_second = document.createElement("div");
|
||
account_name_second.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_second_label = document.createElement("label");
|
||
account_name_second_label.setAttribute("id", "account_second");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_second_title = document.createElement("b");
|
||
account_name_second_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_second_title.innerText = "Фамилия:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_second_input = document.createElement("input");
|
||
account_name_second_input.classList.add("medium");
|
||
account_name_second_input.setAttribute(
|
||
"autocomplete",
|
||
"family-name"
|
||
);
|
||
account_name_second_input.setAttribute("name", "second");
|
||
account_name_second_input.setAttribute("type", "text");
|
||
account_name_second_input.setAttribute("minlength", "0");
|
||
account_name_second_input.setAttribute("maxlength", "100");
|
||
account_name_second_input.setAttribute(
|
||
"title",
|
||
"Фамилия аккаунта"
|
||
);
|
||
account_name_second_input.setAttribute("placeholder", "Иванов");
|
||
account_name_second_input.value = data.name.second ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_name_last = document.createElement("div");
|
||
account_name_last.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_name_last_label = document.createElement("label");
|
||
account_name_last_label.setAttribute("id", "account_last");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_name_last_title = document.createElement("b");
|
||
account_name_last_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_name_last_title.innerText = "Отчество:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_name_last_input = document.createElement("input");
|
||
account_name_last_input.classList.add("medium");
|
||
account_name_last_input.setAttribute("name", "last");
|
||
account_name_last_input.setAttribute(
|
||
"autocomplete",
|
||
"additional-name"
|
||
);
|
||
account_name_last_input.setAttribute("type", "text");
|
||
account_name_last_input.setAttribute("minlength", "0");
|
||
account_name_last_input.setAttribute("maxlength", "100");
|
||
account_name_last_input.setAttribute(
|
||
"title",
|
||
"Отчество/Матчество аккаунта"
|
||
);
|
||
account_name_last_input.setAttribute("placeholder", "Иванович");
|
||
account_name_last_input.value = data.name.last ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_number = document.createElement("div");
|
||
account_number.classList.add("row", "merged", "divided");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_number_label = document.createElement("label");
|
||
account_number_label.setAttribute("id", "account_number");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_number_title = document.createElement("b");
|
||
account_number_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_number_title.innerText = "SIM-номер:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_number_input = document.createElement("input");
|
||
account_number_input.classList.add("medium");
|
||
account_number_input.setAttribute("name", "sim-number");
|
||
account_number_input.setAttribute("autocomplete", "tel");
|
||
account_number_input.setAttribute("type", "text");
|
||
account_number_input.setAttribute("minlength", "18");
|
||
account_number_input.setAttribute("maxlength", "18");
|
||
account_number_input.setAttribute("title", "SIM-номер аккаунта");
|
||
account_number_input.setAttribute(
|
||
"placeholder",
|
||
"+7 (000) 000-00-00"
|
||
);
|
||
account_number_input.value = data.number ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_mail = document.createElement("div");
|
||
account_mail.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_mail_label = document.createElement("label");
|
||
account_mail_label.setAttribute("id", "account_mail");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_mail_title = document.createElement("b");
|
||
account_mail_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_mail_title.innerText = "Почта:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_mail_input = document.createElement("input");
|
||
account_mail_input.classList.add("medium");
|
||
account_mail_input.setAttribute("name", "mail");
|
||
account_mail_input.setAttribute("autocomplete", "email");
|
||
account_mail_input.setAttribute("type", "text");
|
||
account_mail_input.setAttribute("minlength", "3");
|
||
account_mail_input.setAttribute("maxlength", "300");
|
||
account_mail_input.setAttribute("title", "Почта аккаунта");
|
||
account_mail_input.setAttribute("placeholder", "name@server");
|
||
account_mail_input.value = data.mail ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_password = document.createElement("div");
|
||
account_password.classList.add("row", "merged");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_password_label = document.createElement("label");
|
||
account_password_label.setAttribute("id", "account_password");
|
||
|
||
// Инициализация заголовка для поля ввода
|
||
const account_password_title = document.createElement("b");
|
||
account_password_title.classList.add(
|
||
"separated",
|
||
"right",
|
||
"unselectable"
|
||
);
|
||
account_password_title.innerText = "Пароль:";
|
||
|
||
// Инициализация поля ввода
|
||
const account_password_input = document.createElement("input");
|
||
account_password_input.classList.add("medium");
|
||
account_password_input.setAttribute("name", "password");
|
||
account_password_input.setAttribute("required", "true");
|
||
account_password_input.setAttribute(
|
||
"title",
|
||
"Не менее 8 символов"
|
||
);
|
||
account_password_input.setAttribute(
|
||
"autocomplete",
|
||
"new-password"
|
||
);
|
||
account_password_input.setAttribute("type", "password");
|
||
account_password_input.setAttribute("minlength", "8");
|
||
account_password_input.setAttribute("maxlength", "100");
|
||
account_password_input.setAttribute("title", "Пароль аккаунта");
|
||
account_password_input.setAttribute("placeholder", "*********");
|
||
|
||
// Инициализация строки
|
||
const account_commentary = document.createElement("div");
|
||
account_commentary.classList.add("row", "endless");
|
||
|
||
// Инициализация оболочки для строки
|
||
const account_commentary_label = document.createElement("label");
|
||
account_commentary_label.setAttribute("id", "account_commentary");
|
||
|
||
// Инициализация поля ввода
|
||
const account_commentary_textarea =
|
||
document.createElement("textarea");
|
||
account_commentary_textarea.setAttribute("maxlength", "800");
|
||
account_commentary_textarea.setAttribute(
|
||
"title",
|
||
"Комментарий аккаунта"
|
||
);
|
||
account_commentary_textarea.setAttribute(
|
||
"placeholder",
|
||
"Дополнительная информация для администраторов"
|
||
);
|
||
account_commentary_textarea.value = data.commentary ?? "";
|
||
|
||
// Инициализация строки
|
||
const account_buttons = document.createElement("div");
|
||
account_buttons.classList.add("row", "divided", "buttons");
|
||
|
||
// Инициализация кнопки обновления
|
||
const account_update_button = document.createElement("button");
|
||
account_update_button.classList.add("grass", "stretched");
|
||
account_update_button.innerText = "Сохранить";
|
||
account_update_button.setAttribute(
|
||
"onclick",
|
||
`markets.account._update(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`
|
||
);
|
||
|
||
// Инициализация кнопки удаления
|
||
const account_delete_button = document.createElement("button");
|
||
account_delete_button.classList.add("clay");
|
||
account_delete_button.innerText = "Удалить";
|
||
account_delete_button.setAttribute(
|
||
"onclick",
|
||
`markets.account._delete(document.getElementById(${id}), this, ...this.parentElement.parentElement.parentElement.querySelectorAll(':is(input, textarea)'))`
|
||
);
|
||
|
||
// Инициализация окна с ошибками
|
||
this.core.body.errors = document.createElement("section");
|
||
this.core.body.errors.classList.add(
|
||
"errors",
|
||
"window",
|
||
"list",
|
||
"small",
|
||
"hidden"
|
||
);
|
||
this.core.body.errors.setAttribute("data-errors", true);
|
||
|
||
// Инициализация элемента-оболочки с ошибками для всплывающего окна
|
||
const errors = document.createElement("section");
|
||
errors.classList.add("body");
|
||
|
||
// Инициализация элемента-списка ошибок
|
||
const dl = document.createElement("dl");
|
||
|
||
// Инициализация активного всплывающего окна
|
||
const old = document.getElementById("popup");
|
||
|
||
if (old instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.freeze = false;
|
||
|
||
// Удаление активного окна
|
||
old.remove();
|
||
}
|
||
|
||
// Запись в документ
|
||
popup.appendChild(title);
|
||
|
||
account_name_first_label.appendChild(account_name_first_title);
|
||
account_name_first_label.appendChild(account_name_first_input);
|
||
account_name_first.appendChild(account_name_first_label);
|
||
account.appendChild(account_name_first);
|
||
|
||
account_name_second_label.appendChild(account_name_second_title);
|
||
account_name_second_label.appendChild(account_name_second_input);
|
||
account_name_second.appendChild(account_name_second_label);
|
||
account.appendChild(account_name_second);
|
||
|
||
account_name_last_label.appendChild(account_name_last_title);
|
||
account_name_last_label.appendChild(account_name_last_input);
|
||
account_name_last.appendChild(account_name_last_label);
|
||
account.appendChild(account_name_last);
|
||
|
||
account_number_label.appendChild(account_number_title);
|
||
account_number_label.appendChild(account_number_input);
|
||
account_number.appendChild(account_number_label);
|
||
account.appendChild(account_number);
|
||
|
||
account_mail_label.appendChild(account_mail_title);
|
||
account_mail_label.appendChild(account_mail_input);
|
||
account_mail.appendChild(account_mail_label);
|
||
account.appendChild(account_mail);
|
||
|
||
account_password_label.appendChild(account_password_title);
|
||
account_password_label.appendChild(account_password_input);
|
||
account_password.appendChild(account_password_label);
|
||
account.appendChild(account_password);
|
||
|
||
account_commentary_label.appendChild(account_commentary_textarea);
|
||
account_commentary.appendChild(account_commentary_label);
|
||
account.appendChild(account_commentary);
|
||
|
||
account_buttons.appendChild(account_update_button);
|
||
account_buttons.appendChild(account_delete_button);
|
||
account.appendChild(account_buttons);
|
||
|
||
main.appendChild(account);
|
||
popup.appendChild(main);
|
||
this.core.body.wrap.appendChild(popup);
|
||
|
||
errors.appendChild(dl);
|
||
this.core.body.errors.appendChild(errors);
|
||
this.core.body.wrap.appendChild(this.core.body.errors);
|
||
|
||
document.body.appendChild(this.core.body.wrap);
|
||
|
||
// Инициалиация масок
|
||
account_number_input.mask = IMask(account_number_input, {
|
||
mask: "+{7} (000) 000-00-00",
|
||
});
|
||
|
||
// Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
|
||
function top(errors) {
|
||
errors.style.setProperty("transition", "0s");
|
||
errors.style.setProperty(
|
||
"--top",
|
||
popup.offsetTop + popup.offsetHeight + 12 + "px"
|
||
);
|
||
setTimeout(
|
||
() => errors.style.removeProperty("transition"),
|
||
100
|
||
);
|
||
}
|
||
top(this.core.body.errors);
|
||
const resize = new ResizeObserver(() =>
|
||
top(this.core.body.errors)
|
||
);
|
||
resize.observe(this.core.body.wrap);
|
||
|
||
// Инициализация функции генерации пароля и записи в поле ввода и буфер обмена
|
||
const generate = (e) => {
|
||
// Блокировка выполнения при нажатии на поле для ввода
|
||
if (e.target.tagName === "INPUT") return;
|
||
|
||
// Инициализация поля ввода пароля
|
||
const input = e.currentTarget.getElementsByTagName("input")[0];
|
||
|
||
if (input instanceof HTMLElement) {
|
||
// Найдено поле для ввода пароля
|
||
|
||
// Инициализация буфера генерации пароля
|
||
let password = "";
|
||
|
||
// Инициализация используемых символов для генерируемого пароля
|
||
const symbols =
|
||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789------";
|
||
|
||
// Генерация пароля
|
||
for (let i = 0; i < Math.random() * 14 + 8; i++) {
|
||
password += symbols.charAt(
|
||
Math.floor(Math.random() * symbols.length)
|
||
);
|
||
}
|
||
|
||
// Запись пароля в поле для ввода пароля
|
||
input.value = password;
|
||
|
||
// Вызов функции инициализации генератора пароля
|
||
input.dispatchEvent(new KeyboardEvent("keyup"));
|
||
|
||
// Запиcь пароля в буфер обмена
|
||
navigator.clipboard.writeText(password);
|
||
|
||
// Фокусировка на поле для ввода пароля
|
||
input.focus();
|
||
}
|
||
};
|
||
|
||
// Инициализация функции инициализации генератора пароля
|
||
const generator = (e) => {
|
||
// Инициализация строки с полем для ввода пароля
|
||
const row = e.currentTarget.parentElement.parentElement;
|
||
|
||
if (row instanceof HTMLElement) {
|
||
// Найдено поле для ввода пароля
|
||
|
||
if (e.target.value.length === 0) {
|
||
// Не введён пароль
|
||
|
||
row.setAttribute("title", "Сгенерировать пароль");
|
||
row.setAttribute("data-interactive", "true");
|
||
row.addEventListener("click", generate);
|
||
} else {
|
||
// Введён пароль
|
||
|
||
row.removeAttribute("title");
|
||
row.removeAttribute("data-interactive");
|
||
row.removeEventListener("click", generate);
|
||
}
|
||
}
|
||
};
|
||
|
||
// Инициализация вызова функции инициализации генератора пароля по события нажатия клавиши
|
||
account_password_input.addEventListener("keyup", generator);
|
||
|
||
// Вызов функции инициализации генератора пароля (первичный)
|
||
account_password_input.dispatchEvent(new KeyboardEvent("keyup"));
|
||
|
||
// Инициализация функции закрытия всплывающего окна
|
||
const click = () => {
|
||
// Блокировка
|
||
if (this.core.freeze) return;
|
||
|
||
// Удаление всплывающего окна
|
||
this.core.body.wrap.remove();
|
||
|
||
// Инициализация буфера выбранных строк
|
||
const buffer = [
|
||
...document.querySelectorAll('div[data-selected="true"]'),
|
||
];
|
||
|
||
// Удаление статуса активной строки у остальных строк
|
||
for (const element of buffer) {
|
||
element.removeAttribute("data-selected");
|
||
}
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.core.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.core.freeze = false;
|
||
};
|
||
|
||
// Инициализация функции добавления функции закрытия всплывающего окна
|
||
const enable = () =>
|
||
this.core.body.wrap.addEventListener("click", click);
|
||
|
||
// Инициализация функции удаления функции закрытия всплывающего окна
|
||
const disable = () =>
|
||
this.core.body.wrap.removeEventListener("click", click);
|
||
|
||
// Первичная активация функции удаления всплывающего окна
|
||
enable();
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с select-элементом
|
||
for (const select of popup.getElementsByTagName("select")) {
|
||
// Перебор всех select-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
select.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.core.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.core.freeze = false), 100);
|
||
});
|
||
|
||
for (const option of select.getElementsByTagName("option")) {
|
||
// Перебор всех option-элементов
|
||
|
||
// Инициализация функции блокировки удаления окна по событию
|
||
option.addEventListener("click", () => {
|
||
// Блокировка удаления окна
|
||
this.core.freeze = true;
|
||
|
||
// Разблокировка удаления окна
|
||
setTimeout(() => (this.core.freeze = false), 100);
|
||
});
|
||
}
|
||
}
|
||
|
||
// Инициализация блокировки удаления окна при взаимодействии с textarea-элементом
|
||
for (const textarea of popup.getElementsByTagName("textarea")) {
|
||
// Перебор всех textarea-элементов
|
||
|
||
// Обновлять позицию окна с ошибками при изменении размера textarea (там position: absolute)
|
||
new MutationObserver(() => top(this.core.body.errors)).observe(
|
||
textarea,
|
||
{
|
||
attributes: true,
|
||
attributeFilter: ["style"],
|
||
}
|
||
);
|
||
|
||
// Инициализация функции игнорирования блокировки для выбранных кнопок
|
||
textarea.addEventListener("keydown", (e) => {
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.core.buttons(e, true);
|
||
} else if (e.ctrlKey && e.keyCode === 13) {
|
||
// Нажаты кнопки: "control", "enter"
|
||
|
||
// Вызов глобальной функции управления кнопками
|
||
this.core.buttons(e, true);
|
||
}
|
||
});
|
||
|
||
// Добавление функции блокировки удаления окна и клавиш по событиям
|
||
textarea.addEventListener(
|
||
"focus",
|
||
() => (this.core.freeze = true)
|
||
);
|
||
textarea.addEventListener(
|
||
"focusout",
|
||
() => (this.core.freeze = false)
|
||
);
|
||
}
|
||
|
||
// Инициализация функции управления кнопками
|
||
this.core.buttons = (e, force = false) => {
|
||
// Блокировка
|
||
if (!force && this.core.freeze) return;
|
||
|
||
if (e.keyCode === 27) {
|
||
// Нажата кнопка: "escape"
|
||
|
||
// Удаление окна
|
||
click();
|
||
} else if (event.keyCode === 13) {
|
||
// Нажата кнопка: "enter"
|
||
|
||
// Инициализация буфера с текущим статусом блокировки закрытия окна
|
||
const freeze = this.core.freeze;
|
||
|
||
// Блокировка закрытия окна (чтобы не вызвался click() через событие onclick)
|
||
this.core.freeze = true;
|
||
|
||
// Активация виртуальной кнопки "сохранить"
|
||
account_update_button.click();
|
||
|
||
// Возвращение статуса блокировки закрытия окна
|
||
this.core.freeze = freeze;
|
||
}
|
||
};
|
||
|
||
// Инициализация быстрых действий по кнопкам
|
||
document.addEventListener("keydown", this.core.buttons);
|
||
|
||
// Добавление функции удаления всплывающего окна по событиям
|
||
popup.addEventListener("mouseenter", disable);
|
||
popup.addEventListener("mouseleave", enable);
|
||
|
||
// Фокусировка
|
||
account_name_first_input.focus();
|
||
});
|
||
}
|
||
}, 300);
|
||
|
||
/**
|
||
* Удалить аккаунт (вызов демпфера)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта <input>
|
||
* @param {HTMLElement} account_name_last Отчество аккаунта <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта<input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static _delete(
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) {
|
||
// Блокировка полей ввода
|
||
account_name_first.setAttribute("readonly", true);
|
||
account_name_second.setAttribute("readonly", true);
|
||
account_name_last.setAttribute("readonly", true);
|
||
account_number.setAttribute("readonly", true);
|
||
account_mail.setAttribute("readonly", true);
|
||
account_password.setAttribute("readonly", true);
|
||
account_commentary.setAttribute("readonly", true);
|
||
|
||
// Блокировка кнопки
|
||
button.setAttribute("disabled", true);
|
||
|
||
// Запуск выполнения
|
||
this.__delete(
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Удалить аккаунт (демпфер)
|
||
*
|
||
* @param {HTMLElement} row Строка <div>
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
* @param {HTMLElement} account_name_first Имя аккаунта <input>
|
||
* @param {HTMLElement} account_name_second Фамилия аккаунта <input>
|
||
* @param {HTMLElement} account_name_last Отчество аккаунта <input>
|
||
* @param {HTMLElement} account_number SIM-номер аккаунта <input>
|
||
* @param {HTMLElement} account_mail Почта аккаунта<input>
|
||
* @param {HTMLElement} account_password Пароль аккаунта <input>
|
||
* @param {HTMLElement} account_commentary Комментарий аккаунта <textarea>
|
||
*
|
||
* @return {void}
|
||
*/
|
||
static __delete = damper(
|
||
async (
|
||
row,
|
||
button,
|
||
account_name_first,
|
||
account_name_second,
|
||
account_name_last,
|
||
account_number,
|
||
account_mail,
|
||
account_password,
|
||
account_commentary
|
||
) => {
|
||
// Инициализация функции разблокировки
|
||
function unblock() {
|
||
// Разблокировка полей ввода
|
||
account_name_first.removeAttribute("readonly");
|
||
account_name_second.removeAttribute("readonly");
|
||
account_name_last.removeAttribute("readonly");
|
||
account_number.removeAttribute("readonly");
|
||
account_mail.removeAttribute("readonly");
|
||
account_password.removeAttribute("readonly");
|
||
account_commentary.removeAttribute("readonly");
|
||
|
||
// Разблокировка кнопки
|
||
button.removeAttribute("disabled");
|
||
}
|
||
|
||
// Инициализация идентификатора
|
||
const id = row.getAttribute("id");
|
||
|
||
// Запуск отсрочки разблокировки на случай, если сервер не отвечает
|
||
const timeout = setTimeout(() => {
|
||
this.core.errors(["Сервер не отвечает"]);
|
||
unblock();
|
||
}, 5000);
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/${id}/delete`, {
|
||
method: "POST",
|
||
headers: {
|
||
"Content-Type": "application/x-www-form-urlencoded",
|
||
},
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
// Удаление отсрочки разблокировки
|
||
clearTimeout(timeout);
|
||
|
||
if (this.core.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
|
||
// Разблокировка полей ввода и кнопок
|
||
unblock();
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
if (data.deleted === true) {
|
||
// Удалены данные
|
||
|
||
// Удаление строки
|
||
row.remove();
|
||
}
|
||
|
||
if (this.core.body.wrap instanceof HTMLElement) {
|
||
// Найдено активное окно
|
||
|
||
// Деинициализация быстрых действий по кнопкам
|
||
document.removeEventListener("keydown", this.core.buttons);
|
||
|
||
// Сброс блокировки
|
||
this.core.freeze = false;
|
||
|
||
// Деинициализация активного окна
|
||
this.core.body.wrap.remove();
|
||
|
||
// Удаление статуса активной строки
|
||
row.removeAttribute("data-selected");
|
||
}
|
||
}
|
||
});
|
||
},
|
||
300
|
||
);
|
||
};
|
||
|
||
/**
|
||
* Заблокировать сотрудника
|
||
*
|
||
* @param {string|int} worker Идентификатор сотрудника
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
*/
|
||
static async ban(worker, button) {
|
||
console.log(button);
|
||
if ((typeof worker === "string" || typeof worker === 'number') && button instanceof HTMLElement) {
|
||
// Получены идентификатор сотрудника и кнопка
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/market/ban/${worker}`, {
|
||
method: "POST",
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
if (this.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
button.classList.remove("clay");
|
||
button.classList.add("earth");
|
||
button.innerText = "Разблокировать";
|
||
button.setAttribute(
|
||
"title",
|
||
"Сотрудник снова сможет записываться на заявки"
|
||
);
|
||
button.setAttribute("onclick", `markets.unban(${worker}, this)`);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Разблокировать сотрудника
|
||
*
|
||
* @param {string|int} worker Идентификатор сотрудника
|
||
* @param {HTMLElement} button Кнопка <button>
|
||
*/
|
||
static async unban(worker, button) {
|
||
if (typeof worker === "string" || typeof worker === 'number' && button instanceof HTMLElement) {
|
||
// Получены идентификатор сотрудника и кнопка
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/market/unban/${worker}`, {
|
||
method: "POST",
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
if (this.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
button.classList.remove("earth");
|
||
button.classList.add("clay");
|
||
button.innerText = "Заблокировать";
|
||
button.setAttribute(
|
||
"title",
|
||
"Сотрудник не сможет записываться на заявки"
|
||
);
|
||
button.setAttribute("onclick", `markets.ban(${worker}, this)`);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Проверить нахождение сотрудника в списке заблокированных
|
||
*
|
||
* @param {string|int} worker Идентификатор сотрудника
|
||
*
|
||
* @return {bool} Сотрудник заблокирован?
|
||
*/
|
||
static async banned(worker) {
|
||
if (typeof worker === "string" || typeof worker === 'number') {
|
||
// Получен идентификатор сотрудника
|
||
|
||
// Запрос к серверу
|
||
return await fetch(`/market/banned/${worker}`, {
|
||
method: "POST",
|
||
})
|
||
.then((response) => response.json())
|
||
.then((data) => {
|
||
if (this.errors(data.errors)) {
|
||
// Сгенерированы ошибки
|
||
} else {
|
||
// Не сгенерированы ошибки (подразумевается их отсутствие)
|
||
|
||
return data.banned;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Сгенерировать HTML-элемент со списком ошибок
|
||
*
|
||
* @param {object} registry Реестр ошибок
|
||
* @param {bool} render Отобразить в окне с ошибками?
|
||
* @param {bool} clean Очистить окно с ошибками перед добавлением?
|
||
*
|
||
* @return {bool} Сгенерированы ошибки?
|
||
*/
|
||
static errors(registry, render = true, clean = true) {
|
||
// Инициализация ссылки на HTML-элемент с ошибками
|
||
const wrap = document.body.contains(this.body.errors)
|
||
? this.body.errors
|
||
: document.querySelector('[data-errors="true"]');
|
||
|
||
if (wrap instanceof HTMLElement && document.body.contains(wrap)) {
|
||
// Найден HTML-элемент с ошибками
|
||
|
||
// Перерасчёт высоты элемента
|
||
function height() {
|
||
wrap.classList.remove("hidden");
|
||
wrap.classList.remove("animation");
|
||
// Реинициализация переменной с данными о высоте HTML-элемента (16 - это padding-top + padding-bottom у div#popup > section.errors)
|
||
wrap.style.setProperty("--height", wrap.offsetHeight - 16 + "px");
|
||
wrap.classList.add("animation");
|
||
wrap.classList.add("hidden");
|
||
}
|
||
|
||
// Инициализация элемента-списка ошибок
|
||
const list = wrap.getElementsByTagName("dl")[0];
|
||
|
||
// Удаление ошибок из прошлой генерации
|
||
if (clean) list.innerHTML = null;
|
||
|
||
for (const error in registry) {
|
||
// Генерация HTML-элементов с текстами ошибок
|
||
|
||
// Инициализация HTML-элемента текста ошибки
|
||
const samp = document.createElement("samp");
|
||
|
||
if (typeof registry[error] === "object") {
|
||
// Категория ошибок
|
||
|
||
// Проверка наличия ошибок
|
||
if (registry[error].length === 0) continue;
|
||
|
||
// Инициализация HTML-элемента-оболочки
|
||
const wrap = document.createElement("dt");
|
||
|
||
// Запись текста категории
|
||
samp.innerText = error;
|
||
|
||
// Запись HTML-элементов в список
|
||
wrap.appendChild(samp);
|
||
list.appendChild(wrap);
|
||
|
||
// Реинициализация высоты
|
||
height();
|
||
|
||
// Обработка вложенных ошибок (вход в рекурсию)
|
||
this.errors(registry[error], false);
|
||
} else {
|
||
// Текст ошибки (подразумевается)
|
||
|
||
// Инициализация HTML-элемента
|
||
const wrap = document.createElement("dd");
|
||
|
||
// Запись текста ошибки
|
||
samp.innerText = registry[error];
|
||
|
||
// Запись HTML-элемента в список
|
||
wrap.appendChild(samp);
|
||
list.appendChild(wrap);
|
||
|
||
// Реинициализация высоты
|
||
height();
|
||
}
|
||
}
|
||
|
||
if (render) {
|
||
// Запрошена отрисовка
|
||
|
||
if (list.childElementCount !== 0) {
|
||
// Найдены ошибки
|
||
|
||
// Сброс анимации
|
||
// УЛОВКА: таким образом не запускается анимация до взаимодействия с элементом (исправлял это в CSS, но не помню как)
|
||
wrap.classList.add("animation");
|
||
|
||
// Отображение
|
||
wrap.classList.remove("hidden");
|
||
} else {
|
||
// Не найдены ошибки
|
||
|
||
// Скрытие
|
||
wrap.classList.add("hidden");
|
||
}
|
||
}
|
||
|
||
return list.childElementCount === 0 ? false : true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// Инициализация ядра
|
||
window.markets.account.core = window.markets;
|
||
}
|
||
|
||
// Вызов события: "инициализировано"
|
||
document.dispatchEvent(
|
||
new CustomEvent("markets.initialized", {
|
||
detail: { markets: window.markets },
|
||
})
|
||
);
|