Сортировка значений в таблице

Как реализовать сортировку данных в HTML-таблице на сайте.

Задача: сделать так, чтобы в таблице при клике по ячейке таблицы с названием колонки, происходила сортировка данных по возрастанию и убыванию.

Вполне решаемая задача, для реализации которой нам понадобится JavaScript.

Демо с сортировкой в таблице

Покликайте по заголовкам колонок:

id Имя Страна Баланс
1 Радж Индия 135
2 Батыр Монголия 0
3 Lisa Англия 65
4 Хавьер Аргентина -43
5 Donald США 350
6 Angela Германия 350.2

Код HTML

<table class="table_sort">
    <thead>
        <tr>
            <th>id</th>
            <th>Имя</th>
            <th>Страна</th>
            <th>Баланс</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>Радж</td>
            <td>Индия</td>
            <td>135</td>
        </tr>
        <tr>
            <td>2</td>
            <td>Батыр</td>
            <td>Монголия</td>
            <td>0</td>
        </tr>
        <tr>
            <td>3</td>
            <td>Lisa</td>
            <td>Англия</td>
            <td>65</td>
        </tr>
        <tr>
            <td>4</td>
            <td>Мутумба</td>
            <td>Зимбабве</td>
            <td>-43</td>
        </tr>
        <tr>
            <td>5</td>
            <td>Donald</td>
            <td>США</td>
            <td>350</td>
        </tr>
        <tr>
            <td>6</td>
            <td>Angela</td>
            <td>Германия</td>
            <td>37</td>
        </tr>
    </tbody>
</table>

Обратите внимание, что у таблицы в открывающем теге table стоит class="table_sort". Именно этот класс для js-скрипта является индикатором того, что таблица должна быть сортируемой.

Таблица имеет структуру по HTML 5. В её структуре обязательно должны быть thead и tbody. Присутствие в структуре таблице tfoot необязательно, но возможно. tfoot не сломает сортировку таблицы.

Javascript

Скрипт сортирующий таблицу:

document.addEventListener('DOMContentLoaded', () => {

    const getSort = ({ target }) => {
        const order = (target.dataset.order = -(target.dataset.order || -1));
        const index = [...target.parentNode.cells].indexOf(target);
        const collator = new Intl.Collator(['en', 'ru'], { numeric: true });
        const comparator = (index, order) => (a, b) => order * collator.compare(
            a.children[index].innerHTML,
            b.children[index].innerHTML
        );
        
        for(const tBody of target.closest('table').tBodies)
            tBody.append(...[...tBody.rows].sort(comparator(index, order)));

        for(const cell of target.parentNode.cells)
            cell.classList.toggle('sorted', cell === target);
    };
    
    document.querySelectorAll('.table_sort thead').forEach(tableTH => tableTH.addEventListener('click', () => getSort(event)));
    
});

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

Повторю, что скрипт находит только те таблицы, у которых стоит class="table_sort".

Если данный скрит вставляете в HTML, через виджеты или модули, то не забудьте его обернуть тегами script

<script>
    // тут код скрипта
</script>

Стили CSS

Так же выкладываю стили, которые я написал для демо-таблицы. Их можно взять за основу и подправить или дополнить под ваши нужды:

.table_sort table {
    border-collapse: collapse;
}

.table_sort th {
    color: #ffebcd;
    background: #008b8b;
    cursor: pointer;
}

.table_sort td,
.table_sort th {
    width: 150px;
    height: 40px;
    text-align: center;
    border: 2px solid #846868;
}

.table_sort tbody tr:nth-child(even) {
    background: #e3e3e3;
}

th.sorted[data-order="1"],
th.sorted[data-order="-1"] {
    position: relative;
}

th.sorted[data-order="1"]::after,
th.sorted[data-order="-1"]::after {
    right: 8px;
    position: absolute;
}

th.sorted[data-order="-1"]::after {
	content: "▼"
}

th.sorted[data-order="1"]::after {
	content: "▲"
}
Таблица в HTML 5
Таблица в HTML 5 Структура и тэги таблицы согласно стандарту в HTML-5: заголовок таблицы, шапка и футер, тело таблицы, ряды и ячейки. Объединение ячеек таблицы.
Таблица с липкой шапкой
Таблица с липкой шапкой Инструкция как сделать липкую шапку таблицы без использования JavaScript и без jQuery. Фиксированные заголовки таблицы сделанные на чистом CSS.
Комментарии 43
Алина
Алина
13:15 27.10.2019 #

Большое спасибо за отличный способ! Я заметила, что если в ячейке заголовка столбца - две строки, то треугольник (наверх или вниз) выравнивается по вертикали относительно нижней строки, а очень хотелось бы, чтобы выравнивание по вертикали было по центру ячейки. Подскажите, пожалуйста, как реализовать выравнивание треугольника по центру ячейки (по вертикали).

Спасибо!

Admin
Admin
13:32 27.10.2019 #

В моём примере у этого треугольничка абсолютное позиционирование. Собственно, его двигать можно при помощи следующих css-свойств: top, right, bottom и left.

Вот к этому фрагменту css:

th.sorted[data-order="1"]::after,th.sorted[data-order="-1"]::after {
    right: 8px;
    position: absolute;
}

допишите свойство top и подберите значение в пикселях. Получится примерно так:

th.sorted[data-order="1"]::after,th.sorted[data-order="-1"]::after {
    top: 15px;
    right: 8px;
    position: absolute;
}
Алина
Алина
15:43 27.10.2019 #

Большое спасибо!

К сожалению, если в нескольких разных таблицах в строке thead - разное количество текстовых строчек (например, в первой таблице заголовки столбцов состоят из одного слова; а во второй таблице в заголовках столбцов много слов, поэтому получается 2-3 строки), то настройки, подходящие для невысоких строк (напр., top: 1px;) не будут подходить для более высоких строк (там, например, нужно было бы: top: 15px;).

Подскажите, пожалуйста, может быть, есть универсальный способ, чтобы вертикальное положение треугольничка было одинаковым, несмотря на то, сколько текстовых строчек в строке заголовка? Спасибо!

Admin
Admin
20:37 27.10.2019 #

Подскажите, пожалуйста, может быть, есть универсальный способ, чтобы вертикальное положение треугольничка было одинаковым, несмотря на то, сколько текстовых строчек в строке заголовка?

Чтобы в такой ситуации отцентрировать, можно top в процентах указать, высчитывая откат на смещение через calc:

top: calc(50% - 8px);

где 8px - это значение половины высоты шрифта, то есть значение font-size делим на 2. Если у меня размер шрифта 16px - получается в calc берём 8px.

Или более универсально, чтобы от размера шрифта не зависеть, можно сделать так:

top: 50%;
transform: translate(0, -50%);
Алина
Алина
09:17 28.10.2019 #

Или более универсально, чтобы от размера шрифта не зависеть, можно сделать так:

top: 50%;
transform: translate(0, -50%);

Большое спасибо! Попробовала этот способ, всё отлично работает!

vianna
vianna
11:54 23.12.2019 #

Sos скрипт не работает в Mozilla. Что мне нужно сделать?

Admin
Admin
12:11 23.12.2019 #

Я в мазиле вот открыл и у меня демка на этой странице работает. Может у вас мазила давно не обновлялась? Типа стоит версия браузера которая не поддерживает ES6.

Можно попробовать скрипт через бабель прогнать чтобы в старых браузерах работало.

Попробуйте так:

"use strict";

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }

function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }

document.addEventListener('DOMContentLoaded', function () {
  var getSort = function getSort(_ref) {
    var target = _ref.target;
    var order = target.dataset.order = -(target.dataset.order || -1);

    var index = _toConsumableArray(target.parentNode.cells).indexOf(target);

    var collator = new Intl.Collator(['en', 'ru'], {
      numeric: true
    });

    var comparator = function comparator(index, order) {
      return function (a, b) {
        return order * collator.compare(a.children[index].innerHTML, b.children[index].innerHTML);
      };
    };

    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;

    try {
      for (var _iterator = target.closest('table').tBodies[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var tBody = _step.value;
        tBody.append.apply(tBody, _toConsumableArray(_toConsumableArray(tBody.rows).sort(comparator(index, order))));
      }
    } catch (err) {
      _didIteratorError = true;
      _iteratorError = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion && _iterator.return != null) {
          _iterator.return();
        }
      } finally {
        if (_didIteratorError) {
          throw _iteratorError;
        }
      }
    }

    var _iteratorNormalCompletion2 = true;
    var _didIteratorError2 = false;
    var _iteratorError2 = undefined;

    try {
      for (var _iterator2 = target.parentNode.cells[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
        var cell = _step2.value;
        cell.classList.toggle('sorted', cell === target);
      }
    } catch (err) {
      _didIteratorError2 = true;
      _iteratorError2 = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
          _iterator2.return();
        }
      } finally {
        if (_didIteratorError2) {
          throw _iteratorError2;
        }
      }
    }
  };

  document.querySelectorAll('.table_sort thead').forEach(function (tableTH) {
    return tableTH.addEventListener('click', function () {
      return getSort(event);
    });
  });
});

Я это в онлайновом инструменте на сайте бабеля перекомпилировал. На работоспособность не проверял. Если сработает, то могу скрипт у себя локально в гальпе прогнать через бабель и минификатор, чтобы по весу не растягивать скрипт.

Sergeevu4
Sergeevu4
18:52 25.12.2019 #

Здравствуйте, спасибо вам за интересный, нативный способ сортировки для таблиц.  Единственное о чем хотелось бы вас попросить оставляйте пожалуйста комментарии для кода. Попытался самостоятельно разобраться, все вроде понял, но сам бы на вряд ли додумался)

Андрей
Андрей
14:30 29.01.2020 #

Вы нереально круты. Огромное спасибо за классный способ сортировки. С уважением и признательностью, Андрей К.

Сонджу
Сонджу
20:01 11.02.2020 #

Отличный скрипт! А как можно сделать, чтобы по-умолчанию сортировало в обратном порядке?

Admin
Admin
20:03 11.02.2020 #

Сортировку по умолчанию задаёте вы когда заполняете таблицу.

Сонджу
Сонджу
21:04 11.02.2020 #

Я имею в виду при клике чтобы от Я до А была сортировка. А то два клика делать неудобно каждый раз.

Admin
Admin
21:25 11.02.2020 #

Я понял. Может вам нужен скрипт попроще чтобы только по одной колонке сортировал?

А в данном скрипте с логикой всё правильно. Он сортирует по любой из колонок таблицы по алфавиту и по числам. В начале по порядку, потом в обратном порядке.

Возможно у вас какой то индувидуальный случай, где нужно сортировать по числам от большего к меньшему и не по всем колонкам а по каким то отдельным. Тогда вам нужно писать уникальный скрипт.

А у меня в данном случае универсальный скрипт для общего применения.

Сонджу
Сонджу
21:44 11.02.2020 #

Спасибо за быстрый ответ. Попробую поискать подобный скрипт.

Prinz
Prinz
07:08 18.02.2020 #

Добрый день,как можно добавить сохранение состояние сортировки (убывание,увеличение) между страниц при пагинации?

Admin
Admin
07:23 18.02.2020 #

Я так понимаю это список записей выводится в табличном виде.

При помощи js можно записывать данные в память браузера. Свойство называется localStorage. Но тут плохо тем что будет перерисовка (сортировка) после загрузки дома страницы.

Я может не совсем правильно понял задачу, но по моему тут лучше делать сортировку на сервере, чтобы данные приходили уже в отсортированном виде.

Андрей
Андрей
10:31 04.03.2020 #

Как быть с данными типа float? Сортирует как текст((( Вернее работает, но если вывести с форматированием, где пробел между тысячами, то не работает. ))) Красотой приходится жертвовать.

Admin
Admin
10:34 04.03.2020 #

float это вы имеете в виду числа с плавающей точкой?

Может у вас запятая проставлена в этих числах, а не точка?

koly25071998
koly25071998
08:20 12.03.2020 #

а как отсортировать допустим все кроме первого столбца? первый столбец будет указывать просто номер строки? то есть если мы сортируем по другим значениям, то значения в первом столбце с id не сортируются

Admin
Admin
09:28 12.03.2020 #

Самое простое решение, можно после сортировки взять и переписать индексы первого столбца:

document.querySelectorAll('.table_sort tbody tr td:first-child').forEach((el, i) => el.textContent = i + 1);

Я из консоли браузера попробовал, вроде всё правильно.

Вставил в скрипт:

document.addEventListener('DOMContentLoaded', () => {

    const getSort = ({ target }) => {
        const order = (target.dataset.order = -(target.dataset.order || -1));
        const index = [...target.parentNode.cells].indexOf(target);
        const collator = new Intl.Collator(['en', 'ru'], { numeric: true });
        const comparator = (index, order) => (a, b) => order * collator.compare(
            a.children[index].innerHTML,
            b.children[index].innerHTML
        );

        for(const tBody of target.closest('table').tBodies)
            tBody.append(...[...tBody.rows].sort(comparator(index, order)));

        for(const cell of target.parentNode.cells)
            cell.classList.toggle('sorted', cell === target);

        document.querySelectorAll('.table_sort tbody tr td:first-child').forEach((el, i) => el.textContent = i + 1);
    };

    document.querySelectorAll('.table_sort thead').forEach(tableTH => tableTH.addEventListener('click', () => getSort(event)));

});
Дмитрий
Дмитрий
08:42 12.03.2020 #

Отличный скрипт, все работает. но подскажите пожалуйста, как сделать что бы изначально в первой колонке (в случае с примером - в ячейке "id") отображалась стрелочка вниз, типо что бы пользователю было наглядно, что есть сортировка и изначальна она по первой колонке?)

Admin
Admin
08:52 12.03.2020 #

Чтобы такое сделать, нужно для этой ячейки в шапке таблицы в хтмле прописать class="sorted" и дата-атрибут data-order="-1". Должно получиться так:

<th data-order="-1" class="sorted">id</th>

Это в css-стилях прописано.

Если data-order="-1" то будет ▼

А если data-order="1" то ▲

Георгий
Георгий
10:36 23.03.2020 #

Скрипт работает великолепно, спасибо! Единственное, подскажите, пожалуйста, можно ли как-то "выкинуть" последнюю строчку из сортировки? Дело в том, что в ней у меня объединены все ячейки и с таким условием сортировка не работает =(

Admin
Admin
10:42 23.03.2020 #

Так вы в такой ситуации делайте футер таблицы.

Просто эту последнюю строку прописывайте не в <tbody> а в <tfoot>

Георгий
Георгий
12:41 23.03.2020 #

И правда, спасибо огромнейшее!

Artem
Artem
07:53 05.04.2020 #

Здравствуйте! Хочу поблагодарить за скрипт! Часто его использую, он великолепен))

Только возникла проблема в ie11, при получении индекса он вылетает с ошибкой неитерируемый объект.(через babel скрипт прогнал) Думаю ошибка в том что в ie11 для querySelectorAll не работает forEach и я переписал [].forEach.call().

Не могу разобраться как пофиксить

Admin
Admin
08:52 05.04.2020 #

Если честно, я даже не знаю как работает IE и никаких полифилов для него никогда не писал.

Я игнорирую браузер IE и само его существование. Что в css, что в js я его просто игнорирую. Считаю что у кого IE или оська Android ниже 4.4 пусть меняют свои устройства. Я использую флексы и svg.

Но тут ещё такой момент, что это всё должен делать бабель. Там как и у автопрефексера можно задать в настройках поддержку браузеров. Вот посмотрите здесь https://babeljs.io/docs/en/babel-preset-env#options есть такой пример:

{
  "targets": {
    "chrome": "58",
    "ie": "11"
  }
}
Artem
Artem
08:52 05.04.2020 #

Оказалось у ie11 HTMLCollection не имеют метода перебора, поэтому for in не работал, переписал под тот же самый forEach)

[].forEach.call(target.closest('table').tBodies, function (tBody) {
    tBody.append.apply(tBody, _toConsumableArray(_toConsumableArray(tBody.rows).sort(comparator(index, order))));
  });

[].forEach.call(target.parentNode.cells, function (cell) {
  cell.classList.toggle('sorted', cell === target);
});
Виктор
Виктор
06:35 22.04.2020 #

Респект автору! Один из самых не капризных и простых скриптов! Удачи в жизни, в самоизоляции и без неё!

Madler
Madler
13:39 13.07.2020 #

Спасибо за скрипт - работает на все 100%.

Единственно, мне необходимо, чтобы по клику сортировка была всегда только в одном порядке - в порядке убывания. Подскажите, как это можно сделать?

Чтобы по-умолчанию при первом клике сортировка была в порядке убывания я поменял значение с -1 на 1

const order = (target.dataset.order = -(target.dataset.order || 1));

Но как сделать так, чтобы при повторном клике не сортировалось в обратном порядке - не знаю.

Admin
Admin
13:58 13.07.2020 #

А есть пример таблицы в html-формате? Пусть данные будут фейковые, просто чтобы понять какая таблица.

Там может у вас на числовых данных и можно работу скрипта упростить. Ну и мне не верстать для тестирования.

Madler
Madler
14:03 13.07.2020 #

Да, конечно и спасибо за оперативный отклик!!!

<table class="rates table_sort">
                <thead>
                    <tr>
                        <th></th>
                        <th>Мужчины</th>
                        <th></th>
                        <th>Рейтинг</th>
                        <th>Рейтинг2</th>
                        <th>Рейтинг3</th>
                    </tr>
                </thead>
                <tbody>
                        <tr class="<?php if(!$i) echo 'blue'; else if($i == $len - 1) echo 'red-border-bottom'; ?>">
                            <td><?php echo $item['pos']; ?></td>
                            <td><?php echo $item['player']; ?></td>
                            <td><span class="flag <?php echo str_replace(" ", "-", $item['country']); ?>"></span></td>
                            <td><?php echo $item['st_rating']; ?></td>
                            <td><?php echo $item['rapid_rating']; ?></td>
                            <td><?php echo $item['blitz_rating']; ?></td>
                        </tr>
                </tbody>
            </table>
Admin
Admin
14:04 13.07.2020 #

а в html есть? На пять строк для тестирования.

И по каким столбцам нужно сортировать?

Madler
Madler
14:11 13.07.2020 #
<table class="rates table_sort">
                <thead>
                    <tr>
                        <th></th>
                        <th>Игроки</th>
                        <th></th>
                        <th data-order="-1" class="sorted">Рейтинг1</th>
                        <th data-order="-1" class="">Рейтинг2</th>
                        <th data-order="-1" class="">Рейтинг3</th>
                    </tr>
                </thead>
                <tbody>            
                        <tr class="blue">
                            <td>1</td>
                            <td>Иванов</td>
                            <td><span class="flag flag-no"></span></td>
                            <td>2863.0</td>
                            <td>2881.0</td>
                            <td>2886.0</td>
                        </tr><tr class="">
                            <td>2</td>
                            <td>Петров</td>
                            <td><span class="flag flag-us"></span></td>
                            <td>2835.0</td>
                            <td>2773.0</td>
                            <td>2711.0</td>
                        </tr><tr class="">
                            <td>3</td>
                            <td>Сидоров</td>
                            <td><span class="flag flag-cn"></span></td>
                            <td>2791.0</td>
                            <td>2836.0</td>
                            <td>2788.0</td>
                        </tr><tr class="">
                            <td>4</td>
                            <td>Михалков</td>
                            <td><span class="flag flag-ru"></span></td>
                            <td>2784.0</td>
                            <td>2778.0</td>
                            <td>2785.0</td>
                        </tr><tr class="">
                            <td>5</td>
                            <td>Толстой</td>
                            <td><span class="flag flag-fr"></span></td>
                            <td>2778.0</td>
                            <td>2860.0</td>
                            <td>2822.0</td>
                        </tr></tbody>
            </table>

Сортировка только в одну сторону (от большего к меньшему) нужна по столбцам рейтинг1, рейтинг2, рейтинг3

Admin
Admin
15:17 13.07.2020 #

В общем, столбцам по которым сортировка нужна добавил класс col_sort . Получается так:

<table class="rates table_sort">
    <thead>
        <tr>
            <th></th>
            <th>Мужчины</th>
            <th></th>
            <th class="col_sort sorted" data-order="-1">Рейтинг</th>
            <th class="col_sort">Рапид</th>
            <th class="col_sort">Блиц</th>
        </tr>
    </thead>
    <tbody>            
        <tr class="blue">
            <td>1</td>
            <td>Иванов</td>
            <td><span class="flag flag-no"></span></td>
            <td>2863.0</td>
            <td>2881.0</td>
            <td>2886.0</td>
        </tr>
        <tr class="">
            <td>2</td>
            <td>Петров</td>
            <td><span class="flag flag-us"></span></td>
            <td>2835.0</td>
            <td>2773.0</td>
            <td>2711.0</td>
        </tr>
    </tbody>
</table>

Скрипт:

document.addEventListener('DOMContentLoaded', () => {
    const getSort = ({ target }) => {
        const order = (target.dataset.order = -1);
        const index = [...target.parentNode.cells].indexOf(target);
        const collator = new Intl.Collator({ numeric: true });
        const comparator = (index, order) => (a, b) => order * collator.compare(
            a.children[index].innerHTML,
            b.children[index].innerHTML
        );
        
        for(const tBody of target.closest('table').tBodies)
            tBody.append(...[...tBody.rows].sort(comparator(index, order)));

        for(const cell of target.parentNode.cells)
            cell.classList.toggle('sorted', cell === target);
        
        document.querySelectorAll('.table_sort tbody tr td:first-child').forEach((el, i) => el.textContent = i + 1);
    };

    document.querySelectorAll('.table_sort thead .col_sort').forEach(tableTH => tableTH.addEventListener('click', () => getSort(event)));
});

Вроде всё как вам нужно. Добавил чтобы первый столбец индексы с единицы начинались после сортировки. Если таблица будет с пагинацией то на это стоит обратить внимание. Хотя тут пагинацию делать не получится, не логично. Пагинацию можно сделать только по отдельному рейтингу, а не в сводной таблице. Я понял что первая фамилия - Магнус, ну и где то там есть бурят Накамура.

Я весь css повторять не буду, просто покажу что курсор где комментарий нужно убрать и добавить его отдельно для колонок в которых есть сортировка:

.table_sort th {
    color: #ffebcd;
    background: #008b8b;
    /* cursor: pointer; */
}
.table_sort th.col_sort {
    cursor: pointer;
}

Там в css можно ещё лишних стилей убрать и немного подчистить, если вы взяли стили с моего примера.

Так же могу порекомендовать сделать липкую шапку таблицы: https://precode.top/b/p/sticky-thead Там вообще один стиль нужно добавить.

Madler
Madler
15:48 13.07.2020 #

Просто 5+! Огромное при огромное спасибо за помощь!!!

P.S. Если на странице более чем одна такая таблица, то у всех таблиц после клика первый столбец перезаписывается и нумерация начинает идти подряд (т.е. у второй таблицы первый номер меняется на +1 от последнего номера в первой таблице). Решил прописыванием отдельно скрипта для каждой таблицы.

Mazula
Mazula
14:46 13.08.2020 #

Здравствуйте, хотелось бы вас поблагодарить за вашу работу. Так же есть небольшая просьба: добавить комментарии к коду, т.к., честно говоря, некоторые вещи в вашем коде мне не понятны. Так же хотелось бы заметить, что скрипт не совсем корректно сортирует отрицательные значения: то есть если у нас будет выборка 1,2 -3 0,7 -,03, то ваш скрипт отсортирует их 1,2 0,7 -3 -0,3, хотя -0,3 больше чем -3. Я по-этому и попросил добавить комментарии, т.к. не смог разобраться, как это пофиксить. Спасибо!

Admin
Admin
14:57 13.08.2020 #

А если в качестве разделителя десятичных знаков ставить точку а не запятую, тоже будет неправильно сортировать данный пример?

Mazula
Mazula
06:16 14.08.2020 #

Доброе утро, да, только что потестил

Влад
Влад
08:44 17.08.2020 #

Можете пожалуйста доработать сортировку отрицательных чисел?

Andrey
Andrey
23:58 13.01.2021 #

Спасибо автору за скрипт!!!

Сразу скажу - я не программист.

Для себя заменил .innerHTML на .textContent (comparator ), т.к. использую вложенные теги цвета и по отображаемому тексту сортируется, соответственно, не правильно.

На счет отрицательных чисел и вообще чисел, я добавил условие "если число", то использовать другую функцию сортировки:

const isNum = (content) => !isNaN(parseFloat(content)) && isFinite(content);//функция проверки числа (можно свою написать)

for(const tBody of target.closest('table').tBodies) {
    if (isNum(tBody.rows[0].children[index].textContent)) //проверка на число в первой строке
        tBody.append(...[...tBody.rows].sort(function(a, b){
            var numA=a.children[index].textContent, numB=b.children[index].textContent;
            if (isNum(numA) && isNum(numB)) return order * (numA - numB); //проверяем на число все ячейки
            else return 0 
        }));
    else            
        tBody.append(...[...tBody.rows].sort(comparator(index, order)));

}
Admin
Admin
14:32 17.08.2020 #

Да, согласен. Посмотрел, есть ошибка в сортировке с отрицательными числами.

Исправить текущий скрипт не могу. Тут нужно с нуля заново всё писать, а у меня на данный момент в этом нет нужды.

Извиняюсь, но мне сидеть над этим сейчас некогда.

Павел
Павел
08:58 24.05.2021 #

Скрипт очень понравился, работает без обновления страницы. Но под мой пример не подходит, так как использую две таблицы для организации прокрутки - первая таблица в виде шапки зафиксирована, вторая прокручивается (class-2). Понимаю, что нужно что-то поменять в скрипте, но в нем совсем не разбираюсь.

<section class="class-1">
	<table>
		<thead>
			<tr>
				<th style="width: 5%;">№</th>
				<th data-order="-1" class="sorted"  style="width: 20%;">Параметр 2</th>
				<th style="width: 75%;">Параметр 2</th>
			</tr>
		</thead>
	</table>	
	<section class="class-2">
		<table>
			<tbody>
				<tr>
					<td style="width: 5%;">1</td>
					<td style="width: 20%;">123</td>
					<td style="width: 70%;">456</td>
				</tr>	
				<tr>
					<td style="width: 5%;">2</td>
					<td style="width: 20%;">123</td>
					<td style="width: 70%;">456</td>
				</tr>	
				<tr>
					<td style="width: 5%;">2</td>
					<td style="width: 20%;">123</td>
					<td style="width: 70%;">456</td>
				</tr>								
			</tbody>
		</table>
	</section>	
</section>

*** чтобы писать комментарии.