Tabulator.js - строим интерактивную html-таблицу за 10 минут
Однажды на работе коллега-бекендщик подошел с вопросом. Есть 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 как в доке. Обновляем страницу и видим это Красота! 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 пропадет. Обновляем страницу и смотрим на ссылки.
Идем дальше. А не добавить ли в таблицу пагинацию?
Пагинация
Это очень просто. В настройках сразу после layout: 'fitColumns' добавим еще 2 пункта.
pagination: 'local', paginationSize: 8
И в апишном запросе изменим limit=8 на 30. Чтобы получить больше данных и сделать пагинацию интереснее. Вот что получилось Чувствуете, как круто? Реализовывать пагинацию собственными лапками то еще удовольствие. Вот здесь мы уже делали Постраничная навигация по товарам в интернет-магазине. А в табуляторе это 2 строки.
Дальше вообще идет магия.
Дизайн
Таблицу можно как угодно стилизовать. А можно не как угодно, а по-бутстраповски. Для этого подключим еще один файлик со стилями
Смотрим Уже гораздо круче. 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' }] - сразу после настроек пагинации, чтобы таблица по дефолту сортировалась по убыванию рейтинга. Сверху самые классные статьи.
И итоговый скрин
Живой пример
А теперь на фиг картинки, посмотрим, что получилось уже в действии. Там не скриншоты, все кликается, сортируется, ссылки активны.
Демонстрация табулятора: рейтинги статей webdevkin.ru
В таблице не левые числа. Это реальный показатель популярности статей, основанный на оценках читателей. Перейдите в любую статью из таблицы, оцените ее (в конце поста блок со звездочками) и обновите демо-страницу. Количество голосов и рейтинг изменятся. Средняя оценка может остаться такой же, если Ваша оценка совпадает со средней.
Мне эта табличка нравится. Конечно, и раньше смотрел, как читатели ставят оценки, но такой наглядной картины не было. Думаю, буду использовать такие таблички чаще.
И это еще я только чуточку библиотечку тронул. А там ведь есть и фильтры, и разные варианты форматирования. Колбеки и обмен данными с сервером. Можно даже добавлять новые строки в таблице и отправлять их бекенду, чтобы записать в базу. Красота.
Заключение
Куда такую таблицу можно прикрутить? Да навскидку:
1. Посещаемость статей
2. Список заказов в админке интернет-магазина
3. Список товаров в админке.
4. Логи или список событий. Здесь нужно будет запариться с серверной пагинацией, не все ж данные на клиент сразу тащить. Но это проще, чем целиком делать руками.
5. Здесь будет ваша фантазия
А еще спрошу.
На этом все, всем спасибо и пока.
Истории из жизни айти и обсуждение кода.