初始上传
This commit is contained in:
152
public/static/ext/searchable_select/searchable_select.css
Executable file
152
public/static/ext/searchable_select/searchable_select.css
Executable file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Author: David Qin
|
||||
E-mail: david@hereapp.cn
|
||||
Date: 2014-11-05
|
||||
*/
|
||||
.searchable-select-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.searchable-select {
|
||||
display: inline-block;
|
||||
min-width: 200px;
|
||||
max-width: 340px;
|
||||
color: #333;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
outline: none;
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
/*font-size: 12px;*/
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.searchable-select-holder {
|
||||
padding: 4px 20px 4px 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #eceef1;
|
||||
/* border-radius: 4px; */
|
||||
min-height: 34px;
|
||||
box-sizing: border-box;
|
||||
/* -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); */
|
||||
/* box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); */
|
||||
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
width: 310px;
|
||||
}
|
||||
|
||||
.searchable-select-caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-width: 6px;
|
||||
border-color: transparent;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
margin-top: -3px;
|
||||
cursor: pointer;
|
||||
border-top-color: #c2c2c2;
|
||||
border-top-style: solid;
|
||||
transition: all .3s;
|
||||
-webkit-transition: all .3s;
|
||||
}
|
||||
|
||||
.searchable-select-caret.selected {
|
||||
margin-top: -9px;
|
||||
-webkit-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.searchable-select-dropdown {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
padding: 4px;
|
||||
border-top: none;
|
||||
top: 28px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 7;
|
||||
}
|
||||
|
||||
.searchable-select-input {
|
||||
border: 1px solid #ccc !important;
|
||||
outline: none;
|
||||
padding: 4px !important;
|
||||
width: 100% !important;
|
||||
box-sizing: border-box;
|
||||
height: 25px !important;
|
||||
border-radius: 0 !important;
|
||||
margin: 5px 0 0 0 !important;
|
||||
}
|
||||
|
||||
.searchable-scroll {
|
||||
margin-top: 4px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.searchable-scroll.has-privious {
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
.searchable-scroll.has-next {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.searchable-has-privious {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.searchable-has-next {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.searchable-has-privious, .searchable-has-next {
|
||||
height: 16px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
z-index: 10;
|
||||
background-color: white;
|
||||
line-height: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.searchable-select-items {
|
||||
max-height: 400px;
|
||||
overflow-y: scroll;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.searchable-select-items::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.searchable-select-item {
|
||||
padding: 5px 5px;
|
||||
cursor: pointer;
|
||||
min-height: 36px;
|
||||
box-sizing: border-box;
|
||||
transition: all 0.5s ease 0s;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.searchable-select-item.hover {
|
||||
background: var(--base-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.searchable-select-item.selected {
|
||||
background: var(--base-color);
|
||||
color: white;
|
||||
}
|
||||
292
public/static/ext/searchable_select/searchable_select.js
Executable file
292
public/static/ext/searchable_select/searchable_select.js
Executable file
@@ -0,0 +1,292 @@
|
||||
// Author: David Qin
|
||||
// E-mail: david@hereapp.cn
|
||||
// Date: 2014-11-05
|
||||
|
||||
(function ($) {
|
||||
|
||||
// a case insensitive jQuery :contains selector
|
||||
$.expr[":"].searchableSelectContains = $.expr.createPseudo(function (arg) {
|
||||
return function (elem) {
|
||||
if (arg) return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
|
||||
else $(".searchable-select-items>div").removeClass("searchable-select-hide");
|
||||
};
|
||||
});
|
||||
|
||||
$.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();
|
||||
//回车回调
|
||||
if (_this.options.enterCallback) _this.options.enterCallback(_this.input);
|
||||
_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();
|
||||
//监听搜索输入框回调
|
||||
if (_this.options.inputKeyUpCallback) _this.options.inputKeyUpCallback($(this));
|
||||
})
|
||||
}
|
||||
|
||||
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.holder = $('<input type="text" readonly class="searchable-select-holder" placeholder="' + (_this.options.placeholder ? _this.options.placeholder : "") + '" />');
|
||||
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 = $('<i class="layui-edge searchable-select-caret"></i>');
|
||||
|
||||
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');
|
||||
this.items.find('.searchable-select-item:searchableSelectContains(' + text + ')').removeClass('searchable-select-hide');
|
||||
if (this.currentSelectedItem && 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 && !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 () {
|
||||
if ($(this).text().length == 0) return;
|
||||
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();
|
||||
|
||||
//选择option后执行回调
|
||||
if (_this.options.optionCallback) {
|
||||
var value = $(this).attr("data-value");
|
||||
var text = $(this).text();
|
||||
_this.options.optionCallback(value, text);
|
||||
}
|
||||
});
|
||||
|
||||
_this.items.append(item);
|
||||
});
|
||||
|
||||
this.items.on('scroll', function () {
|
||||
_this.setPriviousAndNextVisibility();
|
||||
})
|
||||
},
|
||||
show: function () {
|
||||
this.dropdown.removeClass('searchable-select-hide');
|
||||
this.input.focus();
|
||||
this.status = 'show';
|
||||
this.caret.addClass("selected");//下三角
|
||||
this.setPriviousAndNextVisibility();
|
||||
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
if (!(this.status === 'show'))
|
||||
return;
|
||||
|
||||
if (this.items.find(':not(.searchable-select-hide)').length === 0)
|
||||
this.input.val('');
|
||||
this.dropdown.addClass('searchable-select-hide');
|
||||
this.searchableElement.trigger('focus');
|
||||
this.status = 'hide';
|
||||
this.caret.removeClass("selected");//下三角
|
||||
},
|
||||
|
||||
hasCurrentSelectedItem: function () {
|
||||
return this.currentSelectedItem && this.currentSelectedItem.length > 0;
|
||||
},
|
||||
|
||||
selectItem: function (item) {
|
||||
if (this.hasCurrentSelectedItem())
|
||||
this.currentSelectedItem.removeClass('selected');
|
||||
|
||||
this.currentSelectedItem = item;
|
||||
item.addClass('selected');
|
||||
|
||||
this.hoverItem(item);
|
||||
this.holder.val(item.text());
|
||||
|
||||
var value = item.data('value');
|
||||
this.holder.data('value', value);
|
||||
this.element.val(value);
|
||||
|
||||
if (this.options.afterSelectItem) {
|
||||
this.options.afterSelectItem.apply(this);
|
||||
}
|
||||
},
|
||||
|
||||
hasCurrentHoverItem: function () {
|
||||
return this.currentHoverItem && this.currentHoverItem.length > 0;
|
||||
},
|
||||
|
||||
hoverItem: function (item) {
|
||||
if (this.hasCurrentHoverItem())
|
||||
this.currentHoverItem.removeClass('hover');
|
||||
|
||||
if (item.outerHeight() + item.position().top > this.items.height())
|
||||
this.items.scrollTop(this.items.scrollTop() + item.outerHeight() + item.position().top - this.items.height());
|
||||
else if (item.position().top < 0)
|
||||
this.items.scrollTop(this.items.scrollTop() + item.position().top);
|
||||
|
||||
this.currentHoverItem = item;
|
||||
item.addClass('hover');
|
||||
},
|
||||
|
||||
setPriviousAndNextVisibility: function () {
|
||||
if (this.items.scrollTop() === 0) {
|
||||
this.hasPrivious.addClass('searchable-select-hide');
|
||||
this.scrollPart.removeClass('has-privious');
|
||||
} else {
|
||||
this.hasPrivious.removeClass('searchable-select-hide');
|
||||
this.scrollPart.addClass('has-privious');
|
||||
}
|
||||
|
||||
if (this.items.scrollTop() + this.items.innerHeight() >= this.items[0].scrollHeight) {
|
||||
this.hasNext.addClass('searchable-select-hide');
|
||||
this.scrollPart.removeClass('has-next');
|
||||
} else {
|
||||
this.hasNext.removeClass('searchable-select-hide');
|
||||
this.scrollPart.addClass('has-next');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.searchableSelect = function (options) {
|
||||
var sS;
|
||||
this.each(function () {
|
||||
sS = new $sS($(this), options);
|
||||
});
|
||||
return sS;//返回当前对象,那边接收到后可以进行后期的修改对象操作
|
||||
//return this;//以前的
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user