Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 09.12.2014, 21:33
Интересующийся
Отправить личное сообщение для leshiple Посмотреть профиль Найти все сообщения от leshiple
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 09.12.2014, 23:51
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,133

leshiple,
строка 140 цикл в никуда???
145 для удаления есть splice
Ответить с цитированием
  #3 (permalink)  
Старый 10.12.2014, 00:46
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 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>
Ответить с цитированием
  #4 (permalink)  
Старый 10.12.2014, 20:31
Интересующийся
Отправить личное сообщение для leshiple Посмотреть профиль Найти все сообщения от leshiple
 
Регистрация: 09.12.2014
Сообщений: 21

рони,
Спасибо за подсказку. В строках 117 и 140 были циклы в никуда. Исправил. Невнимательность и запутался в коде. В строке 145 delete заменил на splice. Теперь получается что если добавил один параметр, а потом его удалил, то уже нельзя добавить ни один параметр в этот элемент массива colParam. В строку 107 в условие if добавил || colParam[i].length == 0 и все вроде бы заработало.

bes,
Спасибо за критику. А как его сделать менее жутковатым? Каждое действие сделать отдельной функцией, и в функции show() вызывать их? Или использовать другие конструкции?

Последний раз редактировалось leshiple, 10.12.2014 в 20:53.
Ответить с цитированием
  #5 (permalink)  
Старый 10.12.2014, 21:08
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 22.03.2012
Сообщений: 3,744

Сообщение от leshiple
Спасибо за критику. А как его сделать менее жутковатым?
я про свой, добил до рабочего и пошёл спасть, твой особо не смотрел, люблю сначала повелосипедить
как сделать менее жутковатым - оптимизировать, например, у меня заменить
this.querySelector("tbody").querySelectorAll("tr");
на
this.querySelectorAll("tbody tr");


+ важна сама идея вычислений, моя чую не совсем хороша
Ответить с цитированием
  #6 (permalink)  
Старый 10.12.2014, 21:39
Интересующийся
Отправить личное сообщение для leshiple Посмотреть профиль Найти все сообщения от leshiple
 
Регистрация: 09.12.2014
Сообщений: 21

bes,
Можете свой код показать?
Ответить с цитированием
  #7 (permalink)  
Старый 10.12.2014, 21:40
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 22.03.2012
Сообщений: 3,744

Сообщение от leshiple
bes,
Можете свой код показать?
ты о чём, он весь в примере, жми на слова "Показать исходный код"
Ответить с цитированием
  #8 (permalink)  
Старый 10.12.2014, 21:46
Интересующийся
Отправить личное сообщение для leshiple Посмотреть профиль Найти все сообщения от leshiple
 
Регистрация: 09.12.2014
Сообщений: 21

bes,
Туплю. Можешь вкратце прокомментировать свой код? Я не совсем понимаю как он работает.

Последний раз редактировалось leshiple, 10.12.2014 в 21:53.
Ответить с цитированием
  #9 (permalink)  
Старый 11.12.2014, 00:34
Аватар для bes
bes bes вне форума
Профессор
Отправить личное сообщение для bes Посмотреть профиль Найти все сообщения от bes
 
Регистрация: 22.03.2012
Сообщений: 3,744

Сообщение от leshiple
Можешь вкратце прокомментировать свой код? Я не совсем понимаю как он работает.
получаются все чекнутые элементы для конкретного столбца и ассоциированные с ними значения, в цикле пробегаются все строки на предмет их скрытия/показа в зависимости от того подходят ли ячейки этой строки в этом столбце под такой фильтр
для хранения информации о том, что строка скрыта посредством фильтра в определённом столбце, для неё задаётся свойство-массив, в котором хранятся индексы этих столбцов, если индекса столбца в этом свойстве-массиве строки нет, то фильтр этого столбца на эту строку не распространяется
Ответить с цитированием
  #10 (permalink)  
Старый 11.12.2014, 01:03
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
как удалить элемент из DOM BorisBritva Events/DOM/Window 8 11.03.2013 21:17
Как удалить элемент? z700i Общие вопросы Javascript 1 30.09.2011 21:40
Как передать элемент в переменную из функции kichSman jQuery 3 12.07.2011 22:16
Как удалить элемент из дерева DOM dummer jQuery 13 16.01.2011 16:19
Как добавить элемент в XML через DOM используя PHP? bayah Серверные языки и технологии 6 11.08.2010 13:33