From f17768bb8e775e915cc68400167b7c876d699738 Mon Sep 17 00:00:00 2001 From: OkunElya Date: Sun, 1 Mar 2026 10:10:30 +1000 Subject: [PATCH] copied js files --- current_site/src/pages/table/data.js | 64 +++++++++++++++ current_site/src/pages/table/filter.js | 91 +++++++++++++++++++++ current_site/src/pages/table/main.js | 106 +++++++++++++++++++++++++ current_site/src/pages/table/sort.js | 87 ++++++++++++++++++++ current_site/src/pages/table/table.js | 50 ++++++++++++ 5 files changed, 398 insertions(+) create mode 100644 current_site/src/pages/table/data.js create mode 100644 current_site/src/pages/table/filter.js create mode 100644 current_site/src/pages/table/main.js create mode 100644 current_site/src/pages/table/sort.js create mode 100644 current_site/src/pages/table/table.js diff --git a/current_site/src/pages/table/data.js b/current_site/src/pages/table/data.js new file mode 100644 index 0000000..7b1e41d --- /dev/null +++ b/current_site/src/pages/table/data.js @@ -0,0 +1,64 @@ +buildings = [ + { "type": "DDR3", "name": "DDR3-1600-4GB-A1", "size": "4GB", "maker": "Kingston", "release": "2014-03", "price2026": 18, }, + { "type": "DDR3", "name": "DDR3-1600-8GB-A2", "size": "8GB", "maker": "Corsair", "release": "2015-06", "price2026": 26, }, + { "type": "DDR3", "name": "DDR3-1866-8GB-A3", "size": "8GB", "maker": "G.Skill", "release": "2016-02", "price2026": 29, }, + { "type": "DDR4", "name": "DDR4-2133-8GB-B1", "size": "8GB", "maker": "Crucial", "release": "2017-01", "price2026": 24, }, + { "type": "DDR4", "name": "DDR4-2400-8GB-B2", "size": "8GB", "maker": "Kingston", "release": "2017-09", "price2026": 27, }, + { "type": "DDR4", "name": "DDR4-2666-16GB-B3", "size": "16GB", "maker": "Corsair", "release": "2018-04", "price2026": 48, }, + { "type": "DDR4", "name": "DDR4-3000-16GB-B4", "size": "16GB", "maker": "G.Skill", "release": "2018-11", "price2026": 52, }, + { "type": "DDR4", "name": "DDR4-3200-16GB-B5", "size": "16GB", "maker": "HyperX", "release": "2019-03", "price2026": 55, }, + { "type": "DDR4", "name": "DDR4-3200-32GB-B6", "size": "32GB", "maker": "Crucial", "release": "2019-08", "price2026": 92, }, + { "type": "DDR4", "name": "DDR4-3600-32GB-B7", "size": "32GB", "maker": "Corsair", "release": "2020-02", "price2026": 99, }, + { "type": "DDR5", "name": "DDR5-4800-16GB-C1", "size": "16GB", "maker": "Kingston", "release": "2021-01", "price2026": 78, }, + { "type": "DDR5", "name": "DDR5-5200-16GB-C2", "size": "16GB", "maker": "Corsair", "release": "2021-06", "price2026": 84, }, + { "type": "DDR5", "name": "DDR5-5600-32GB-C3", "size": "32GB", "maker": "G.Skill", "release": "2022-02", "price2026": 145, }, + { "type": "DDR5", "name": "DDR5-6000-32GB-C4", "size": "32GB", "maker": "Crucial", "release": "2022-07", "price2026": 158, }, + { "type": "DDR5", "name": "DDR5-6400-32GB-C5", "size": "32GB", "maker": "Corsair", "release": "2023-01", "price2026": 172, }, + { "type": "DDR5", "name": "DDR5-6600-64GB-C6", "size": "64GB", "maker": "Kingston", "release": "2023-05", "price2026": 310, }, + { "type": "DDR5", "name": "DDR5-6800-64GB-C7", "size": "64GB", "maker": "G.Skill", "release": "2023-09", "price2026": 329, }, + { "type": "DDR5", "name": "DDR5-7200-64GB-C8", "size": "64GB", "maker": "Corsair", "release": "2024-02", "price2026": 355, }, + { "type": "DDR5", "name": "DDR5-7600-96GB-C9", "size": "96GB", "maker": "Crucial", "release": "2024-06", "price2026": 520, }, + { "type": "DDR5", "name": "DDR5-8000-96GB-C10", "size": "96GB", "maker": "Kingston", "release": "2024-10", "price2026": 560, }, + { "type": "LPDDR4", "name": "LP4-3200-8GB-D1", "size": "8GB", "maker": "Samsung", "release": "2019-01", "price2026": 34, }, + { "type": "LPDDR4", "name": "LP4-4266-8GB-D2", "size": "8GB", "maker": "Micron", "release": "2019-07", "price2026": 39, }, + { "type": "LPDDR5", "name": "LP5-5500-12GB-D3", "size": "12GB", "maker": "Samsung", "release": "2020-03", "price2026": 58, }, + { "type": "LPDDR5", "name": "LP5-6400-16GB-D4", "size": "16GB", "maker": "SKHynix", "release": "2021-01", "price2026": 74, }, + { "type": "LPDDR5X", "name": "LP5X-7500-24GB-D5", "size": "24GB", "maker": "Micron", "release": "2022-05", "price2026": 118, }, + { "type": "DDR4", "name": "DDR4-2666-8GB-E1", "size": "8GB", "maker": "Patriot", "release": "2018-05", "price2026": 25, }, + { "type": "DDR4", "name": "DDR4-3000-8GB-E2", "size": "8GB", "maker": "ADATA", "release": "2018-09", "price2026": 28, }, + { "type": "DDR4", "name": "DDR4-3200-8GB-E3", "size": "8GB", "maker": "TeamGroup", "release": "2019-04", "price2026": 30, }, + { "type": "DDR4", "name": "DDR4-3600-16GB-E4", "size": "16GB", "maker": "ADATA", "release": "2020-01", "price2026": 53, }, + { "type": "DDR4", "name": "DDR4-4000-16GB-E5", "size": "16GB", "maker": "Patriot", "release": "2020-06", "price2026": 61, }, + { "type": "DDR5", "name": "DDR5-5200-8GB-F1", "size": "8GB", "maker": "TeamGroup", "release": "2021-03", "price2026": 52, }, + { "type": "DDR5", "name": "DDR5-5600-16GB-F2", "size": "16GB", "maker": "ADATA", "release": "2021-10", "price2026": 88, }, + { "type": "DDR5", "name": "DDR5-6000-16GB-F3", "size": "16GB", "maker": "Patriot", "release": "2022-03", "price2026": 95, }, + { "type": "DDR5", "name": "DDR5-6400-32GB-F4", "size": "32GB", "maker": "TeamGroup", "release": "2022-09", "price2026": 168, }, + { "type": "DDR5", "name": "DDR5-7200-32GB-F5", "size": "32GB", "maker": "ADATA", "release": "2023-04", "price2026": 185, }, + { "type": "DDR3", "name": "DDR3-1333-4GB-G1", "size": "4GB", "maker": "Samsung", "release": "2013-02", "price2026": 15, }, + { "type": "DDR3", "name": "DDR3-1600-4GB-G2", "size": "4GB", "maker": "Micron", "release": "2014-08", "price2026": 17, }, + { "type": "DDR3", "name": "DDR3-1866-8GB-G3", "size": "8GB", "maker": "Samsung", "release": "2015-11", "price2026": 28, }, + { "type": "DDR5", "name": "DDR5-8400-128GB-H1", "size": "128GB", "maker": "Corsair", "release": "2025-01", "price2026": 890, }, + { "type": "DDR5", "name": "DDR5-8800-128GB-H2", "size": "128GB", "maker": "G.Skill", "release": "2025-03", "price2026": 940, }, + { "type": "DDR5", "name": "DDR5-9200-128GB-H3", "size": "128GB", "maker": "Kingston", "release": "2025-06", "price2026": 990, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X1", "size": "48GB", "maker": "Corsair", "release": "2024-01", "price2026": 210, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X2", "size": "48GB", "maker": "Kingston", "release": "2024-02", "price2026": 215, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X3", "size": "48GB", "maker": "G.Skill", "release": "2024-03", "price2026": 218, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X4", "size": "48GB", "maker": "ADATA", "release": "2024-04", "price2026": 222, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X5", "size": "48GB", "maker": "Patriot", "release": "2024-05", "price2026": 225, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X6", "size": "48GB", "maker": "TeamGroup", "release": "2024-06", "price2026": 228, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X7", "size": "48GB", "maker": "Crucial", "release": "2024-07", "price2026": 230, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X8", "size": "48GB", "maker": "Samsung", "release": "2024-08", "price2026": 235, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X9", "size": "48GB", "maker": "Micron", "release": "2024-09", "price2026": 238, }, + { "type": "DDR5", "name": "DDR5-6000-48GB-X10", "size": "48GB", "maker": "SKHynix", "release": "2024-10", "price2026": 240, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y1", "size": "64GB", "maker": "Corsair", "release": "2021-01", "price2026": 180, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y2", "size": "64GB", "maker": "Kingston", "release": "2021-02", "price2026": 182, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y3", "size": "64GB", "maker": "G.Skill", "release": "2021-03", "price2026": 185, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y4", "size": "64GB", "maker": "ADATA", "release": "2021-04", "price2026": 188, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y5", "size": "64GB", "maker": "Patriot", "release": "2021-05", "price2026": 190, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y6", "size": "64GB", "maker": "TeamGroup", "release": "2021-06", "price2026": 192, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y7", "size": "64GB", "maker": "Crucial", "release": "2021-07", "price2026": 195, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y8", "size": "64GB", "maker": "Samsung", "release": "2021-08", "price2026": 198, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y9", "size": "64GB", "maker": "Micron", "release": "2021-09", "price2026": 200, }, + { "type": "DDR4", "name": "DDR4-3200-64GB-Y10", "size": "64GB", "maker": "SKHynix", "release": "2021-10", "price2026": 205, } + +] \ No newline at end of file diff --git a/current_site/src/pages/table/filter.js b/current_site/src/pages/table/filter.js new file mode 100644 index 0000000..82c32a5 --- /dev/null +++ b/current_site/src/pages/table/filter.js @@ -0,0 +1,91 @@ +const correspond = { + "Название": "structure", + "Тип": "category", + "Страна": "country", + "Город": "city", + "Год": ["yearFrom", "yearTo"], + "Высота": ["heightFrom", "heightTo"] +} + + +/* Структура возвращаемого ассоциативного массива: +{ + input_id: input_value, + ... +} +*/ +const dataFilter = (dataForm) => { + let dictFilter = {}; + + // перебираем все элементы формы с фильтрами + for (const item of dataForm.elements) { + + // получаем значение элемента + let valInput = item.value; + + // если поле типа text - приводим его значение к нижнему регистру + if (item.type === "text") { + valInput = valInput.toLowerCase(); + } + + if (item.type === "number") { + if (valInput === "") { + if (item.id.includes("From")) { + valInput = -Infinity; + } + else { + valInput = Infinity; + } + } + else { + valInput = Number(valInput); + } + } + // формируем очередной элемент ассоциативного массива + dictFilter[item.id] = valInput; + } + return dictFilter; +} + + +// фильтрация таблицы +const filterTable = (data, idTable, dataForm) => { + + // получаем данные из полей формы + const datafilter = dataFilter(dataForm); + + // выбираем данные соответствующие фильтру и формируем таблицу из них + let tableFilter = data.filter(item => { + + /* в этой переменной будут "накапливаться" результаты сравнения данных + с параметрами фильтра */ + let result = true; + + // строка соответствует фильтру, если сравнение всех значения из input + // со значением ячейки очередной строки - истина + Object.entries(item).map(([key, val]) => { + + // текстовые поля проверяем на вхождение + if (typeof val == 'string') { + result &&= val.toLowerCase().includes(datafilter[correspond[key]]) + } + + // САМОСТОЯТЕЛЬНО проверить числовые поля на принадлежность интервалу + if (typeof val == 'number') { + result &&= datafilter[correspond[key][0]] <= Number(val) && datafilter[correspond[key][1]] >= Number(val) + } + + }); + + return result; + }); + + // САМОСТОЯТЕЛЬНО вызвать функцию, которая удаляет все строки таблицы с id=idTable + clearTable(idTable); + // показать на странице таблицу с отфильтрованными строками + createTable(tableFilter, idTable); +} + +const clearFilters = (form) => { + form.querySelectorAll(`& input[type="text"],& input[type="number"]`).forEach((elem) => elem.value = null) +} \ No newline at end of file diff --git a/current_site/src/pages/table/main.js b/current_site/src/pages/table/main.js new file mode 100644 index 0000000..fd62a53 --- /dev/null +++ b/current_site/src/pages/table/main.js @@ -0,0 +1,106 @@ +document.addEventListener("DOMContentLoaded", function () { + doInit() +}) + +function doInit() { + createTable(buildings, 'list'); + const clearFiltersButton = document.getElementById("clearFiltersButton"); + clearFiltersButton.addEventListener("click", (event) => { + clearFilters(filter); + filterTable(buildings,'list',filter) + resetSort(sort); + }) + + const applyFiltersButton = document.getElementById("applyFiltersButton"); + applyFiltersButton.addEventListener("click", (event) => { + filterTable(buildings,'list',filter) + resetSort(sort); + }) + + setSortSelects(buildings[0], sort) + + + sort.fieldsFirst.addEventListener("change",()=>{ + changeNextSelect(sort.fieldsFirst,sort.fieldsSecond.id) + }) + + sort.doSortButton.addEventListener("click", ()=>{if (!sortTable('list',sort)){ + clearTable('list'); + createTable(buildings, 'list'); + }}); + sort.resetSortButton.addEventListener("click", ()=>{resetSort(sort); + clearTable('list'); + createTable(buildings, 'list'); + }); + +} + +// формирование полей элемента списка с заданным текстом и значением + +const createOption = (str, val) => { + let item = document.createElement('option'); + item.text = str; + item.value = val; + return item; +} + +// формирование поля со списком +// параметры – массив со значениями элементов списка и элемент select + +const setSortSelect = (arr, sortSelect) => { + + // создаем OPTION Нет и добавляем ее в SELECT + sortSelect.append(createOption('Нет', 0)); + // перебираем массив со значениями опций + arr.forEach((item, index) => { + // создаем OPTION из очередного ключа и добавляем в SELECT + // значение атрибута VALUE увеличиваем на 1, так как значение 0 имеет опция Нет + sortSelect.append(createOption(item, index + 1)); + }); +} +// формируем поля со списком для многоуровневой сортировки +const setSortSelects = (data, dataForm) => { + + // выделяем ключи словаря в массив + const head = Object.keys(data); + + // находим все SELECT в форме + const allSelect = dataForm.getElementsByTagName('select'); + + for(const item of dataForm.elements){ + // формируем очередной SELECT + setSortSelect(head, item); + + // САМОСТОЯТЕЛЬНО все SELECT, кроме первого, сделать неизменяемым + } + let skipped = false + for(const elem of allSelect){ + if(!skipped){ + skipped = true; + continue; + } + elem.disabled = true; + } +} + +const changeNextSelect = (curSelect, nextSelectId) => { + + let nextSelect = document.getElementById(nextSelectId); + + nextSelect.disabled = false; + + // в следующем SELECT выводим те же option, что и в текущем + nextSelect.innerHTML = curSelect.innerHTML; + + // удаляем в следующем SELECT уже выбранную в текущем опцию + // если это не первая опция - отсутствие сортировки + if (curSelect.value != 0) { + nextSelect.remove(curSelect.value); + } else { + nextSelect.disabled = true; + } +} + +const resetSort = (form)=>{ + form.querySelectorAll(`& select`).forEach((curSelect,index) => {if(index!=0){curSelect.disabled = true} curSelect.value = 0}) +} diff --git a/current_site/src/pages/table/sort.js b/current_site/src/pages/table/sort.js new file mode 100644 index 0000000..496c9ae --- /dev/null +++ b/current_site/src/pages/table/sort.js @@ -0,0 +1,87 @@ +/*формируем массив для сортировки по двум уровням вида + [ + {column: номер столбца, по которому осуществляется сортировка, + direction: порядок сортировки (true по убыванию, false по возрастанию) + }, + ... + ] +*/ +const createSortArr = (data) => { + let sortArr = []; + + const sortSelects = data.getElementsByTagName('select'); + + for (const item of sortSelects) { + // получаем номер выбранной опции + const keySort = item.value; + // в случае, если выбрана опция Нет, заканчиваем формировать массив + if (keySort == 0) { + break; + } + // получаем порядок сортировки очередного уровня + // имя флажка сформировано как имя поля SELECT и слова Desc + const desc = document.getElementById(item.id + 'Desc').checked; + // очередной элемент массива - по какому столбцу и в каком порядке сортировать + sortArr.push( + { + column: keySort - 1, + direction: desc + } + ); + } + return sortArr; +}; + +const numberColumns = [4, 5] + +const sortTable = (idTable, formData) => { + + // формируем управляющий массив для сортировки + const sortArr = createSortArr(formData); + + // сортировать таблицу не нужно, во всех полях выбрана опция Нет + if (sortArr.length === 0) { + clearTable(idTable) + return false; + + } + //находим нужную таблицу + let table = document.getElementById(idTable); + + // преобразуем строки таблицы в массив + let rowData = Array.from(table.rows); + + // удаляем элемент с заголовками таблицы + const headerRow = rowData.shift(); + + //сортируем данные по всем уровням сортировки + rowData.sort((first, second) => { + for (let { column, direction } of sortArr) { + const firstCell = first.cells[column].innerHTML; + const secondCell = second.cells[column].innerHTML; + + // используем localeCompare для корректного сравнения + let comparison = null; + if (numberColumns.includes(column)) { + comparison = Number(firstCell) - Number(secondCell); + } + else { + comparison = firstCell.localeCompare(secondCell); + } + // учитываем направление сортировки + if (comparison !== 0) { + return (direction ? -comparison : comparison); + } + } + return 0; + }); + clearTable(idTable) + //выводим отсортированную таблицу на страницу + + let tbody = document.createElement('tbody'); + rowData.forEach(item => { + tbody.append(item); + }); + table.append(tbody); + return true; +} \ No newline at end of file diff --git a/current_site/src/pages/table/table.js b/current_site/src/pages/table/table.js new file mode 100644 index 0000000..bd8d290 --- /dev/null +++ b/current_site/src/pages/table/table.js @@ -0,0 +1,50 @@ +const createTable = (data, idTable) => { + const table = document.getElementById(idTable); + if (data.length == 0) { + return; + } + const header = Object.keys(data[0]); + + /* создание шапки таблицы */ + if (!table.firstElementChild) { + const headerRow = createHeaderRow(header); + table.append(headerRow); + } + + /* создание тела таблицы */ + const bodyRows = createBodyRows(data); + table.append(bodyRows); +}; + +const clearTable = (idTable) => { + const table = document.getElementById(idTable); + if (table.children.length > 1) { + table.removeChild(table.children[1]); + } +} + +const createHeaderRow = (headers) => { + const tr = document.createElement('tr'); + headers.forEach(header => { + const th = document.createElement('th'); + th.innerHTML = header; + tr.append(th); + }); + const thead = document.createElement('thead') + thead.appendChild(tr) + return thead; +}; + +const createBodyRows = (rows) => { + const body = document.createElement('tbody'); + rows.forEach(row => { + const rowElement = document.createElement('tr'); + for (let key in row) { + const td = document.createElement('td'); + td.innerHTML = row[key]; + rowElement.appendChild(td); + } + body.appendChild(rowElement); + }) + return body; +}