Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Фильтрация таблицы по селектам (https://javascript.ru/forum/dom-window/72525-filtraciya-tablicy-po-selektam.html)

Anushki 04.02.2018 18:53

Фильтрация таблицы по селектам
 
Всем привет. Подскажите как настроить фильтрацию чтобы они были привязаны к определенным tr и td. И были связанны между собой.

Например: Москва, гражданское право - должно отображать все компании по москве которые ведут дела по гражданскому праву.

<!DOCTYPE html>
<html>
<head>
<title>Фильтрация по Select'ам</title>
</head>

<body>
<table>
<thead>
<tr>
<th>Название организации</th>
<th>
<select id="a">
<option value="" selected disabled>- Выберите город -</option>
<option value="a1">Москва</option>
<option value="a2">Питер</option>
</select>
</th>
<th>
<select id="b">
<option value="" selected disabled>- Области права -</option>
<option value="b1">Гражданское право</option>
<option value="b2">Уголовное право</option>
</select>
</th>
</tr>
</thead>
<tbody id="target">
<tr>
<td>Компания 1</td>
<td name="a1">Москва</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 2</td>
<td name="a1">Москва</td>
<td name="b2">Уголовное право</td>
</tr>
<tr>
<td>Компания 3</td>
<td name="a2">Питер</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 4</td>
<td name="a2">Питер</td>
<td name="b2">Уголовное право</td>
</tr>
</tbody>
</table>

<script>

</script>
</body>
</html>

j0hnik 04.02.2018 19:49

<!DOCTYPE html>
<html>
<head>
<title>Фильтрация по Select'ам</title>
</head>

<body>
<table>
<thead>
<tr>
<th>Название организации</th>
<th>
<select id="a">
<option value="" selected disabled>- Выберите город -</option>
<option value="a1">Москва</option>
<option value="a2">Питер</option>
</select>
</th>
<th>
<select id="b">
<option value="" selected disabled>- Области права -</option>
<option value="b1">Гражданское право</option>
<option value="b2">Уголовное право</option>
</select>
</th>
</tr>
</thead>
<tbody id="target">
<tr>
<td>Компания 1</td>
<td name="a1">Москва</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 2</td>
<td name="a1">Москва</td>
<td name="b2">Уголовное право</td>
</tr>
<tr>
<td>Компания 3</td>
<td name="a2">Питер</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 4</td>
<td name="a2">Питер</td>
<td name="b2">Уголовное право</td>
</tr>
</tbody>
</table>
<script>

var tr = document.querySelectorAll('#target tr'),
sel = document.querySelectorAll('select');
sel.forEach(el=>el.onclick=e=>tr.forEach(el=>el.style.display = (el.textContent.includes(sel[0].options[sel[0].selectedIndex].textContent) || sel[0].selectedIndex==0) && (el.textContent.includes(sel[1].options[sel[1].selectedIndex].textContent) || sel[1].selectedIndex==0)?'table-row':'none'));

</script>
</body>
</html>

рони 04.02.2018 19:54

фильтрация строк таблицы
 
Anushki,

другие варианты по ссылкам (добавлен параметр исключения колонок из фильтрации )
https://javascript.ru/forum/showthread.php?p=306236
https://javascript.ru/forum/misc/522...tml#post345974

:-? :-? :-?
<!DOCTYPE HTML>
<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  body{height:1000px;background:#FF8C00;font-family:Georgia,"Times New Roman",Times,serif;letter-spacing:1px}
  .zebra select{margin:0px auto;width:100%;background:#CCC;color:#FFF}
  .zebra select option {color: #ff0;background: #000;}
  .zebra select option:nth-of-type(1) {color: #FFFFFF;background: #000;}
  .zebra td{border:1px solid #555555;color:#FFF;padding:5px;text-align:left;background:#000}
  .zebra tr:nth-child(2n) td{background:#383838}
  .zebra thead td:hover{background-image:-webkit-gradient(linear,top,bottom,color-stop(0,#E6E6FA),color-stop(1,#696969));background-image:-ms-linear-gradient(top,#E6E6FA,#696969);background-image:-o-linear-gradient(top,#E6E6FA,#696969);background-image:-moz-linear-gradient(top,#E6E6FA,#696969);background:-webkit-linear-gradient(top,#E6E6FA,#696969);background:linear-gradient(to bottom,#E6E6FA,#696969)}
  .zebra thead tr td{padding:5px;font-weight:bold;background-image:-webkit-gradient(linear,top,bottom,color-stop(0,#000000),color-stop(1,#CCCCCC));background-image:-o-linear-gradient(top,#000000,#CCCCCC);background-image:-moz-linear-gradient(top,#000000,#CCCCCC);background-image:-webkit-linear-gradient(top,#000000,#CCCCCC);background:linear-gradient(to bottom,#000000,#CCCCCC)}
  .zebra tbody tr:hover td{background-image:-webkit-gradient(linear,left,right,color-stop(0,#D2691E),color-stop(1,#DEB887));background-image:-ms-linear-gradient(left,#D2691E,#DEB887);background-image:-o-linear-gradient(left,#D2691E,#DEB887);background-image:-moz-linear-gradient(left,#D2691E,#DEB887);background:-webkit-linear-gradient(left,#D2691E,#DEB887);background:linear-gradient(to right,#D2691E,#DEB887)}
  table.zebra{border-collapse:collapse;border-spacing:0;box-shadow:0 2px 1px 5px rgba(242,242,242,0.1);width:700px;margin:0px auto}
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
  <script>
$(function () {
    $("table").tablework();
});
$.fn.tablework = function() {
    return this.each(function() {
        var $table = $(this),
            $trs = $table.find("tbody tr"),
            $thead = $table.find('thead');
        $thead.length || ($thead = $('<thead/>').prependTo($table));
        var $tr = $('<tr/>').prependTo($thead),
            hide = {};
        $("td", $trs.first()).each(function(indx, element) {
            var options = [$('<option/>', {
                    'text': 'Без выбора'
                })],
                $td = $trs.find(":nth-child(" + (indx + 1) + ")"),
                temp = {};
            $td.each(function(i, el) {
                var text = $(el).text();
                temp[text] || (
                    options.push($('<option/>', {
                        'text': text
                    })),
                    temp[text] = true
                );
            });
            var $select = $('<select/>', {
                multiple: "multiple",
                html: options,
                'change': function() {
                    var val = $(this).val() || [];
                    hide[indx] = [];
                    this.selectedIndex && $td.each(function(i, el) {
                        $.inArray($(el).text(), val) == -1 && hide[indx].push($trs[i])
                    });
                    var trs = [];
                    for (var k in hide) $.merge(trs, hide[k]);
                    $.unique(trs);
                    $trs.show();
                    $(trs).hide()

                }

            });
            $('<td/>').append($select).appendTo($tr);
        });

    });
};
</script>
</head>
<body>
<br>
<table class="zebra" >
<tbody id="target">
<tr>
<td>Компания 1</td>
<td name="a1">Москва</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 2</td>
<td name="a1">Москва</td>
<td name="b2">Уголовное право</td>
</tr>
<tr>
<td>Компания 3</td>
<td name="a2">Питер</td>
<td name="b1">Гражданское право</td>
</tr>
<tr>
<td>Компания 4</td>
<td name="a2">Питер</td>
<td name="b2">Уголовное право</td>
</tr>
</tbody>
	</table>

</body>
</html>

j0hnik 04.02.2018 20:08

рони,
Куя се ты заморочился :write: :write: :write:

Anushki 04.02.2018 20:18

Первый вариант проще.. к тому же если использовать второй вариант то нет возможности выводить дополнительные столбцы вне фильтрации.. например название компании

Anushki 04.02.2018 20:19

спасибо вам обоим ребят) вы оба мои кумиры)

рони 04.02.2018 20:31

Цитата:

Сообщение от Anushki
к тому же если использовать второй вариант то нет возможности выводить дополнительные столбцы вне фильтрации..

:-? о чём это вы?

laimas 05.02.2018 06:29

Цитата:

Сообщение от рони
другие варианты

А можно и не тасовать ячейки таблицы. При первом запросе к сортировке получить значения ячеек в объект, ключами которого являются индексы колонок, а значениями объекты - значения колонки под индексами строк как ключами. Далее сортируем объект выбранной колонки и заменяем значения ячеек таблицы значениями из этого объекта по ключам отсортированного объекта.

рони 05.02.2018 11:07

laimas,
не понял, но есть вариант где, таблица формируется из обьекта, который начале фильтруется, а на основе отфильтрованного создаются строки, есть и сортировка обьекта, вместо фильтрации, и тоже на основе отсортированного, пересоздание таблицы.
на форуме, искать только надо. :)

laimas 05.02.2018 11:19

Цитата:

Сообщение от рони
не понял

Таблица с колонками A, B, C по которым производится сортировка.

A B C
1 4 7
2 5 8
3 6 9

При запросах, если объект еще не создан, то создается:

obj = {
    'A': {'0': 1, '1': 2, '2': 3},
    'B': {'0': 4, '1': 5, '2': 6},
    'C': {'0': 7, '1': 8, '2': 9}
}


Если выбрана сортировка по колонке B, то сортируется копия объекта В, а таблица заполняется данными взятыми из объекта по ключам отсортированной копии. Например после сортировки получится так - {'2': 6, '0': 4, '1': 5}, значит таблица будет заполнена:

1 строка - значения объектов под ключами 2
2 строка - значения объектов под ключами 0
3 строка - значения объектов под ключами 1

laimas 05.02.2018 14:54

рони,
вот примерно так. Правда и некогда, и лень писать, поэтому по проще и работать будет только в браузере поддерживающем Object.entries().

<html>
<head>
<style>
table {
    border-collapse: collapse;
    margin: 20px auto;
}

td, th {
    border: 1px solid #ddd;
    padding: 5px;
}

th {
    cursor: default;
    padding: 6px;
    background: #eee;
}
</style>
</head>
<body>
<table>
<tr>
 <th id="0">Col 1</th>
 <th id="1">Col 2</th>
 <th id="2">Col 3</th>
 <th id="3">Col 4</th>
</tr>
<tr><td>7.5</td><td>abcd</td><td>120</td><td>230</td></tr>
<tr><td>.5</td><td>txt</td><td>200</td><td>500</td></tr>
<tr><td>.18</td><td>jnr</td><td>150</td><td>180</td></tr>
</table>

<script>
var obj = [], 
    dir = 0, 
    tbl = document.querySelector('table'), 
    c = tbl.rows[0].cells.length,
    m = c*tbl.rows.length;
    
sortTable();
    
tbl.querySelector("tr:first-child").addEventListener("click", function(e) {
    e = e.target || e.srcElement;
    "TH" == e.tagName && (e = Object.entries(obj[e.id]).sort(function(a, b) {
        return a[1]-b[1]
    }).map(function(a) {
        return a[0]
    }),
    sortTable(e))
});

function sortTable(e){
    for(var d=c; d<m; d++) {
        var a = d%c, b;
        a || (b = d/c);
        e ? tbl.rows[b].cells[a].textContent = obj[a][e[b-1]] 
          : (obj[a] || (obj[a] = {}), obj[a][b] = tbl.rows[b].cells[a].textContent)
    }
}
</script>
</body>
</html>


Проще и в случае просто сделать реверс сортировки, если выбирается обратный порядок у активной колонки (последняя сортировка). Можно хранить ключи сортировки и просто реверсировать их.

рони 05.02.2018 16:01

laimas,
:thanks:

рони 05.02.2018 17:33

Сортировка строк таблицы с реверсом на js
 
Цитата:

Сообщение от laimas
Можно хранить ключи сортировки и просто реверсировать их.

:write: ... (на всякий случай уточню, ключ создаётся только при первом клике, для каждой колонки, потом при кликах, работает только реверс ).


<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        table {
            border-collapse: collapse;
            margin: 20px auto;
        }

        td,
        th {
            border: 1px solid #ddd;
            padding: 5px;
        }

        th {
            cursor: default;
            padding: 6px;
            background: #eee;
        }
    </style>
    <script>
        window.addEventListener('DOMContentLoaded', function() {
            var tbl = document.querySelector("table"),
                tbody = tbl.querySelector("tbody"),
                th = [].slice.call(tbl.querySelectorAll("th"), 0),
                tr = [].slice.call(tbody.querySelectorAll("tr"), 0),
                td = [].slice.call(tbody.querySelectorAll("td"), 0),
                obj = {};
            tbl.querySelector("tr:first-child").addEventListener("click", function(e) {
                e = e.target || e.srcElement;
                if ("TH" == e.tagName) {
                    e = th.indexOf(e);
                    e = obj[e] || (obj[e] = td.filter(function(a, i) {
                        return i == e && (e += th.length);
                    }).map(function(a, i) {
                        return [i, a.textContent];
                    }).sort(function(a, b) {
                        a = a[1];
                        b = b[1];
                        return a == +a ? b - a : b > a ? 1 : b < a ? -1 : 0;
                    }));
                var f = document.createDocumentFragment();
                    e.reverse().forEach(function(a, i) {
                        f.appendChild(tr[a[0]]);
                    });
                tbody.appendChild(f);
                }
            });
        });
    </script>
</head>

<body>
    <table>
        <thead>
            <tr>
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
                <th>Col 4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>7.5</td>
                <td>abcd</td>
                <td>120</td>
                <td>230</td>
            </tr>
            <tr>
                <td>.5</td>
                <td>txt</td>
                <td>200</td>
                <td>500</td>
            </tr>
            <tr>
                <td>.18</td>
                <td>jnr</td>
                <td>150</td>
                <td>180</td>
            </tr>
        </tbody>
    </table>
</body>

</html>

laimas 05.02.2018 18:11

Цитата:

Сообщение от рони
ключ создаётся только при первом клике, для каждой колонки

Ну так о чем я и писал. Но тут уже appendChild().

рони 05.02.2018 18:22

Цитата:

Сообщение от laimas
Но тут уже appendChild().

не знаю что лучше переместить 3 строки (1 один раз, если document.createDocumentFragment() использовать, добавлено выше) или содержимое 12 ячеек поменять (что уже, вызывает вопросы, если нужна именно сортировка строк)

laimas 05.02.2018 18:27

Цитата:

Сообщение от рони
не знаю что лучше переместить 3 строки ...
или содержимое 12 ячеек поменять

Да фиг его знает. :) Я читал пост 3 темы, дошел до строки 29 кода, ну и что-то в голову стукнуло, а что если менять просто значения. Вот так и появилось, без оглядки на "зачем".

На большой таблице можно проверить что выгоднее.

PS. Хранить ключи можно только для обычной сортировки возрастание/убывание, а если потребуется пользовательская сортировка, тогда уже не получится.


Часовой пояс GMT +3, время: 21:44.