knockoutjs. Интеграция chosen

Для меня навсегда останется загадкой, почему разработчики браузеров не потрудились создать красивый выпадающий списко select. К счастью, есть плагин chosen, который успещно заменяет стандартные списки. Именно о его интеграции knockoutjs и пойдет речь.

Прежде, чем изобретать собственный велосипед я обратился к всезнающему (и потому пугающему) гуглу и нашел тех, кто уже сталкивался с подобной проблемой Does not work with Knockout.js и её решение. Там же можно найти ссылку на рабочий пример, однако не сложно убедиться, что он не работает, достаточно для первого списка так же указать knockout.binding chosen

Итак, нужно создать custom binding, который позволит использовать привязку данных knockoutjs и интерфейс chosen. После нескольких попыток у меня получилось следующее

  1. ko.bindingHandlers.chosen =
  2. {
  3. init: function(element)
  4. {
  5. $(element).addClass('chzn-select');
  6. $(element).chosen();
  7. },
  8. update: function(element)
  9. {
  10. $(element).trigger('liszt:updated');
  11. }
  12. };

Для вызова использовался вот такой код

  1. data-bind="options: items,
  2. optionsText: 'name',
  3. optionsCaption: 'Select item...',
  4. value: selectedItem,
  5. chosen: {}"

Однако код не заработал, так как мне было нужно, потому что не обновлялось привязанное значение при изменении значения в списке. Стоило убрать вызов chosen и все работало, как часы. Но каждая попытка использовать плагин снова приводила к неудаче, selectedItem не изменял своекл значения.

Оказалось, что knockout не устанавливает атрибут value, а без него chosen не отличет один элемент от другого и потому не посылает сообщение о новом значении селектора. Решить проблему со стороны knockout не получилось и потому пришлось править файл chosen.jquery.js

Потребовалось изменить лишь одну строку, отключив проверку на изменение value в методе Chosen.prototype.result_select

  1. //if (this.is_multiple || this.form_field_jq.val() !== this.current_value)
  2. {
  3. this.form_field_jq.trigger("change", {
  4. 'selected': this.form_field.options[item.options_index].value
  5. });
  6. }
  7.  

Посмотреть, как все это работает можно на jsFiddle

Читайте в блоге

Knockout JS. Определение собственных связываний (custom binding)
jsFiddle. Тестирование JSONP

Комментарии:

Vladimir Rybakov @ 18.09.2012 00:52

Сам себе оставлю комментарий по поводу аналога для Chosen

http://ivaynberg.github.com/select2/

Кстати, у меня почему-то логинза перестала с контактом работать.

Войдите на сайт, чтобы оставить комментарий