Dynamic table

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

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

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

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

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

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

  
Поле 1 Поле 2 Поле 3 Поле 4  
Значение 1 Значение 2 Значение 3 Значение 4  
Значение 1 Значение 2 Значение 3 Значение 4  

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

  1. GLOB — глобальный контекст (объект window или this)
  2. htmlTable — html — элемент таблица, которую будем делать динамичной.
  3. config — объект конфигурации *
Читайте также:  Url to png php

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

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

Array ( [val1] => Array ( [0] => Значение 1 [1] => Значение 1 ) [val2] => Array ( [0] => Значение 2 [1] => Значение 2 ) [val3] => Array ( [0] => Значение 3 [1] => Значение 3 ) [val4] => Array ( [0] => Значение 4 [1] => Значение 4 ) )

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

if(typeof window.DynamicTable !== 'function') < function DynamicTable(GLOB, htmlTable, config) < // Так как эта функция является конструктором, // подразумевается, что ключевое слово this - будет // указывать на экземнпляр созданного объекта. Т.е. // вызывать её нужно с оператором "new". // Проверка ниже является страховкой: // если эта функция была вызвана без оператора "new", // то здесь эта досадная ситуация исправляется: if ( !(this instanceof DynamicTable) ) < return new DynamicTable(GLOB, htmlTable, config); >// Зависимость: var DOC = GLOB.document, // Ссылка на массив строк таблицы: tableRows = htmlTable.rows, // Кол-во строк таблицы: RLength = tableRows.length, // Кол-во ячеек в таблице: CLength = tableRows[0].cells.length, // Контейнер для работы в циклах ниже: inElement = null, // Контейнер кнопки button = null, // Контейнер текстового узла кнопки butText = null, // В одном из методов ниже, потребуется // сохранить контекст: self = this, // Счётчики итераций: i,j; // Метод "Вставить кнопки". // Создаёт/добавляет две кнопки "удалить" и "добавить" // завёрнутые в элемент "P". Используются DOM - методы создания // и добавления элементов. this.insertButtons = function() < // Создаём первую кнопку: inElement = DOC.createElement("P"); inElement.className = "d-butts"; button = DOC.createElement("BUTTON"); button.onclick = this.delRow; butText = DOC.createTextNode("-"); button.appendChild(butText); // Добавляем её в DOM: inElement.appendChild(button); // Создаём вторую кнопку: button = DOC.createElement("BUTTON"); button.onclick = this.addRow; butText = DOC.createTextNode("+"); button.appendChild(butText); // Добавляем её в DOM: inElement.appendChild(button); // Обнуляем переменную, т.к. // она используется и в других методах. return inElement; >; // Метод "Добавить строку" this.addRow = function(ev) < // Кросс бр. получаем событие и цель (кнопку) var e = ev||GLOB.event, target = e.target||e.srcElement, // Получаем ссылку на строку, в которой была кнопка: row = target.parentNode.parentNode.parentNode, // Получаем кол-во ячеек в строке: cellCount = row.cells.length, // Получаем индекс строки в которой была кнопка + 1, // что бы добавить строку сразу после той, в которой // была нажата кнопка: index = row.rowIndex + 1, i; // Вставляем строку: htmlTable.insertRow(index); // В этом цикле, вставляем ячейки. for(i=0; i < cellCount; i += 1) < htmlTable.rows[index].insertCell(i); // Если ячейка последняя. if(i == cellCount-1) < // Получаем в переменную кнопки, используя метод, описанный выше: inElement = self.insertButtons(); >else < // Иначе получаем в переменную текстовое поле: inElement = DOC.createElement("INPUT"); // . и задаём ему имя, типа name[] - которое // впоследствии станет массивом. inElement.name = config[i+1]+"[]"; >// Добавляем в DOM, то что получили в переменную: htmlTable.rows[index].cells[i].appendChild(inElement); > // Обнуляем переменную, т.к. // она используется и в других методах. inElement = null; // Во избежании ненужных действий, при нажатии на кнопку // возвращаем false: return false; >; // Метод "Удалить строку" // Удаляем строку, на кнопку, которой нажали: this.delRow = function(ev) < // Страховка: не даёт удалить строку, если она осталась // последней. Цифра 2 здесь потому, что мы считаем так же // строку с заголовками TH. Итого получается, что 1 строка // с заголовками и 1 строка - с содержимым. if(tableRows.length >2) < htmlTable.deleteRow(this.parentNode.parentNode.parentNode.rowIndex); >else < return false; >>; // Фактически, ниже это инициализация таблицы: // Содержимое ячеек помещается внутрь текстовых // полей, а в последнюю ячейку кажой строки, помещаются // нопки "удалить" и "добавить" Функция является // "вызываемой немедленно" return (function() < // Мы имеем дело с двумерным массивом: // table.rows[. ].cells[. ] // Поэетому сдесь вложенный цикл. // Внешний цикл "шагает" по строкам. for( i = 1; i < RLength; i += 1 ) < // Внутренний цикл "шагает" по ячейкам: for( j = 0; j < CLength; j += 1 ) < // Если ячейка последняя. if( j + 1 == CLength ) < // Помещаем в переменную кнопки: inElement = self.insertButtons(); >else < // Иначе создаем текстовый элемент, inElement = DOC.createElement("INPUT"); // Помещаем в него данные ячейки, inElement.value = tableRows[i].cells[j].firstChild.data; // Присваиваем имя - массив, inElement.name = config[j+1]+"[]"; // Удаляем, уже не нужный экземпляр данных непосредственно // из самой ячейки, потому что теперь данные у нас внутри // текстового поля: tableRows[i].cells[j].firstChild.data = ""; >// Вставляем в ячейку содержимое переменной - это // либо текстовое поле, либо кнопки: tableRows[i].cells[j].appendChild(inElement); // Обнуляем переменную, т.к. // она используется и в других методах. inElement = null; > > >()); >// end function DynamicTable >

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

new DynamicTable( window, document.getElementById("dynamic"), );

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

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

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

Array ( [val1] => Array ( [0] => Значение 1 [1] => Значение 1 ) [val2] => Array ( [0] => Значение 2 [1] => Значение 2 ) [val3] => Array ( [0] => Значение 3 [1] => Значение 3 ) [val4] => Array ( [0] => Значение 4 [1] => Значение 4 ) [sub] => SEND )

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

// . Возможно еще какой то другой код . if ($_POST) < // Внимание, это пример! - Все очень кратко и без проверок. $mysqli = new mysqli("example.com", "user", "password", "database"); $mysqli->set_charset("utf8"); // Строим начало запроса. // Допустим у нас есть столбцы из формы : val1,val2,val3,val4 // Ваш способ организации хранения данных может и отличаться. Это лишь пример! // В этом примере таблица без ухищрений заносится в таблицу БД. Т.е. столбцы // формы становятся столбцами таблицы БД, а строки формы становятся строками // (записями) таблицы БД. $sql = 'INSERT INTO `YOUR_TABLE_NAME` (`val1`,`val2`,`val3`,`val4`) VALUES '; // Подразумевается, что в подмассивах val1,val2,val3,val4 - будет одинаковое // кол-во элементов. for ($i = 0; $i < count($_POST['val1']); $i++) < // "Накачиваем" запрос данными. // $DBCONN->escape(. ) - предполагается, что это функция в Вашем объекте // для экранирования нежелательных символов, для избежания SQL-нъекций $sql .= ' ("'. $mysqli->mysqli_real_escape_string($_POST['val1'][$i]) .'","'. $mysqli->mysqli_real_escape_string($_POST['val2'][$i]) .'","'. $mysqli->mysqli_real_escape_string($_POST['val3'][$i]) .'","'. $mysqli->mysqli_real_escape_string($_POST['val4'][$i]) .'"),'; > // обрезаем последнюю запятую $sql = rtrim($sql, ','); // Исполняем запрос. $mysqli->query($sql); > // . Возможно еще какой то другой код .

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

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

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

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

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

        

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

/** * @param tableId ID элемента tbody таблицы * @param selectId ID элемента select для установки кол-ва строк * @param fields Конфигурация строки таблицы: * @param creatorCallback - ф-ция обратного вызова принимающая два параметра: * - номер строки таблицы, * - имя поля из объекта fields */ function setupTable(tableId, selectId, fields, creatorCallback) < var htmlTBody = document.getElementById(tableId), htmlSelect = document.getElementById(selectId), rowTpl = document.createElement("TR"), rowNum = 0, ELEMENT, TD; /* Строим шаблон строки таблицы один раз, в дальнейшем будем просто его клонировать */ for(var field in fields) < if (false === fields.hasOwnProperty(field)) < continue; >TD = document.createElement("TD"); if (creatorCallback) < ELEMENT = creatorCallback(rowNum, fields[field]) >else < ELEMENT = document.createElement("INPUT"); ELEMENT.name = fields[field] + "[]"; >TD.appendChild(ELEMENT); rowTpl.appendChild(TD); rowNum += 1; > // Вешаем обработчик на элемент управления кол-вом строк htmlSelect.onchange = function (e) < var numRows = htmlSelect.options[htmlSelect.selectedIndex].value; /* Отслеживаем отрицательные значения а то мало ли какие там значения в option понаставят */ numRows = numRows < 0 ? 0 : numRows; /* Удаляем те строки которые есть. */ while(htmlTBody.firstChild) < htmlTBody.removeChild(htmlTBody.firstChild); >for (var i = 0; i < numRows; i++) < htmlTBody.appendChild(rowTpl.cloneNode(true)); >>; >

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

Источник

Удаление строка table html

Автор — Выскорко М.С. (aspid02@ngs.ru)

Введение

Объект — некоторая абстракция, которой можно дать уникальное и осмысленное имя. Оно (имя) отделяет конкретный объект от других подобных абстракций. Каждый объект обладает уникальным набором свойств. Эти свойства называются атрибутами. Каждый экземпляр объекта описывается конкретным набором значений атрибутов.

Таблица является одним из объектов HTML, который обладает своими свойствами, методами, атрибутами. Для доступа к которым используют следующую конструкцию:
[window.]document.getElementById(“идентификатор”).свойство | метод([параметры])

Иерархическая структура таблиц

Существует четыре дескриптора, с помощью которых можно определить различные области таблицы: описание, заголовок, тело и нижний колонтитул (соответственно: CAPTION, THEAD, TBODY и TFOOT).

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

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

Использование данных элементов на сегодняшний день, наверное, является больше «хорошим тоном программирования» и встречается в сложных структурах таблиц. Элементы THEAD, TBODY, TFOOT опускаются за ненадобностью, так как это не мешает нормальной работе браузера.

Свойства (атрибуты)

Border – значение: целочисленное; доступ: чтение/запись
Задаёт толщину границ таблицы.

Rules – значение: строковая константа; доступ: чтение/запись
Используется для управления отображения границ исключительно ячейками.
Различают пять значений свойства rules:

Поле 1 Поле 2 Поле 3 Поле 4
Значение Описание
All Граница вокруг каждой ячейки
Cols Вертикальные границы между столбцами
Groups Вертикальные границы между группами столбцов; горизонтальные границы между группами строк
None Границы между ячейками не отображаются
Rows Горизонтальные границы между группами строк

Источник

HTMLTableElement: deleteRow() method

The HTMLTableElement.deleteRow() method removes a specific row ( ) from a given .

Syntax

Parameters

index is an integer representing the row that should be deleted. However, the special index -1 can be used to remove the very last row of a table.

Return value

Exceptions

Thrown if index is greater than or equal to the number of available rows or is a negative value other than -1 .

Examples

This example uses JavaScript to delete a table’s second row.

HTML

table> tr> td>Cell 1.1td> td>Cell 1.2td> td>Cell 1.3td> tr> tr> td>Cell 2.1td> td>Cell 2.2td> td>Cell 2.3td> tr> tr> td>Cell 3.1td> td>Cell 3.2td> td>Cell 3.3td> tr> table> 

JavaScript

let table = document.querySelector("table"); // Delete second row table.deleteRow(1); 

Result

Specifications

Browser compatibility

BCD tables only load in the browser

Found a content problem with this page?

This page was last modified on Apr 7, 2023 by MDN contributors.

Your blueprint for a better internet.

MDN

Support

Our communities

Developers

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.

Источник

Оцените статью