09.12.2014, 21:33
|
Интересующийся
|
|
Регистрация: 09.12.2014
Сообщений: 21
|
|
Фильтр таблицы. Как удалить элемент из массива?
Изучаю JavaScript.
Решил создать фильтр для таблицы, неопределенного размера (наподобие того что есть в Excel).
Не удается удалить параметр из массива.
После первого клика по фильтру, параметр успешно добавляется в массив (добавление параметров вроде бы работает), второй щелчок по этому же параметру удаляет его из массива, но остается длинна i-того массива равной единице. Последующие щелчки в этом же столбце творят ужас. Не пойму что я делаю не правильно. Подскажите пожалуйста как решить данную проблему.
Вот сам код, который подробно прокомментировал:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head lang="ru">
<meta charset="UTF-8">
<title>First</title>
<link rel="stylesheet" href="style.css"/>
<style>
table {
border-collapse: collapse;
font-family: "Arial", sans-serif;
font-size: 0.9em;
margin: 50px;
position: relative;
}
td {
border: 1px solid black;
width: 150px;
padding: 5px;
}
thead {
background-color: coral;
font-weight: bold;
}
.select-group {
font-weight: normal;
font-style: italic;
display: none;
position: absolute;
background-color: burlywood;
width: 150px;
padding: 5px;
border: 1px solid black;
top: 33px;
}
td:hover > .select-group {
display: block;
}
thead:hover {
cursor: pointer;
}
.second-name {
left: 0;
}
.first-name {
left: 161px;
}
.otch {
left: 322px;
}
.select-item {
padding: 5px 0;
border-bottom: 1px solid black;
}
.select-item:hover {
background-color: darkkhaki;
}
span {
background-color: #fff;
padding: 3px;
width: 144px;
display: block;
}
label {
display: block;
}
</style>
<script type="text/javascript">
var selectGroup = document.getElementsByClassName("select-group"),
tr = document.querySelectorAll("tbody tr"),
tHead = document.getElementsByTagName("thead"),
colParam = new Array(selectGroup.length),// массив в котором будут храниться параметры выбора
numParam = 0;
function show() {
// переберем блоки с input'ами
for (var i = 0; i < selectGroup.length; i++) {
// теперь переберем сами input'ы в этих блоках
for (var j = 0; j < selectGroup[i].querySelectorAll("input").length; j++) {
//создадим переменную в которой будет хранится один input
var hasChecked = selectGroup[i].querySelectorAll("input")[j];
//если input выбран
if (hasChecked.checked) {
то если массив с параметрами пуст
if (colParam[i] == undefined || colParam[i].length == 0) {
/*то создадим i-тым (i - это номер столбца) элементом массив
в который занесем значение выбранного input'а*/
colParam[i] = new Array(hasChecked.value);
} else {
//если массив с параметрами не пуст, то переберем его
for (var r = 0; r < colParam[i].length; r++) {
if (colParam[i][r] != hasChecked.value) {
/* r - номер параметрам в i-том столбце
и если значения выбранного input'а нет в
массиве с параметрами, то заносим это значение*/
colParam[i].push(hasChecked.value);
} else {
break;
}
}
}
} else {
/*вот тут у меня и начинается беда
Проверяем не пуст ли массив с параметрами
*/
if (colParam[i] != undefined) {
//если не пуст то переберем все его значения
for (var v = 0; v < colParam[i].length; v++) {
if (colParam[i][numParam] == hasChecked.value) {
// и если значение есть в массиве, то удаляем его
colParam[i].splice(v, 1);
} else {
break;
}
}
} else {
break;
}
}
}
}
}
//Функция запускается по клику на шапке таблицы
tHead[0].addEventListener("click", show);
</script>
</head>
<body>
<table>
<thead>
<tr>
<td>
<span>Фамилия</span>
<div class="select-group second-name">
<label><input class="select-item col11" type="checkbox" value="Епихин">Епихин</label>
<label><input class="select-item col11" type="checkbox" value="Буртовой">Буртовой</label>
</div>
</td>
<td>
<span>Имя</span>
<div class="select-group first-name">
<label><input class="select-item col11" type="checkbox" value="Александр">Александр</label>
<label><input class="select-item col11" type="checkbox" value="Евгений">Евгений</label>
<label><input class="select-item col11" type="checkbox" value="Сергей">Сергей</label>
</div>
</td>
<td>
<span>Отчество</span>
<div class="select-group otch">
<label><input class="select-item col11" type="checkbox" value="Валерьевич">Валерьевич</label>
<label><input class="select-item col11" type="checkbox" value="Олегович">Олегович</label>
<label><input class="select-item col11" type="checkbox" value="Анатольевич">Анатольевич</label>
</div>
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Евгений</td>
<td class="col3">Олегович</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Анатольевич</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Сергей</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Александр</td>
<td class="col3">Олегович</td>
</tr>
</tbody>
</table>
</body>
</html>
P.S. Если не правильно или неудобно оформил тему то скажите как исправить.
Последний раз редактировалось leshiple, 10.12.2014 в 20:51.
|
|
09.12.2014, 23:51
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,133
|
|
leshiple,
строка 140 цикл в никуда???
145 для удаления есть splice
|
|
10.12.2014, 00:46
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от leshiple
|
P.S. Если не правильно или неудобно оформил тему то скажите как исправить.
|
добавь все атрибуты [ html run height=500 hide]
мой вариант на сон грядущий, код жутковат, но вроде бы работает
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head lang="ru">
<meta charset="UTF-8">
<title>First</title>
<link rel="stylesheet" href="style.css"/>
<style>
table {
border-collapse: collapse;
font-family: "Arial", sans-serif;
font-size: 0.9em;
margin: 50px;
position: relative;
}
td {
border: 1px solid black;
width: 150px;
padding: 5px;
}
thead {
background-color: coral;
font-weight: bold;
}
.select-group {
font-weight: normal;
font-style: italic;
display: none;
position: absolute;
background-color: burlywood;
width: 150px;
padding: 5px;
border: 1px solid black;
top: 33px;
}
td:hover > .select-group {
display: block;
}
thead:hover {
cursor: pointer;
}
.second-name {
left: 0;
}
.first-name {
left: 161px;
}
.otch {
left: 322px;
}
.select-item {
padding: 5px 0;
border-bottom: 1px solid black;
}
.select-item:hover {
background-color: darkkhaki;
}
span {
background-color: #fff;
padding: 3px;
width: 144px;
display: block;
}
label {
display: block;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
function closest (elem, selector) {
while (elem && elem.tagName != selector) {
elem = elem.parentNode;
}
return elem;
}
Array.prototype.map.call(document.querySelector("table").querySelectorAll("input[type=checkbox"), function (inp) {
inp.checked = true;
});
document.querySelector("table").addEventListener("click", function (event) {
var target = event.target;
if ( target.type && target.type == "checkbox" ) {
var td = closest(target, "TD");
var index = td.cellIndex;
var inps = td.querySelectorAll("input:checked");
var vals = Array.prototype.map.call(inps, function (inp) {
return inp.value;
});
var trs = this.querySelector("tbody").querySelectorAll("tr");
Array.prototype.map.call(trs, function (tr ) {
if ( !tr.isHiddenByCol ) tr.isHiddenByCol = [];
if ( vals.indexOf(tr.cells[index].innerHTML) == -1 ) {
tr.style.display = "none";
if ( tr.isHiddenByCol.indexOf(index) == -1 )
tr.isHiddenByCol.push(index);
} else if ( tr.isHiddenByCol.indexOf(index) != -1 ) {
tr.isHiddenByCol.splice(tr.isHiddenByCol.indexOf(index), 1);
if ( tr.isHiddenByCol.length == 0 ) {
tr.style.display = "";
}
}
});
}
});
});
</script>
</head>
<body>
<table>
<thead>
<tr>
<td>
<span>Фамилия</span>
<div class="select-group second-name">
<label><input class="select-item col11" type="checkbox" value="Епихин">Епихин</label>
<label><input class="select-item col11" type="checkbox" value="Буртовой">Буртовой</label>
</div>
</td>
<td>
<span>Имя</span>
<div class="select-group first-name">
<label><input class="select-item col11" type="checkbox" value="Александр">Александр</label>
<label><input class="select-item col11" type="checkbox" value="Евгений">Евгений</label>
<label><input class="select-item col11" type="checkbox" value="Сергей">Сергей</label>
</div>
</td>
<td>
<span>Отчество</span>
<div class="select-group otch">
<label><input class="select-item col11" type="checkbox" value="Валерьевич">Валерьевич</label>
<label><input class="select-item col11" type="checkbox" value="Олегович">Олегович</label>
<label><input class="select-item col11" type="checkbox" value="Анатольевич">Анатольевич</label>
</div>
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Евгений</td>
<td class="col3">Олегович</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Анатольевич</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Сергей</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Александр</td>
<td class="col3">Олегович</td>
</tr>
</tbody>
</table>
</body>
</html>
|
|
10.12.2014, 20:31
|
Интересующийся
|
|
Регистрация: 09.12.2014
Сообщений: 21
|
|
рони,
Спасибо за подсказку. В строках 117 и 140 были циклы в никуда. Исправил. Невнимательность и запутался в коде. В строке 145 delete заменил на splice. Теперь получается что если добавил один параметр, а потом его удалил, то уже нельзя добавить ни один параметр в этот элемент массива colParam. В строку 107 в условие if добавил || colParam[i].length == 0 и все вроде бы заработало.
bes,
Спасибо за критику. А как его сделать менее жутковатым? Каждое действие сделать отдельной функцией, и в функции show() вызывать их? Или использовать другие конструкции?
Последний раз редактировалось leshiple, 10.12.2014 в 20:53.
|
|
10.12.2014, 21:08
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от leshiple
|
Спасибо за критику. А как его сделать менее жутковатым?
|
я про свой, добил до рабочего и пошёл спасть, твой особо не смотрел, люблю сначала повелосипедить
как сделать менее жутковатым - оптимизировать, например, у меня заменить
this.querySelector("tbody").querySelectorAll("tr");
на
this.querySelectorAll("tbody tr");
+ важна сама идея вычислений, моя чую не совсем хороша
|
|
10.12.2014, 21:39
|
Интересующийся
|
|
Регистрация: 09.12.2014
Сообщений: 21
|
|
bes,
Можете свой код показать?
|
|
10.12.2014, 21:40
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от leshiple
|
bes,
Можете свой код показать?
|
ты о чём, он весь в примере, жми на слова "Показать исходный код"
|
|
10.12.2014, 21:46
|
Интересующийся
|
|
Регистрация: 09.12.2014
Сообщений: 21
|
|
bes,
Туплю. Можешь вкратце прокомментировать свой код? Я не совсем понимаю как он работает.
Последний раз редактировалось leshiple, 10.12.2014 в 21:53.
|
|
11.12.2014, 00:34
|
|
Профессор
|
|
Регистрация: 22.03.2012
Сообщений: 3,744
|
|
Сообщение от leshiple
|
Можешь вкратце прокомментировать свой код? Я не совсем понимаю как он работает.
|
получаются все чекнутые элементы для конкретного столбца и ассоциированные с ними значения, в цикле пробегаются все строки на предмет их скрытия/показа в зависимости от того подходят ли ячейки этой строки в этом столбце под такой фильтр
для хранения информации о том, что строка скрыта посредством фильтра в определённом столбце, для неё задаётся свойство-массив, в котором хранятся индексы этих столбцов, если индекса столбца в этом свойстве-массиве строки нет, то фильтр этого столбца на эту строку не распространяется
|
|
11.12.2014, 01:03
|
|
Профессор
|
|
Регистрация: 13.03.2013
Сообщений: 1,572
|
|
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/html">
<head lang="ru">
<meta charset="UTF-8">
<title>First</title>
<style>
table {
border-collapse: collapse;
font-family:"Arial", sans-serif;
font-size: 0.9em;
margin: 50px;
position: relative;
}
td {
border: 1px solid black;
width: 150px;
padding: 5px;
}
thead {
background-color: coral;
font-weight: bold;
}
.select-group {
font-weight: normal;
font-style: italic;
display: none;
position: absolute;
background-color: burlywood;
width: 150px;
padding: 5px;
border: 1px solid black;
top: 33px;
}
td:hover > .select-group {
display: block;
}
thead:hover {
cursor: pointer;
}
.second-name {
left: 0;
}
.first-name {
left: 161px;
}
.otch {
left: 322px;
}
.select-item {
padding: 5px 0;
border-bottom: 1px solid black;
}
.select-item:hover {
background-color: darkkhaki;
}
span {
background-color: #fff;
padding: 3px;
width: 144px;
display: block;
}
label {
display: block;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<td>
<span>Фамилия</span>
<div class="select-group second-name">
<label>
<input class="select-item col11" type="checkbox" value="Епихин" data-type="surname">Епихин</label>
<label>
<input class="select-item col11" type="checkbox" value="Буртовой" data-type="surname">Буртовой</label>
</div>
</td>
<td>
<span>Имя</span>
<div class="select-group first-name">
<label>
<input class="select-item col11" type="checkbox" value="Александр" data-type="name">Александр</label>
<label>
<input class="select-item col11" type="checkbox" value="Евгений" data-type="name">Евгений</label>
<label>
<input class="select-item col11" type="checkbox" value="Сергей" data-type="name">Сергей</label>
</div>
</td>
<td>
<span>Отчество</span>
<div class="select-group otch">
<label>
<input class="select-item col11" type="checkbox" value="Валерьевич" data-type="middle">Валерьевич</label>
<label>
<input class="select-item col11" type="checkbox" value="Олегович" data-type="middle">Олегович</label>
<label>
<input class="select-item col11" type="checkbox" value="Анатольевич" data-type="middle">Анатольевич</label>
</div>
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Евгений</td>
<td class="col3">Олегович</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Александр</td>
<td class="col3">Анатольевич</td>
</tr>
<tr>
<td class="col1">Епихин</td>
<td class="col2">Сергей</td>
<td class="col3">Валерьевич</td>
</tr>
<tr>
<td class="col1">Буртовой</td>
<td class="col2">Александр</td>
<td class="col3">Олегович</td>
</tr>
</tbody>
</table>
<script>
window.onload = function () {
var cache = {
surname: {},
name: {},
middle: {}
},
s, n, m, tr, tbl = document.querySelector("table"),
dataTr = tbl.querySelectorAll("tbody tr");
for (var i = 0; i < dataTr.length; ++i) {
tr = dataTr[i];
s = tr.cells[0].innerHTML;
n = tr.cells[1].innerHTML;
m = tr.cells[2].innerHTML;
if (!cache.surname.hasOwnProperty(s)) {
cache.surname[s] = [];
tbl.querySelector("input[data-type=surname][value='" + s + "']").checked = true;
}
if (!cache.name.hasOwnProperty(n)) {
cache.name[n] = [];
tbl.querySelector("input[data-type=name][value='" + n + "']").checked = true;
}
if (!cache.middle.hasOwnProperty(m)) {
cache.middle[m] = [];
tbl.querySelector("input[data-type=middle][value='" + m + "']").checked = true;
}
cache.surname[s].push(tr);
cache.name[n].push(tr);
cache.middle[m].push(tr);
}
tbl.onclick = function (e) {
var el = e ? e.target : window.event.srcElement;
if (el.tagName != "INPUT" || el.type != 'checkbox') return;
var type = cache[el.getAttribute('data-type')][el.value];
for (var i = 0; i < type.length; ++i) {
type[i].style.display = el.checked ? "" : "none";
}
}
};
</script>
</body>
</html>
еще вариант, но и он далек от идеала. Не совсем понятна логика. Переключение Имя,фамилия, отчество. Какой порядок должен быть
Последний раз редактировалось Vlasenko Fedor, 11.12.2014 в 01:27.
|
|
|
|