let MenuEditor = (function() { let public = {}; /** * ID редактироуемого элемента */ let __EditItemID = -1; let __Elements = { /** * @type {HTMLDivElement} */ ButtonMenuAdd: undefined, /** * @type {HTMLDivElement} */ ButtonMenuTopAdd: undefined, /** * @type {HTMLDivElement} */ ButtonMenuEdit: undefined, /** * @type {HTMLDivElement} */ ButtonMenuTopEdit: undefined, }; let __CurrentCategory = undefined; __Elements.ButtonMenuAdd = document.querySelector("#CreateMainMenuItem"); if (!__Elements.ButtonMenuAdd) { Messenger.Show("Некоторые элементы не были найдены"); return undefined; } __Elements.ButtonMenuAdd.onclick = addItemModal.bind(__Elements.ButtonMenuAdd, MENU_CATEGORY.MAIN); __Elements.ButtonMenuTopAdd = document.querySelector("#CreateTopMenuItem"); if (!__Elements.ButtonMenuTopAdd) { Messenger.Show("Некоторые элементы не были найдены"); return undefined; } __Elements.ButtonMenuTopAdd.onclick = addItemModal.bind(__Elements.ButtonMenuTopAdd, MENU_CATEGORY.TOP); __Elements.ButtonMenuEdit = document.querySelector("#EditMainMenuItem"); if (!__Elements.ButtonMenuEdit) { Messenger.Show("Некоторые элементы не были найдены"); return undefined; } __Elements.ButtonMenuEdit.onclick = addControls.bind(__Elements.ButtonMenuEdit, MENU_CATEGORY.MAIN); __Elements.ButtonMenuTopEdit = document.querySelector("#EditTopMenuItem"); if (!__Elements.ButtonMenuTopEdit) { Messenger.Show("Некоторые элементы не были найдены"); return undefined; } __Elements.ButtonMenuTopEdit.onclick = addControls.bind(__Elements.ButtonMenuTopEdit, MENU_CATEGORY.TOP); function getMenu() { XHR.POST(replaceMenu, "/menu-get"); } function replaceMenu(result) { if (result && "Menu" in result) { Main.ReplaceMenu(result.Menu); } else { Messenger.Show("Обновленное меню не было получено :("); } } function addItem() { /** * @type {HTMLDivElement} */ let tree = document.querySelector("#NewItemParent"); /** * @type {HTMLInputElement} */ let caption = document.querySelector("#NewItemCaption"); /** * @type {HTMLInputElement} */ let link = document.querySelector("#NewItemLink"); let isLink = document.querySelector("#NewItemIsLink"); if (!caption || !link || !isLink || !tree) { Messenger.Show("Необходимые элементы не были найдены. Перезагрузите страницу и повторите попытку"); return; } if (caption.value.length < 2) { Messenger.Show("Некорректный заголовок"); return; } if (isLink.checked) { if (link.value.length < 1) { Messenger.Show("Некорректная ссылка"); return; } } let parent = tree.querySelector(".branch.selected"); if (parent) { parent = { Int32: (parent.dataset.id * 1), Valid: true, }; } else { parent = { Valid: false, Int32: 0, } } let data = { Parent: parent, Caption: caption.value, Link: { Valid: isLink.checked, String: link.value, }, }; XHR.POST( function (result) { if (result && "Error" in result && result.Error) { Messenger.Show(result.Error); } else { Messenger.Show("Пункт меню был успешно добавлен"); getMenu(); } }, "/menu-insert-item/"+__CurrentCategory, data ); this.closest(".modal").querySelector(".close").click(); } function editItem() { /** * @type {HTMLInputElement} */ let caption = document.querySelector("#EditItemCaption"); /** * @type {HTMLInputElement} */ let link = document.querySelector("#EditItemLink"); let isLink = document.querySelector("#EditItemIsLink"); if (!caption || !link || !isLink) { Messenger.Show("Необходимые элементы не были найдены. Перезагрузите страницу и повторите попытку"); return; } if (caption.value.length < 2) { Messenger.Show("Некорректный заголовок"); return; } if (isLink.checked) { if (link.value.length < 2) { Messenger.Show("Некорректная ссылка"); return; } } let data = { ID: __EditItemID, Caption: caption.value, Link: { Valid: isLink.checked, String: link.value, }, }; XHR.POST( function (result) { if (result && "Error" in result && result.Error) { Messenger.Show(result.Error); } else { Messenger.Show("Пункт меню был успешно изменён"); caption.value = ""; link.value = ""; isLink.checked = false; getMenu(); } }, "/menu-update-item", data ); this.closest(".modal").querySelector(".close").click(); } function deleteItem(event) { let data = { ID: __EditItemID }; XHR.POST( function (result) { if (result && "Error" in result && result.Error) { Messenger.Show(result.Error); } else { Messenger.Show("Пункт меню был успешно удалён"); getMenu(); } }, "/menu-delete-item", data ); this.closest(".modal").querySelector(".close").click(); } /** * Добавить элементы управления (редактировать, удалить) на каждый пункт меню */ function addControls(category) { __CurrentCategory = category; let query = ""; if (__CurrentCategory === MENU_CATEGORY.MAIN) { query = ".menu .text[data-id]"; } else { if (__CurrentCategory === MENU_CATEGORY.TOP) { query = "nav .text[data-id]"; } else { return; } } let items = document.querySelectorAll(query); for (const item of items) { let edit = document.createElement("i"), textContent = document.createElement("span"); textContent.textContent = item.textContent; item.textContent = null; edit.className = "fas fa-pen"; edit.onclick = editItemModal; item.append(textContent, edit); } } /** * Открыть окно для редактирования пункта меню * * @param {MouseEvent} event */ function editItemModal(event) { event.stopPropagation(); event.preventDefault(); let body = document.createElement("div"), inputCaption = document.createElement("input"), inputLink = document.createElement("input"), button = document.createElement("button"), buttonDel = document.createElement("button"), buttonGroup = document.createElement("div"), inputCheckbox = Controls.CreateCheckbox("Сделать ссылкой?", "EditItemIsLink", null, toggleIsLink), inputCheckboxActive = Controls.CreateCheckbox("Активный пункт?", "EditItemIsActive", null, toggleIsActive); let item = this.parentElement; item.classList.add("edit"); __EditItemID = item.dataset.id * 1; inputCaption.type = "text"; inputCaption.placeholder = "Заголовок пункта"; inputCaption.id = "EditItemCaption"; inputCaption.value = item.firstChild.textContent; inputLink.type = "text"; inputLink.placeholder = "Ссылка на материал или внешний URL"; inputLink.id = "EditItemLink"; if (item.dataset.link) { if (item.dataset.link == "none") { inputLink.disabled = true; } else { inputCheckbox.querySelector("input").checked = true; if (item.dataset.link == "url") { inputLink.value = item.href; } else { inputLink.value = item.dataset.link; } } } if (item.parentElement.matches(".hide")) { inputCheckboxActive.querySelector("input").checked = false; } else { inputCheckboxActive.querySelector("input").checked = true; } button.onclick = editItem; button.textContent = "Изменить"; buttonDel.onclick = deleteItem; buttonDel.textContent = "Удалить"; buttonGroup.append(button, buttonDel); buttonGroup.className = "button-group"; body.append(inputCaption, inputCheckboxActive, inputCheckbox, inputLink, buttonGroup); Modal.Create("Редактировать пункт в меню", body, cancelEdit); } function cancelEdit() { if (__EditItemID > -1) { let editableItem = document.querySelector(`.text[data-id="${__EditItemID}"`); if (editableItem) { editableItem.classList.remove("edit"); } __EditItemID = -1; } } /** * Создать мадальное окно с указанным типом * * @param {MENU_CATEGORY} category категория меню */ function addItemModal(category) { __CurrentCategory = category; let body = document.createElement("div"), menuTreeLabel = document.createElement("label"), menuTree = document.createElement("div"), inputCaption = document.createElement("input"), inputLink = document.createElement("input"), button = document.createElement("button"), buttonGroup = document.createElement("div"), inputCheckbox = Controls.CreateCheckbox("Сделать ссылкой?", "NewItemIsLink", null, toggleIsLink); menuTreeLabel.textContent = "Родительский элемент:"; menuTree.className = "menu-tree"; menuTree.id = "NewItemParent"; inputCaption.type = "text"; inputCaption.placeholder = "Заголовок пункта"; inputCaption.id = "NewItemCaption"; inputLink.type = "text"; inputLink.placeholder = "Ссылка на материал или внешний URL"; inputLink.id = "NewItemLink"; inputLink.disabled = true; button.onclick = addItem; button.textContent = "Добавить"; buttonGroup.append(button); buttonGroup.className = "button-group"; body.append(menuTreeLabel, menuTree, inputCaption, inputCheckbox, inputLink, buttonGroup); getMenuSource(menuTree); Modal.Create("Добавить новый пункт в меню", body); } function toggleIsLink() { /** * @type {HTMLInputElement} */ let input = this.parentElement.nextElementSibling; if (input) { input.disabled = !this.checked; if (input.disabled) { input.value = ""; } } } function getMenuSource(elem) { XHR.POST(postGetMenuSource, "/menu-get-source/"+__CurrentCategory, {}, elem); } function postGetMenuSource(result, elem) { if (!result || !elem) { return; } if (!"Menu" in result) { Messenger.Show("Нет данных меню"); return; } let tree = __init__Tree(); buildTree(result.Menu, tree); tree.SetTo(elem); } /** * * @param {[Object]} root * @param {Object} tree */ function buildTree(root, tree, branch) { for (let item of root) { let newBranch = tree.AddBranch(item.Caption, {id: item.ID}, branch); if (item.Rows !== null) { buildTree(item.Rows, tree, newBranch); } } } /** * * @param {MouseEvent} event */ function toggleIsActive(event) { if (__EditItemID < 0) { event.preventDefault(); return; } let data = { ID: __EditItemID, Active: this.checked, }; XHR.POST( function (result) { if (result && "Error" in result && result.Error) { Messenger.Show(result.Error); } else { Messenger.Show("Статус пункта меню был успешно изменён"); getMenu(); } }, "/menu-update-item-active", data ); this.closest(".modal").querySelector(".close").click(); } return public; })();