jComponent - Редактируемая таблица

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.


Ссылки:

Категории