Download:
child 1:73d980e47217
0:b09cdd220793
Anton Shestakov <engored@ya.ru>, Sun, 05 May 2013 20:10:51 +0900
Working prototype.

1 файлов изменено, 139 вставок(+), 0 удалений(-) [+]
jquery.lensy.js file | annotate | diff | comparison | revisions
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jquery.lensy.js Sun May 05 20:10:51 2013 +0900
@@ -0,0 +1,139 @@
+(function($) {
+ "use strict";
+
+ var settings, $select, $widget, $modal, $filter, $container, $closeButton;
+
+ function Lensy(element, options) {
+ $select = $(element);
+ settings = $.extend({}, $.fn.lensy.defaults, options);
+
+ this.build();
+ this.bindEvents();
+ }
+
+ Lensy.prototype = {
+ build: function() {
+ $widget = $('<ul>').addClass(settings.widgetClass);
+ $modal = $('<div>').addClass(settings.modalClass).hide();
+ $filter = $('<input>').attr('type', 'text').addClass(settings.filterClass);
+ $container = $('<ul>').addClass(settings.containerClass);
+ $closeButton = $('<a>').text(settings.closeButtonText).addClass(settings.closeButtonClass);
+
+ $select.hide();
+
+ $widget
+ .insertAfter($select);
+
+ $modal
+ .append($filter)
+ .append($container)
+ .append($closeButton)
+ .appendTo('body');
+ },
+
+ show: function() {
+ $modal.show();
+ $filter.focus();
+ },
+
+ hide: function() {
+ $modal.hide();
+ },
+
+ bindEvents: function() {
+ $widget.click($.proxy(this.show, this));
+
+ $closeButton.click($.proxy(this.hide, this));
+
+ // $item in $container gets clicked on
+ var itemSelected = function() {
+ var $item = $(this);
+ var value = $item.attr('data-original-value');
+ var values = $select.val() || [];
+
+ if (values.indexOf(value) == -1) {
+ $select.val(values.concat(value));
+ } else {
+ $select.val($.grep(values, function(v) { return v != value; }));
+ }
+
+ $select.trigger('change');
+ };
+
+ // $container is populated with $items
+ $select.find('option').each(function() {
+ var $option = $(this);
+ var $item = $('<li>').addClass(settings.itemClass);
+
+ $item.attr('data-original-value', $option.val());
+ $item.html(settings.itemFn($option.val()));
+ $container.append($item);
+
+ $item.on('click', itemSelected);
+ });
+
+ var update = function() {
+ var values = $select.val() || [];
+
+ $widget.empty();
+ $container.find('[data-original-value]').each(function() {
+ var $item = $(this);
+ var value = $item.attr('data-original-value');
+
+ if (values.indexOf(value) == -1) {
+ $item.removeClass(settings.itemActiveClass);
+ } else {
+ $item.addClass(settings.itemActiveClass);
+
+ var $widgetItem = $('<li>').addClass(settings.itemClass);
+ $widgetItem.html((settings.widgetItemFn || settings.itemFn)(value));
+ $widget.append($widgetItem);
+ }
+ });
+ };
+
+ $select.on('change', update);
+ update();
+
+ var filter = function() {
+ $container.find('[data-original-value]').each(function() {
+ var $item = $(this);
+ var value = $item.attr('data-original-value');
+ if (settings.filterFn($filter.val(), value, $item)) {
+ $item.show();
+ } else {
+ $item.hide();
+ }
+ });
+ };
+
+ $filter.on('change keyup', filter);
+ filter();
+
+ return this;
+ }
+ };
+
+ $.fn.lensy = function(options) {
+ return this.each(function() {
+ if (!$.data(this, 'lensy')) {
+ $.data(this, 'lensy', new Lensy(this, options));
+ }
+ });
+ };
+
+ $.fn.lensy.defaults = {
+ // escape action: close / clean filter
+ containerClass: 'lensy-container',
+ closeButtonText: 'Close',
+ closeButtonClass: 'lensy-button',
+ modalClass: 'lensy-modal',
+ filterClass: 'lensy-filter',
+ widgetClass: 'lensy-widget',
+ itemClass: 'lensy-item',
+ itemActiveClass: 'active',
+ itemFn: function(value) { return $('<span>').text(value); },
+ widgetItemFn: undefined,
+ filterFn: function(filterString, value) { return value.toLowerCase().indexOf(filterString.toLowerCase()) != -1; }
+ };
+})(jQuery);