/
memoryspeak
/
MemorySpeakWebClient
Обзор
Документация
Войти
/
memoryspeak
/
MemorySpeakWebClient
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
static/js/SearchPage.js
225 строк
9 KB
memoryspeak
initial commit: project structure
20 ноя 2025, 21:54
20 ноя 2025, 21:54
9ddd280
Код
Авторство
О чём код?
class SearchPage { static translator = { 'en': { search: 'Search', clear: 'Clear', error: 'Error', allIsLost: 'All is lost!', noteIsNotFound: 'No records were found during the search' }, 'ru': { search: 'Поиск', clear: 'Очистить', error: 'Ошибка', allIsLost: 'Всё пропало!', noteIsNotFound: 'В ходе поиска никаких записей обнаружено не было' } }; static clearButtonOnMouseOver = false; static clearButtonOnFocus = false; static searchInputOldValue = ''; static draw() { document.body.innerHTML += ` <form id="searchForm"> <div class="d-flex justify-content-between mb-3"> <button type="submit" class="btn btn-dark mt-3 fw-bold" id="searchButton"> ${this.translator[SettingsPage.language].search} <span id="searchSpinner" class="spinner-border spinner-border-sm float-end mt-1 ms-2" role="status" aria-hidden="true" style="display:none;"></span> </button> <button type="button" class="btn btn-light mt-3 fw-bold border-dark" id="searchClearButton"> ${this.translator[SettingsPage.language].clear} </button> </div> <div class="form-floating mb-3"> <input type="text" class="form-control" id="searchInput" placeholder="🔍"> <label for="searchInput"><a>${Icons.search_16_black_svg}</a></label> <button id="searchInputClearButton" type="button" class="btn-close position-absolute" aria-label="Close" style="right:10px;top:18px;display:none;"></button> </div> <div id="searchTagsPanel" class="form-floating mb-3"></div> <div class="form-floating mb-3" id="searchResultContainter"></div> </form> `; }; static handle(urlParams, currentPageName, username, md5password) { this.saveOldValue(); // handle search form document.getElementById('searchForm').addEventListener('submit', async function(event) { event.preventDefault(); this.setOldValue(); this.disableElements(); fetch(Strings.apiUrl, { method: 'POST', headers: {'Content-Type': 'application/json;charset=utf-8'}, body: JSON.stringify({ method: (document.getElementById('searchInput').value.trim() == '') ? 'getallnotes' : 'getnote', // check for empty search field username: username, md5password: md5password, search: this.getSearchArray() }) }) .then(response => response.json()) .then(data => { if (data.exception != undefined) { Alert.show(this.translator[SettingsPage.language].error, data.exception); } else { // show cards let cardsHtml = ""; for (let i = 0; i < data.result.length; i++) { for (let j = 0; j < data.result[i].length; j++) { cardsHtml += Card.getHmtl(i, j, data.result[i][j], data.notescount); }; }; document.getElementById('searchResultContainter').innerHTML = cardsHtml; // handler cards if (cardsHtml !== "") { for (let i = 0; i < data.result.length; i++) { for (let j = 0; j < data.result[i].length; j++) { Card.handler(i, j, data.result[i][j], data.notescount, username, md5password); }; }; } else {// empty search container document.getElementById('searchResultContainter').innerHTML = ` <div class="row justify-content-center"> <div class="col-lg-8 text-center"> <div class="mb-4"> <svg width="100" height="100" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="text-dark"> <path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-width="2"/> <path d="M12 8V12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> <path d="M12 16H12.01" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> </svg> </div> <h1 class="display-4 fw-bold text-dark mb-3">404</h1> <h2 class="h3 mb-4">${this.translator[SettingsPage.language].allIsLost}</h2> <p class="lead mb-5">${this.translator[SettingsPage.language].noteIsNotFound}</p> </div> </div> `; }; }; this.enableElements(); }); }.bind(this)); // handle clear button document.getElementById('searchClearButton').addEventListener('click', function(event) { event.preventDefault(); document.getElementById('searchInput').value = ''; this.setOldValue(); document.getElementById('searchResultContainter').innerHTML = ''; }.bind(this)); // handle search input clear button document.getElementById('searchInputClearButton').addEventListener('click', function(event) { event.preventDefault(); document.getElementById('searchInput').value = ''; this.setOldValue(); }.bind(this)); document.getElementById('searchInputClearButton').addEventListener('mouseover', function(event) { event.preventDefault(); this.clearButtonOnMouseOver = true; }.bind(this)); document.getElementById('searchInputClearButton').addEventListener('mouseout', function(event) { event.preventDefault(); this.clearButtonOnMouseOver = false; if (this.clearButtonOnFocus) return; document.getElementById('searchInputClearButton').style.display = "none"; }.bind(this)); // handle search input document.getElementById('searchInput').addEventListener('focus', function(event) { event.preventDefault(); this.clearButtonOnFocus = true; document.getElementById('searchInputClearButton').style.display = "block"; }.bind(this)); document.getElementById('searchInput').addEventListener('blur', function(event) { event.preventDefault(); this.clearButtonOnFocus = false; if (this.clearButtonOnMouseOver) return; document.getElementById('searchInputClearButton').style.display = "none"; }.bind(this)); // draw tags panel elements TagsPanel.draw('search', document.getElementById('searchTagsPanel'), document.getElementById('searchInput'), username, md5password); }; static disableElements() { document.getElementById('searchInput').disabled = true; document.getElementById('searchInputClearButton').disabled = true; document.getElementById('searchButton').disabled = true; document.getElementById('searchClearButton').disabled = true; document.getElementById('searchSpinner').style.display = "block"; }; static enableElements() { document.getElementById('searchInput').disabled = false; document.getElementById('searchInputClearButton').disabled = false; document.getElementById('searchButton').disabled = false; document.getElementById('searchClearButton').disabled = false; document.getElementById('searchSpinner').style.display = "none"; }; static getSearchArray() { let searchString = document.getElementById('searchInput').value; searchString = searchString.trim(); let searchArray = searchString.split('*'); let searchArrayLength = searchArray.length; let searchArrayResult = []; for (let indexOfSearchArray = 0; indexOfSearchArray < searchArrayLength; indexOfSearchArray++) { let questionString = searchArray[indexOfSearchArray]; questionString = questionString.trim(); let questionArray = questionString.split('+'); let questionArrayLength = questionArray.length; let question = {tags: [], queries: []}; for (let indexOfQuestionArray = 0; indexOfQuestionArray < questionArrayLength; indexOfQuestionArray++) { let tagQueryString = questionArray[indexOfQuestionArray]; tagQueryString = tagQueryString.trim(); let tagQueryArray = tagQueryString.split('#'); let query = tagQueryArray.shift(); query = query.trim(); if (query != "") { question.queries.push(query); }; let tagQueryArrayLength = tagQueryArray.length; for (let indexOfTagQueryArray = 0; indexOfTagQueryArray < tagQueryArrayLength; indexOfTagQueryArray++) { let tag = tagQueryArray[indexOfTagQueryArray]; tag = tag.trim(); if (tag != "") { question.tags.push(tag); }; }; }; if (question.tags.length != 0 || question.queries.length != 0) { question.tags = Utils.getUniqueArray(question.tags); question.queries = Utils.getUniqueArray(question.queries); searchArrayResult.push(question); }; }; return searchArrayResult; }; static saveOldValue() { document.getElementById('searchInput').value = this.searchInputOldValue; }; static setOldValue() { this.searchInputOldValue = document.getElementById('searchInput').value; }; };