Javascript, jComponent 12 ноября 2019 1 мин. 4517
Вспомнил интересную задачу - создание редактируемой таблицы. Раньше подобное я делал, используя разные jQuery плагины, при этом получалось не очень выразительно, много кода, ради этого простого функционала, приходилось таскать эти плагины. Сейчас такое решение легко можно реализовать, используя библиотеку jComponent
. Итак, погнали разбираться, как же все таки это сделать.
Сперва необходимо подключить библиотеку jComponent
, а также несколько компонент, которые нам понадобятся, это j-Textbox
, j-Dropdown
, j-Repeater
. Как это сделать можно посмотреть этот пост jComponent - #Часть 1, Подключение, DataBinding.
Теперь создадим два массива в одном из них мы будем хранить таблицу с данными, а в другом массив из которого будем формировать список для выбора цвета.
//массив цветов, для списка (select)
var arr_colors = [
{ id: 1, name: 'Красный'},
{ id: 2, name: 'Синий'},
{ id: 3, name: 'Зеленый'},
];
//таблица с данными, массив объектов
var datasource = [
{ id: 125, firstname: 'Имя 1', lastname: 'Фамилия 1', color_id: 1},
{ id: 133, firstname: 'Имя 2', lastname: 'Фамилия 2', color_id: 2},
{ id: 143, firstname: 'Имя 3', lastname: 'Фамилия 3', color_id: 3},
{ id: 145, firstname: 'Имя 4', lastname: 'Фамилия 4', color_id: 2},
]
Теперь создадим в HTML структуру таблицы. Строки редактируемой таблицы мы будем формировать, используя компонент j-Repeater
. В ячейки, которые мы будем редактировать добавим класс edit
, при этом добавим дополнительные атрибуты тип data-type
и переменную в массиве datasource
, которую будем менять data-field
.
<table class='table table-bordered mv20'>
<!-- Заголовок таблицы --!>
<thead>
<tr>
<th>#</th>
<th>id</th>
<th>Имя</th>
<th>Фамилия</th>
<th style='width:150px'>Цвет</th>
<th></th>
</tr>
</thead>
<!-- используем j-Repeater, используются возможности шаблонизатора TAngular --!>
<tbody data-jc="repeater__datasource" >
<script type="text/html">
<tr data-index="$index">
<td>{{index+1}}</td>
<td>{{id}}</td>
<td class='edit' data-type='textbox' data-field='firstname'>{{firstname}}</td>
<td class='edit' data-type='textbox' data-field='lastname'>{{lastname}}</td>
<td class='edit' data-type='dropdown' data-field='color_id' data-source='arr_colors'>{{color_id|select(arr_colors)}}</td>
<td><button type='button' class='btn btn-danger btn-flat btn-xs' data-bind="rem__click:remRow" data-id='$index' title='Удалить запись'><i class='fa fa-fw fa-remove'></i></button></td>
</tr>
</script>
</tbody>
<!-- строка, которая содержит поля ввода для добавления данных --!>
<tfooter>
<tr>
<th></th>
<th><div data---="textbox__form.id__required:true;type:number;placeholder:id;class:form-control input-sm;"></div></th>
<th><div data---="textbox__form.firstname__required:true;placeholder:Имя;class:form-control input-sm;"></div></th>
<th><div data---="textbox__form.lastname__required:true;placeholder:Фамилия;class:form-control input-sm;"></div></th>
<th><div data---="dropdown__form.color_id__required:true;datasource:arr_colors;text:name;value:id;type:number;class:form-control input-sm;"></div></th>
<th><button type='button' class='btn btn-primary btn-flat btn-xs' data-bind="rem__click:addRow" data-id='$index' title='Добавить запись'><i class='fa fa-fw fa-plus'></i></button></th>
</tr>
</tfooter>
</table>
Теперь в javascript код добавим хелпер, который необходим шаблонизатору. У шаблонизатора TAngular есть одна фишка. Можно создавать любые обработчики и затем использовать их в нужном месте. Наш обработчик, необходим, для того, чтобы по id
из массива мы могли извлечь название цвета. В колонке где выводится цвет, мы используем наш хелпер, вот таким образом {{color_id|select(arr_colors)}}
.
//хелпер, ищет в массиве по id название цвета
Thelpers.select = function(value, arr) {
var res = arr.findItem('id', value);
return (res) ? res.name : '';
};
Теперь немного магии, которая позволит изменять значение ячеек прямо в таблице. Для этого сделаем обработчик. При клике по ячейки с классом edit
будет вызываться это обработчик и в зависимости от дополнительных атрибутов, в ячейку таблицы встроится нужное поле для ввода.
//обработчик сработает при клике по ячейки таблицы с классом edit
$('body').on('click', 'table td.edit', function(e) {
if ($(e.target).closest('select, input, .btn-group, .btn, a').length) return; //определим ряд, той ячейки в котрой произошел клик
var tr = $(this).closest('tr');
//индекс объекта в массиве данных datasource
var ind = tr.data('index');
//тип поля для ввода select или input
var type = $(this).data('type');
//переменная в объекте, которую будем менять
var field = $(this).data('field');
//если select, то определим из какого массива будем формировать список
//для выбора, в нашем случае arr_colors
var source = $(this).data('source');
//если обычный input, то вставим в ячейку компонент j-texbox, в параметрах
//укажем, какое именно свойство менять в массиве с данными для таблицы и в какой строке
if (type=='textbox') {
$(this).html('<div data---="textbox__datasource[{0}].{1}__class:form-control input-sm;keypress:true;"></div>'.format(ind, field));
}
//если select, то вставим компонент j-dropdow, в параметрах
//укажем, какое именно свойство менять в массиве с данными для таблицы и в
//какой строке, также укажем из какого массива сформировать список для выбора цвета
if (type=='dropdown') {
$(this).html('<div data---="dropdown__datasource[{0}].{1}__class:form-control input-sm;required:true;datasource:{2};text:name;value:id;type:number;"></div>'.format(ind, field, source));
}
//так как компоненты добавлены у нас динамически, то для того чтобы
//они заработали необходимо вызвать данный метод
COMPILE();
})
Добавим в js код две функции, одна из которых будет вызываться при нажатии на кнопку <Добавить>, другая же при нажатии на кнопку <Удалить строку>.
//добавление записи в таблицу
function addRow(e) {
//проверим форму на ошибки, если есть ошибки прервем добавление записи
if (!VALIDATE('form.*')) return;
//добавим запись в конец массива datasource
PUSH('datasource', form);
//очистим форму
SET('form', null);
RESET('form.*');
}
//удалим запись из таблицы
function remRow(e) {
//определим индекс строки в таблице и соответственно в массиве
var tr = $(e).closest('tr');
var ind = tr.data('index');
//удалим из массива объект по опрделенному индексу
datasource.splice(ind, 1);
//обновим массив
UPDATE('datasource');
}
Вот собственно говоря и все, готово.
Итак, таблица будет создана с использованием компонента j-Repeater
. При клике на ячейке с классом edit
вызовется обработчик, после чего в ячейку будет вставлен компонент для ввода данных j-Textbox
или j-Dropdown
. Как только будет осуществлен ввод, и массив с объектами datasource
будет обновлен, автоматически произойдет перерисовка таблицы.
See the Pen Table editable by Saper639 (@saper639) on CodePen.