Tabulator.js - строим интерактивную html-таблицу за 10 минут

ноябрь 14 , 2018
Демо

Однажды на работе коллега-бекендщик подошел с вопросом. Есть get-запрос, который отдает json с массивом данных.  Нужно по ним построить таблицу в браузере. Проект личный, таблица для внутреннего использования, красоты особой не нужно.  Главное сделать минимальными усилиями.

Как бы поступил я, обычный jquery-программист? Получил бы данные через $.get, распарсил, прогнал массив через шаблонизатор, добавил стили. Работы на пару часов. Если нужна еще сортировка, пагинация и фильтрация, то больше.

Коллега поступил гораздо мудрее и загуглил готовые решения. ЗАГУГЛИЛ. Да, так можно было. И показал результат.

Отрисована симпатичная таблица с данными, с сортировкой и фильтрацией. В 20 строк кода. Всю эту красоту делает библиотека tabulator.js. Я был впечатлен. Сам виджеты опросов и рейтингов делаю, а тут такая вещь очевидная. Не приходило в голову, что для построения таблиц наверняка есть готовые решения. Но это урок на будущее, а пока я об этом узнал и расскажу подробнее вам.

Итак, библиотека tabulator. Вот сайт - tabulator.info. Сайт по не-русски, но мышайтишники, разберемся. А если вам разбираться лениво, да и букв там много, то покажу на примере и картинках, как библиотека работает. Пойдем по тому же пути, что проделал коллега.

Есть у меня одна апишечка. Отдает json с массивом популярных статей в блоге. Хочу этот список показать. Для начала вот сама апишечка - https://cp.simpple.ru/api/v1/widgets/ratings/753bf174295992b3ca2d0bd4a78d6598/popular&limit=8. Откройте в браузере, убедитесь, что работает. Видите, там 4 поля: айдишник, заголовок статьи, количество проголосовавших и средняя оценка. Отобразим эту информацию в браузере.


Базовая таблица

Для начала подключим на странице одну css и две js, в том числе jquery - tabulator без нее не работает.

    
    
    

Можно скачать исходники с сайта либы, я же подключал с cdn, чтобы лишний раз файлы не таскать.

Затем в html поставим пустой див, где и отрисуем таблицу

    

И еще один js-файлик, где зададим настройки табулятора.

    

В файлике tabulator.js сначала пишем заготовку

    $(document).ready(function() {
        var url = 'https://cp.simpple.ru/api/v1/widgets/ratings/753bf174295992b3ca2d0bd4a78d6598/popular&limit=8';
        $.get(url, function(response) {
            // Инициализируем таблицу
            ...
        });
    });

В табуляторе можно напрямую указать url, куда сама либа будет ходить аяксом. Но у меня это не сработало, либа заругалась на кроссдоменные запросы. Поэтому пришлось добавить прослойку в виде $.get. Но не суть. Самое интересное внутри. Для инициализации беру код из доки. Только названия полей ставлю нужные

    var table = new Tabulator('#example-table', {
        data: JSON.parse(response),
        layout: 'fitColumns',
        columns: [
            { title: 'Статья', field: 'title', width: 550 },
            { title: 'Количество голосов', field: 'countRates', align: 'left', formatter: 'progress' },
            { title: 'Средняя оценка', field: 'rating' }
        ]
    });

Настройки колонок понятные: заголовок, название поля field (совпадает с полем в json-массиве), ширина и выравнивание. И formatter - классная штука, вариантов форматирования много, я взял progress как в доке. Обновляем страницу и видим это Tabulator по умолчанию Красота! 10 строчек кода и море удовольствия: и таблица, и сортировки, и даже симпатичный прогрессбар. Без усилий мы сделали таблицу, которую врукопашную кодили бы пару часов.


Добавляем ссылки

Разбираемся дальше. Я хочу не просто показать заголовки статей, а дать ссылки на них. Настройка formatter может быть не только текстом или прогрессбаром. Но также и функцией, которая возвращает любые строки. Добавим в нашу таблицу новое скрытое поле id, а в существующем title напишем функцию formatter

    { title: 'id', field: 'itemId', visible: false },
    {
        title: 'Статья',
        field: 'title',
        width: 550,
        formatter: function(cell) {
            var data = cell.getData(),
                href = 'https://webdevkin.ru/index.php?id=' + data.itemId;

            return '' + data.title + '';
        }
    }

Зачем лишнее поле id? Оно используется для формирования ссылки в другой колонке таблицы. Поэтому приходится id добавить, чтобы потом вытащить из объекта data = cell.getData(). Уберем колонку - и из data поле id пропадет. Обновляем страницу и смотрим на ссылки. Tabulator со ссылками

Идем дальше. А не добавить ли в таблицу пагинацию?


Пагинация

Это очень просто. В настройках сразу после layout: 'fitColumns' добавим еще 2 пункта.

    pagination: 'local',
    paginationSize: 8

И в апишном запросе изменим limit=8 на 30. Чтобы получить больше данных и сделать пагинацию интереснее. Вот что получилось Tabulator с пагинацией Чувствуете, как круто? Реализовывать пагинацию собственными лапками то еще удовольствие. Вот здесь мы уже делали Постраничная навигация по товарам в интернет-магазине. А в табуляторе это 2 строки.

Дальше вообще идет магия.


Дизайн

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

    

Смотрим Tabulator с bootstrap Уже гораздо круче. Bootstrap4, все дела. И пагинация приличнее стала. Такой вариант уже не то что в админке держать, а и людям не стыдно показать.

И последнее, что сегодня замутим. Добавим кастомную колонку "Рейтинг статьи". По скриншотам Вы видели, что статьи сортируются по количеству голосов и средней оценке. Но статья, которой 3 человека поставили пятерку, ценнее статьи, которой четверо поставили трояк, согласны? 3 * 5 > 4 * 3. Арифметика. Поэтому введем самую полезную колонку таблицы Рейтинг = Количество голосов * Средняя оценка

    {
        title: 'Рейтинг статьи',
        field: 'rating',
        formatter: function(cell) {
            var data = cell.getData();
            return Math.round(data.countRates * data.rating);
        },
        sorter: function(a, b, aRow, bRow) {
            var data1 = aRow.getData(),
                data2 = bRow.getData(),
                value1 = Math.round(data1.countRates * data1.rating),
                value2 = Math.round(data2.countRates * data2.rating);
            return value1 - value2;
        }
    }

Как работает formatter, мы уже знаем. Появилась еще новая функция sorter. Выглядит диковато, но на первый взгляд. Берем два сравниваемых значения (value = count * rating) и возвращаем их разницу. Кастомные сортировки работают по такому принципу, углубляться не будем.

Напоследок добавим еще пару штрихов:
1. tooltip: true в колонке с прогрессбаром. Чтобы при ховере показалось число голосов
2. initialSort: [{ column: 'rating', dir: 'desc' }] - сразу после настроек пагинации, чтобы таблица по дефолту сортировалась по убыванию рейтинга. Сверху самые классные статьи.
И итоговый скрин Tabulator с кастомной колонкой


Живой пример

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

Демонстрация табулятора: рейтинги статей webdevkin.ru

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

Мне эта табличка нравится. Конечно, и раньше смотрел, как читатели ставят оценки, но такой наглядной картины не было. Думаю, буду использовать такие таблички чаще.

И это еще я только чуточку библиотечку тронул. А там ведь есть и фильтры, и разные варианты форматирования. Колбеки и обмен данными с сервером. Можно даже добавлять новые строки в таблице и отправлять их бекенду, чтобы записать в базу. Красота.


Заключение

Куда такую таблицу можно прикрутить? Да навскидку:

1. Посещаемость статей
2. Список заказов в админке интернет-магазина
3. Список товаров в админке.
4. Логи или список событий. Здесь нужно будет запариться с серверной пагинацией, не все ж данные на клиент сразу тащить. Но это проще, чем целиком делать руками.
5. Здесь будет ваша фантазия

А еще спрошу.

На этом все, всем спасибо и пока.

Демо
Заходите в группу в контакте - https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как Вам статья? Оцените!