(function ($) {
// a case insensitive jQuery :contains selector
// $.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) {
// return function( elem ) {
// return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
// };
// });
$.expr[":"].searchableSelectContains = $.expr.createPseudo(function (arg) {
return function (elem) {
var pinyin = ConvertPinyin($(elem).text());
var firstWord = makePy($(elem).text())[0];
if ($(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0)
return true;
if (pinyin.toUpperCase().indexOf(arg.toUpperCase()) >= 0)
return true;
if (firstWord.toUpperCase().indexOf(arg.toUpperCase()) >= 0)
return true;
return false;
};
});
/*$.expr[":"].searchableSelectContains = function(obj,index,meta){
return $(obj).text().toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
};*/
$.searchableSelect = function (element, options) {
this.element = element;
this.options = options || {};
this.init();
var _this = this;
this.searchableElement.click(function (event) {
// event.stopPropagation();
_this.show();
}).on('keydown', function (event) {
if (event.which === 13 || event.which === 40 || event.which == 38) {
event.preventDefault();
_this.show();
}
});
$(document).on('click', null, function (event) {
if (_this.searchableElement.has($(event.target)).length === 0)
_this.hide();
});
this.input.on('keydown', function (event) {
event.stopPropagation();
if (event.which === 13) { //enter
event.preventDefault();
_this.selectCurrentHoverItem();
_this.hide();
} else if (event.which == 27) { //ese
_this.hide();
} else if (event.which == 40) { //down
_this.hoverNextItem();
} else if (event.which == 38) { //up
_this.hoverPreviousItem();
}
}).on('keyup', function (event) {
if (event.which != 13 && event.which != 27 && event.which != 38 && event.which != 40)
_this.filter();
})
}
var $sS = $.searchableSelect;
$sS.fn = $sS.prototype = {
version: '0.0.1'
};
$sS.fn.extend = $sS.extend = $.extend;
$sS.fn.extend({
init: function () {
var _this = this;
this.element.hide();
this.searchableElement = $('<div tabindex="0" class="searchable-select"></div>');
this.holder = $('<div class="searchable-select-holder"></div>');
this.dropdown = $('<div class="searchable-select-dropdown searchable-select-hide"></div>');
this.input = $('<input type="text" class="searchable-select-input" />');
this.items = $('<div class="searchable-select-items"></div>');
this.caret = $('<span class="searchable-select-caret"></span>');
this.scrollPart = $('<div class="searchable-scroll"></div>');
this.hasPrivious = $('<div class="searchable-has-privious">...</div>');
this.hasNext = $('<div class="searchable-has-next">...</div>');
this.hasNext.on('mouseenter', function () {
_this.hasNextTimer = null;
var f = function () {
var scrollTop = _this.items.scrollTop();
_this.items.scrollTop(scrollTop + 20);
_this.hasNextTimer = setTimeout(f, 50);
}
f();
}).on('mouseleave', function (event) {
clearTimeout(_this.hasNextTimer);
});
this.hasPrivious.on('mouseenter', function () {
_this.hasPriviousTimer = null;
var f = function () {
var scrollTop = _this.items.scrollTop();
_this.items.scrollTop(scrollTop - 20);
_this.hasPriviousTimer = setTimeout(f, 50);
}
f();
}).on('mouseleave', function (event) {
clearTimeout(_this.hasPriviousTimer);
});
this.dropdown.append(this.input);
this.dropdown.append(this.scrollPart);
this.scrollPart.append(this.hasPrivious);
this.scrollPart.append(this.items);
this.scrollPart.append(this.hasNext);
this.searchableElement.append(this.caret);
this.searchableElement.append(this.holder);
this.searchableElement.append(this.dropdown);
this.element.after(this.searchableElement);
this.buildItems();
this.setPriviousAndNextVisibility();
},
filter: function () {
var text = this.input.val();
this.items.find('.searchable-select-item').addClass('searchable-select-hide');
if (text != '') {
this.items.find('.searchable-select-item:searchableSelectContains(' + text + ')').removeClass('searchable-select-hide');
} else {
this.items.find('.searchable-select-item').removeClass('searchable-select-hide');
}
if (this.currentSelectedItem.hasClass('searchable-select-hide') && this.items.find('.searchable-select-item:not(.searchable-select-hide)').length > 0) {
this.hoverFirstNotHideItem();
}
this.setPriviousAndNextVisibility();
},
hoverFirstNotHideItem: function () {
this.hoverItem(this.items.find('.searchable-select-item:not(.searchable-select-hide)').first());
},
selectCurrentHoverItem: function () {
if (!this.currentHoverItem.hasClass('searchable-select-hide'))
this.selectItem(this.currentHoverItem);
},
hoverPreviousItem: function () {
if (!this.hasCurrentHoverItem())
this.hoverFirstNotHideItem();
else {
var prevItem = this.currentHoverItem.prevAll('.searchable-select-item:not(.searchable-select-hide):first')
if (prevItem.length > 0)
this.hoverItem(prevItem);
}
},
hoverNextItem: function () {
if (!this.hasCurrentHoverItem())
this.hoverFirstNotHideItem();
else {
var nextItem = this.currentHoverItem.nextAll('.searchable-select-item:not(.searchable-select-hide):first')
if (nextItem.length > 0)
this.hoverItem(nextItem);
}
},
buildItems: function () {
var _this = this;
this.element.find('option').each(function () {
var item = $('<div class="searchable-select-item" data-value="' + $(this).attr('value') + '">' + $(this).text() + '</div>');
if (this.selected) {
_this.selectItem(item);
_this.hoverItem(item);
}
item.on('mouseenter', function () {
$(this).addClass('hover');
}).on('mouseleave', function () {
$(this).removeClass('hover');
}).click(function (event) {
event.stopPropagation();
_this.selectItem($(this));
_this.hide();
});
_this.items.append(item);
});
this.items.on('scroll', function () {
评论0