Подгрузку данных по ajax с кешированием мы решили ранее (часть первая).
Осталось еще несколько неудобных моментов.
Во-первых: сам факт выбора пункта в выпадающем списке уже является подтверждением желания заменить исполнителя на выбранного, кнопа «сохранить» на плашке нам не нужна.
Во-вторых: Плашка закрывается кликом на любом месте вне плашки и по нажатию на Esc. Кнопа «Закрыть» тоже не нужна.
Ну, с этим вроде просто, добавляем 2 строчки в конфигурацию:
cell.editable({ ... showbuttons : false, saveonchange : true, ... });
В третьих: Select должен открываться автоматически при появлении плашки. Совершенно ни к чему заставлять человека делать лишние бессмысленные клики. Раз кликнули для редактирования, список должен быть виден незамедлительно. Фокус должен быть установлен в поле для поиска при достаточном количестве результатов.
На вопрос — как это сделать? — мануал ответа не дал. Значит будем решать проблему подручными средствами. Выясняем селектор, однозначно указывающий на select2 в появившейся плашке и даем команду на открытие сразу же после команды cell.editable(‘show’);
elem.editable('show'); $('.editable-popup:visible input[type=hidden]').select2('open');
Тестируем. Хмм… вот это глюк!
При клике вне плашки и попытке смены исполнителя для другой записи появляется аж 2 списка, один, как положено из select на плашке, а второй на месте, где открывался только что закрывшийся список. и Курсор мерцает между двумя полями поиска. Выглядит ужасно!
Смотрим, что там в исходном коде: вот и наши 2 списка. Один из них от уже исчезнушей плашки.
Может удалить старый выпадающий список перед тем как показывать новый?
$('.select2-drop').remove(); elem.editable('show'); $('.editable-popup:visible input[type=hidden]').select2('open');
Вот это прикол! Нифига не изменилось! По прежнему вылезает 2 списка. Что-то реанимирует уже удаленный список. Получается, что на момент открытия новой плашки редактирования старый select2 еще жив и в процессе скрытия плашки редактирования от предыдущей записи выпадающий список для нее восстанавливается, прежде, чем select2 пропадет из кода страницы. То есть какое-то время на странице существует 2 разных select2 в контейнерах с классом editable-popup, причем оба контейнера находятся на странице и оба еще видимы уже после открытия второго.
Есть смысл дать некоторую задержку по времени перед открытием нового выпадающего списка. Начнем с задержки 200 мс, думаю, что 100 может быть недостаточно и при этом 200 мс все еще практически неощутимая задержка.
elem.editable('show'); window.setTimeout(function() { $('.editable-popup:visible input[type=hidden]').select2('open'); }, 200);
Отлично! От глюка избавились.
Осталась последняя хотелка: по какой-то причине select2 появляется с пустым значением, а должен появиться с выбранным текущим исполнителем. Чтобы для снятия исполнителя достаточно было кликнуть по крестику очистки.
То есть перед .select2(‘open’) нам надо отыскать id выбранного исполнителя в массиве App.cache.empls и задать значение для списка — .select2(‘val’, id)
Финальный код инициализации редактирования:
$('.dataTable a.x-edit-select2').click(function() { // инициализацию и вызов плашки // редактирования лучше вынести // в отдельную функцию, чтобы не дублировать код // для инициализации в случаях, когда список // запрашивается и когда уже закеширован function showEditForm() { // инициализируем editable только // один раз для ячейки if (!cell.data('source-setted')) { cell.editable({ url : '/tasks/edit-field/', type : 'select2', inputclass : 'form-control input-medium', toggle : 'manual', source : App.cache.empls, emptytext : '', showbuttons : false, saveonchange : true, select2 : { minimumResultsForSearch : 7, placeholder : 'Выберите исполнителя', allowClear : true } }); cell.data('source-setted', true); } cell.editable('show'); window.setTimeout(function() { var text, id; text = elem.text(); for (var i in App.cache.empls) if (App.cache.empls[i].text == text) { id = App.cache.empls[i].id; break; } $('.editable-popup:visible input[type=hidden]').select2('val', id).select2('open'); }, 200); } 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; });