Хочу рассказать о своих мытарствах при использовании библиотеки x-editable совместно с select2 для редактирования данных в таблице dataTablesЧасть вторая
Дано: данные демонстрируются на странице посредством dataTables и нужно прямо в таблице, не переходя к отдельным записям редактировать изменчивые данные.
К примеру в таблице задач надо выбрать или поменять исполнителя для этой задачи и редактировать некоторые числовые факторы, которые нужны для выполнения и контроля выполнения задачи.
Выводим данные в таблицу и прицепляем свежие версии библиотек x-editable и select2.
По мануалу вешаем редактирование на числовые данные.
''+id+'' $('.dataTable a.x-edit-number').editable({ url : '/tasks/edit-field/', type : 'text', inputclass : 'input-small form-control', defaultValue : '0', validate: function(value) { if($.trim(value) > '' && parseInt(value) != value) { return 'Введите целое число'; } } });
Отлично запустилось сразу же. По клику всплывает поле для редактирования, можно изменить и сохранить, есть возможность отменить редактирование.
Не все так радужно оказалось с выбором из списка.
Подгружать данные для списка при загрузке страницы, на случай если пригодится для редактирования — довольно глупо. Совершенно не нужна нам дополнительная нагрузка на сервер.
Подгружать исполнителей правильно будет — только в случае необходимости, когда уже кликнули на ячейку таблицы, непосредственно перед открытием плашки редактирования.
Эти данные не должны загружаться повторно при выборе исполнителей для других задач. Возможных исполнителей у нас под 50, поэтому select должен быть с поиском. На этом этапе анализа требований — просто select отвалился, самый подходящий вариант — select2.
Вот тут-то и началось самое интересное.
Пробуем запустить — код подобный вышеприведенному, только type : ‘select2’ и задаем source : ‘/users/automoplete/empls/’ — по этому адресу сайт отдает json массив со списком исполнителей, каждый элемент массива представляет собой object вида {id:’99’, text:’Имя исполнителя’}.
Щелкаем на стрелочку открытия select-элемента — происходит подгрузка списка исполнителей. Поле поиска присутствует, все исполнители на месте — доступны для выбора.
Но один взгляд в консоль разработчика — обозначил проблему — каждое открытие списка в плашке редактирования предваряется запросом на сервер для очередного получения списка всех исполнителей. В каждый запрос подставляется get параметр ?query=.
Пробуем включить кеширование — добавляем в конфигурацию editable секцию select2
$('.dataTable a.x-edit-select2').editable({ ... select2 : { cache : true, minimumResultsForSearch : 7, placeholder : 'Выберите исполнителя', allowClear : true } });
Полный вариант инициализации опубликую, после того, как будет готов окончательный вариант.
Не помогло — постоянные запросы на сервер при каждом телодвижении.
Ну что ж — придется позаботиться о кешировании самому.
То есть при клике на ячейку нам не надо, чтобы сразу открывалась плашка редактирования, сначала мы подгружаем список исполнителей, засовываем его в source и только потом показываем плашку.
$('.dataTable a.x-edit-select2').click(function() { // инициализацию и вызов плашки // редактирования лучше вынести // в отдельную функцию, чтобы не дублировать код // для инициализации в случаях, когда список // запрашивается и когда уже закеширован function showEditForm(data) { // инициализируем editable только // один раз для ячейки if (!cell.data('source-setted')) { cell.editable({ url : '/tasks/edit-field/', type : 'select2', inputclass : 'form-control input-medium', toggle : 'manual', source : data, emptytext : '', select2 : { minimumResultsForSearch : 7, placeholder : 'Выберите исполнителя', allowClear : true } }); cell.data('source-setted', true); } cell.editable('show'); } var cell = $(this); // чтобы не загаживать глобальное пространство имен, // все свое пакуем в объект App // проверяем объявлен ли он уже if (typeof App == 'undefined') var App = {}; if (typeof App.cache == 'undefined') App.cache = {}; // если списка еще нет if (typeof App.cache.empls == 'undefined') { cell.addClass('loading'); url = '/users/autocomplete/empls/'; $.post( url, {}, function(answ) { cell.removeClass('loading'); answ = App.parseJSON(answ); if (answ !== false) App.cache.empls = answ; showEditForm(App.cache.empls); }, 'text' ); // список уже получен, надо только инициализировать // (если необходимо) // и открыть плашку редактирования } else { showEditForm(App.cache.empls); } return false; });
Работает! Запрос на сервер только один, поиск отрабатывает как положено, повторных запросов на сервер не производится.
Но остается еще несколько неприятных моментов, которые надо устранить, чтобы было действительно удобно для использования.
О них в следующей части →.