Всем привет!
В черновиках завалялась статья, которую долгое время не мог довести до публикации. Наконец-то, решил выделить время и выложить её для всеобщего обозрения. Помнится в своё время очень радовался, что разобрался с описываемой проблемой. Это была один из “висяков”, которые нужно было разрешить. С чем я успешно и справился (сам себя не похвалишь… =)). И хотя, заказчик до сих пор полностью не рассчитался за объем выполненных работ, определенный опыт получен. Собственно, им и делюсь. Надеюсь, кому-то поможет.
На первый взгляд, в заголовке статьи – непонятный набор английских слов. Или для кого-то, возможно, понятны сами слова, но не суть проблемы. Сама же проблема, скорей всего, будет интересна довольно узкому кругу программистов, но те кто столкнутся с ней и найдут здесь решение, думаю, будут очень благодарны. Я сам потратил прилично времени пока разобрался что к чему.
Итак, о чем же речь? Озаглавить статью более расширенно можно таким образом: “Проблема jQuery клонирования селектов chosen”. Ясней, наверное, не стало, поэтому давайте по порядку.
1. jQuery clone.
В jQuery есть функция клонирования элементов – clone. Как пишут в документации: “clone создаёт полную копию набора элементов”. Т.е. функция clone позволяет дублировать целые блоки со всем содержимым. Например, у вас есть блок <div class=”mydiv”></div>, внутри которого расположены всяческие инпуты, селекты, чекбоксы.
В некоторых случаях, когда на странице нужен еще один (или несколько) аналогичный блок, то очень удобно не создавать их вновь, а произвести копирование уже существующего блока. Как раз это и позволяет сделать jQuery функция clone:
1 2 3 |
$('.mydiv').clone(true).appendTo(".container"); |
Данный код скопирует блок(блоки) с классом class=”mydiv” и добавит их в блок с классом class=”container”.
На этом первый пункт закончу. Подробней, думаю, не стоит описывать, поскольку моя задача в данной статье не рассказать о функции clone, а описать решение конкретной проблемы, суть которой опишу чуть ниже. А те, кто столкнулся с этой ситуацией, скорей всего, знают как работает функция clone и без моих разъяснений.
2. Chosen select.
Chosen – javascript плагин, который делает выпадающие списки select более красивыми и дружественными для пользователя. Для использования этого плагина нужно подключить файл плагина chosen.min.js и потом в коде для нужных селектов (конкретных или сразу всех – это вы определяете в jQuery селекторе) применить функцию chosen(), например, вот так:
1 2 3 |
$('select').chosen(); |
3. jQuery clone chosen select.
Теперь объединим пункты 1 и 2 и получим суть проблемы:
Если вы произведете клонирование select, который “улучшен” с помощью плагина chosen, то увидите, что при попытке взаимодействия с полученной копией селекта вас будет отправлять к родителю данного клона.
Чтобы исправить эту проблему нужно заново проинициализировать chosen select. Т.е., сначала удалить из полученной копии элемента классы и атрибуты, относящиеся к chosen, а потом произвести инициализацию chosen для данного элемента.
Вот пример кода благодаря которому я разобрался с описываемой проблемой (источник):
1 2 3 4 |
$("#" + currentRow+ " select").removeClass("chzn-done").removeAttr("id").css("display", "block").next().remove(); $("#" + currentRow+ " select").chosen(); |
А вот как я применил это в своей задаче:
1 2 3 4 5 6 |
var dd = $(ev.target).parents('.edit_p_f_desc:first'); var dd2 = dd.clone(true); dd2.find('.sel_w:first select').removeClass("chzn-done").removeAttr("id").css("display", "block").next().remove(); dd2.find('.sel_w:first select').chosen(); |
Пока всё. До новых публикаций.
Успехов в решении задач!