Bazaprogram.ru

Новости из мира ПК
4 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Javascript работа с таблицами

Javascript динамическая html таблица

Понадобилось мне в одном проекте на днях сделать html таблицу, которую бы выводил серверный php скипт. Но таблицу не простую, а динамическую. Динамическую в том плане, что нужно было предоставить пользователю возможность править данные в ней. Добавлять и удалять строки, а так же отсылать отредактированные данные на сервер. В данной заметке я опишу процесс создания такой html таблицы, а так же приведу полностью рабочий, прокоментированный листинг.

Внимание! По просьбе уважаемого Павла скрипт был доработан. В результате он стал более функционален. Теперь есть возможность размещать и другие элементы html-формы. Скрипт стал меньше размером. Вдобавок немного изменилась структура данных отправляемая на сервер, на мой взгляд она стала более удобна. К сожалению, если приводить описание скрипта на странице, то нужно полностью переписывать статью, а мне делать этого не охота. Поэтому я залил новый скрипт в свой репозиторий: Динамическая html таблица там так же есть полноценный пример и описание как его использовать и пример как обработать данные на сервере.

Получившаяся в итоге html таблица будет примерно следующей:

Порывшись в Javascript доках, я нашёл всего несколько кроссбраузерных функций, отвечающих стандарту W3C. Используя которые, тем не менее, можно творить с html таблицей всё что угодно:

МетодОписание
createCaption()Создает пустой элемент заголовка и добавляет его в таблицу
createTFoot()Создает пустой элемент TFOOT и добавляет его в таблицу
createTHead()Создает пустой элемент THEAD и добавляет его в таблицу
deleteCaption()Удаляет первый элемент caption
deleteRow()Удаляет строку из таблицы
deleteTFoot()Удаляет элемент TFOOT из таблицы
deleteTHead()Удаляет элемент THEAD из таблицы
insertRow()Создает пустую строку и добавляет её в таблицу

Используя данный инструментарий создадим нашу динамическую html таблицу. Я подумал, что исходная таблица для работы должна быть как можно более естественная. Навроде вот этой:

В итоге в сжатом виде скрипт динамической html таблицы «весит» 1.15Кб и предоставляет всего одну функцию — конструктор DynamicTable которая принимает три параметра:

GLOB — глобальный контекст (объект window или this)

htmlTable — html — элемент таблица, которую будем делать динамичной.

config — объект конфигурации *

* Объект конфигурации должен содержать свойства в виде целых чисел:

значения которых станут имена подмассивов. Если попробовать объяснить проще, то сама html таблица это ассоциативный массив, а столбцы таблицы — это индексные массивы. в общем ниже приведена трассировка результирующего массива. Такой он получится, если 3 параметр конфиг, передать таким, каким он показан в примере. Ниже я приведу полный листинг скрипта с подробными комментариями.

Динамическая html таблица

Как всегда, если убрать комментарии — он не такой уж и страшныйНо для срабатывания нужно вызвать функцию DynamicTable как конструктор (в принципе можно и просто как функцию, у нас есть страховка) следующим образом:

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

Вместо ответа на вопрос от пользователя Яна в одном из комментариев приведу простенький пример занесения данных в базу MySQL

После того, как форма «ушла» на сервер в массиве $_POST мы можем наблюдать примерно следующее:

Обработать этого монстра мы можем следующим образом:

Таблица с заранее проставляемыми строками

По просьбам трудящихся выкладываю скрипт таблицы с заранее проставляемыми строками:

Поле 1
Поле 2Поле 3Поле 4

Логика серверной стороны может быть такой же как и у таблицы сверху

Нам понадобится вот такой html-каркас:

А вот собственно реализация функции setupTable

Забираем и пользуемся на здоровье

DOM: Работаем со строками и ячейками таблицы

Перед вами стоит задача «препарировать» таблицу. Пройтись по её строкам и ячейкам, что-то удалить, что-то добавить. Зацепившись за элемент table, мы начинаем использовать привычные DOM-свойства и методы: firstChild, createElement, appendChild и др. И вдруг оказывается, что всё работает совсем не так, как представлялось на первый взгляд.

Неправильный подход

Есть простая таблица, с идентификатором «tableId», в которой требуется удалить первую и добавить в конец новую строку:

row:1, cell:1row:1, cell:2
row:2, cell:1row:2, cell:2

Решим задачу привычными методами, выполнив функцию no() :

function no ( ) <
var table = document. getElementById ( «tableId» ) ;
// Перейдем к первой строке таблицы
var tr1 = table. firstChild ;
alert ( tr1. nodeName ) ; // В IE и Opera выведет «TBODY», а в Gecko — «#text»
// Не получилось, идем другим путем
var allRows = table. getElementsByTagName ( «tr» ) ;
tr1 = allRows [ 0 ] ;
// Удаляем первую строку
tr1. parentNode . removeChild ( tr1 ) ;
// Создаем новую строку
var tr3 = document. createElement ( «tr» ) ;
tr3. innerHTML = »

row:3, cell:1row:3, cell:2

» ;
// Добавляем её в таблицу
allRows = table. getElementsByTagName ( «tr» ) ;
tr3 = allRows [ 0 ] . parentNode . appendChild ( tr3 ) ; /* Вот здесь совсем интересно
В IE строка не отобразилась вовсе, т.к. в добавленной строке находятся битые ячейки, без открывающего тега td
В Gecko добавился только элемент TR, содержащий строку «row:3, cell:1row:3, cell:2» без ячеек
Только в Опере всё отработало как задумывалось
*/
// Затираем добавленную строку
alert ( «Сейчас произойдет удаление строки» ) ;
tr3. parentNode . removeChild ( tr3 ) ;
// Добавляем то, что хотим более корректно, через DOM
alert ( «Повторное добавление строки» ) ;
var td3_1 = document. createElement ( «td» ) ;
td3_1. innerHTML = «row:3, cell:1» ;
var td3_2 = document. createElement ( «td» ) ;
td3_2. innerHTML = «row:3, cell:2» ;
tr3 = document. createElement ( «tr» ) ;
tr3. appendChild ( td3_1 ) ;
tr3. appendChild ( td3_2 ) ;
allRows = table. getElementsByTagName ( «tr» ) ;
tr3 = allRows [ 0 ] . parentNode . appendChild ( tr3 ) ;
// УРА!
>

Как видно из комментариев к коде, в итоге задача решена, но не очень гибким (и уж точно некрасивым) способом.

Правильное решение

Пока мы пытаемся найти кроссбраузерные способы работы с элементами таблицы, в DOM2 давно описан удобный интерфейс как раз для решения таких задач. Почему-то рунете, не много материалов на эту тему, так что остановимся более подробно на разборе необходимых свойств и методов:

Interface HTMLTableElement

  • Свойство rows, возвращает коллекцию узлов строк таблицы, readonly.
  • Метод deleteRow принимает в качестве аргумента индекс строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertRow принимает в качестве аргумента индекс строки, перед которой будет вставлена новая строка. Возвращает ссылку на новую вставленную строку.

Также есть свойства и методы для работы с элементами THEAD, TFOOT, TBODY и CAPTION , но из-за нечастого использования останавливаться на них подробно не будем.

Interface HTMLTableRowElement

  • Свойство cells, возвращает коллекцию узлов ячеек для строки, readonly.
  • Метод deleteCell принимает в качестве аргумента индекс ячейки строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertCell принимает в качестве аргумента индекс ячейки, перед которой будет вставлена новая ячейка в строке. Возвращает ссылку на новую вставленную ячейку.

Interface HTMLTableCellElement

  • Свойство cellIndex, возвращает индекс ячейке в строке (от нуля) readonly.

Решим кроссбраузерно поставленную задачу с помощью перечисленных выше свойств и методов:

Надеюсь описанный в этой статье интерфейс облегчит вам работу с таблицами в DOM. Удачи!

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

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

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

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

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

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

Есть у меня одна апишечка. Отдает json с массивом популярных статей в блоге. Хочу этот список показать. Для начала вот сама апишечка — https://cp.simpple.ru/api/v1/w >

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

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

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

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

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

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

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

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

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

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

Зачем лишнее поле />

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

Пагинация

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

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

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

Дизайн

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

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

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

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

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

Живой пример

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

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

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

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

Заключение

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

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

DOM: Работаем со строками и ячейками таблицы

Перед вами стоит задача «препарировать» таблицу. Пройтись по её строкам и ячейкам, что-то удалить, что-то добавить. Зацепившись за элемент table, мы начинаем использовать привычные DOM-свойства и методы: firstChild, createElement, appendChild и др. И вдруг оказывается, что всё работает совсем не так, как представлялось на первый взгляд.

Неправильный подход

Есть простая таблица, с идентификатором «tableId», в которой требуется удалить первую и добавить в конец новую строку:

row:1, cell:1row:1, cell:2
row:2, cell:1row:2, cell:2

Решим задачу привычными методами, выполнив функцию no() :

function no ( ) <
var table = document. getElementById ( «tableId» ) ;
// Перейдем к первой строке таблицы
var tr1 = table. firstChild ;
alert ( tr1. nodeName ) ; // В IE и Opera выведет «TBODY», а в Gecko — «#text»
// Не получилось, идем другим путем
var allRows = table. getElementsByTagName ( «tr» ) ;
tr1 = allRows [ 0 ] ;
// Удаляем первую строку
tr1. parentNode . removeChild ( tr1 ) ;
// Создаем новую строку
var tr3 = document. createElement ( «tr» ) ;
tr3. innerHTML = »

row:3, cell:1row:3, cell:2

» ;
// Добавляем её в таблицу
allRows = table. getElementsByTagName ( «tr» ) ;
tr3 = allRows [ 0 ] . parentNode . appendChild ( tr3 ) ; /* Вот здесь совсем интересно
В IE строка не отобразилась вовсе, т.к. в добавленной строке находятся битые ячейки, без открывающего тега td
В Gecko добавился только элемент TR, содержащий строку «row:3, cell:1row:3, cell:2» без ячеек
Только в Опере всё отработало как задумывалось
*/
// Затираем добавленную строку
alert ( «Сейчас произойдет удаление строки» ) ;
tr3. parentNode . removeChild ( tr3 ) ;
// Добавляем то, что хотим более корректно, через DOM
alert ( «Повторное добавление строки» ) ;
var td3_1 = document. createElement ( «td» ) ;
td3_1. innerHTML = «row:3, cell:1» ;
var td3_2 = document. createElement ( «td» ) ;
td3_2. innerHTML = «row:3, cell:2» ;
tr3 = document. createElement ( «tr» ) ;
tr3. appendChild ( td3_1 ) ;
tr3. appendChild ( td3_2 ) ;
allRows = table. getElementsByTagName ( «tr» ) ;
tr3 = allRows [ 0 ] . parentNode . appendChild ( tr3 ) ;
// УРА!
>

Как видно из комментариев к коде, в итоге задача решена, но не очень гибким (и уж точно некрасивым) способом.

Правильное решение

Пока мы пытаемся найти кроссбраузерные способы работы с элементами таблицы, в DOM2 давно описан удобный интерфейс как раз для решения таких задач. Почему-то рунете, не много материалов на эту тему, так что остановимся более подробно на разборе необходимых свойств и методов:

Interface HTMLTableElement

  • Свойство rows, возвращает коллекцию узлов строк таблицы, readonly.
  • Метод deleteRow принимает в качестве аргумента индекс строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertRow принимает в качестве аргумента индекс строки, перед которой будет вставлена новая строка. Возвращает ссылку на новую вставленную строку.

Также есть свойства и методы для работы с элементами THEAD, TFOOT, TBODY и CAPTION , но из-за нечастого использования останавливаться на них подробно не будем.

Interface HTMLTableRowElement

  • Свойство cells, возвращает коллекцию узлов ячеек для строки, readonly.
  • Метод deleteCell принимает в качестве аргумента индекс ячейки строки, которая подлежит удалению. Индексация начинается с нуля.
  • Метод insertCell принимает в качестве аргумента индекс ячейки, перед которой будет вставлена новая ячейка в строке. Возвращает ссылку на новую вставленную ячейку.

Interface HTMLTableCellElement

  • Свойство cellIndex, возвращает индекс ячейке в строке (от нуля) readonly.

Решим кроссбраузерно поставленную задачу с помощью перечисленных выше свойств и методов:

Надеюсь описанный в этой статье интерфейс облегчит вам работу с таблицами в DOM. Удачи!

Читать еще:  Java util comparator
Ссылка на основную публикацию
Adblock
detector