copied js files

This commit is contained in:
2026-03-01 10:10:30 +10:00
parent 4cf18c4895
commit f17768bb8e
5 changed files with 398 additions and 0 deletions

View File

@@ -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, }
]

View File

@@ -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)
}

View File

@@ -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})
}

View File

@@ -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;
}

View File

@@ -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;
}