pl.editabledropdown.css
使用:
.editabledropdown {
position: relative;
display: inline-block;
padding: 0;
font-size: 13px;
}
.editabledropdown .selections {
width: 100px;
}
.editabledropdown .dropdowninput {
position: absolute;
top: 1px;
left: 1px;
border: none;
}
.editabledropdown .autocomplete_suggestions {
margin: 0;
padding: 0;
border: solid 1px #ccc;
position: absolute;
display: none;
overflow-y: auto;
overflow-x: hidden;
max-height: 105px;
}
.editabledropdown .autocomplete_suggestions li {
padding: 0 3px 0 2px;
white-space: nowrap;
width: 100%;
font-size: 12px;
cursor: pointer;
}
.editabledropdown .autocomplete_suggestions li {
color: black;
background-color: white;
}
.editabledropdown .autocomplete_suggestions li .hit {
color: red;
}
.editabledropdown .autocomplete_suggestions li.selected {
color: white;
background-color: #3399ff;
}
pl.editabledropdown.js
window.pl = window.pl || {};
window.pl.editableDropDown = function (config) {
this._keys = { up: 38, down: 40, enter: 13, tab: 9, esc: 27 };
this.config = $.extend({
dropDownArrowWidth: 20,
selectionTextField: "text",
selectionValueField: "id",
selectionChange: function (e) {
e.data.value = e.data.selections.val();
e.data.dropDownInput.val($("option:selected", e.data.selections).text());
},
inputPlaceHolder: "",
inputFocus: function (e) {
if ($("li", e.data.suggestions).length > 0) {
e.data.suggestionOnfocus = false;
e.data.suggestions.show();
}
},
inputBlur: function (e) {
window.setTimeout(function () {
if (!e.data.suggestionOnfocus) {
e.data.suggestions.hide();
e.data.dropDownInput.val($("option:selected", e.data.selections).text());
}
}, 300);
},
inputKeydown: function (e) {
var len = 0, idx = -1;
switch (e.which || e.keyCode) {
case e.data._keys.tab:
case e.data._keys.enter:
if (e.data.suggestions.is(":visible")) {
var selected = $("li.selected", e.data.suggestions);
if (selected.length > 0) {
e.data.suggestionOnfocus = true;
e.data.value = $(selected[0]).attr("value");
e.data.dropDownInput.val($(selected[0]).text());
e.data.suggestions.hide();
if (e.data.config.autocomplete && typeof e.data.config.autocomplete === "function") {
e.data.config.autocomplete(e.data, selected[0]);
}
}
}
return false;
case e.data._keys.up:
if (e.data.suggestions.is(":visible")) {
len = $("li", e.data.suggestions).length;
if (len > 1) {
idx = $("li.selected", e.data.suggestions).index();
if (idx < 1) {
idx = len - 1;
}
else {
idx--;
}
$("li.selected", e.data.suggestions).removeClass("selected");
$("li:eq(" + idx + ")", e.data.suggestions).addClass("selected");
}
else if (len === 1) {
$("li:eq(0)", e.data.suggestions).addClass("selected");
}
}
else {
len = $("option", e.data.selections).length;
if (len > 1) {
idx = $("option:selected", e.data.selections).index();
if (idx < 1) {
idx = len - 1;
}
else {
idx--;
}
$("option:selected", e.data.selections).removeAttr("selected");
$("option:eq(" + idx + ")", e.data.selections).attr("selected", "selected");
}
else {
$("option:eq(0)", e.data.selections).attr("selected", "selected");
}
}
return false;
case e.data._keys.down:
if (e.data.suggestions.is(":visible")) {
len = $("li", e.data.suggestions).length;
if (len > 1) {
idx = $("li.selected", e.data.suggestions).index();
if (idx < len - 1) {
idx++;
}
else {
idx = 0;
}
$("li.selected", e.data.suggestions).removeClass("selected");
$("li:eq(" + idx + ")", e.data.suggestions).addClass("selected");
}
else if (len === 1) {
$("li:eq(0)", e.data.suggestions).addClass("selected");
}
}
else {
len = $("option", e.data.selections).length;
if (len > 1) {
idx = $("option:selected", e.data.selections).index();
if (idx < len - 1) {
idx++;
}
else {
idx = 0;
}
$("option:selected", e.data.selections).removeAttr("selected");
$("option:eq(" + idx + ")", e.data.selections).attr("selected", "selected");
}
else {
$("option:eq(0)", e.data.selections).attr("selected", "selected");
}
}
return false;
case e.data._keys.esc:
e.data.suggestions.hide();
return false;
}
},
inputKeyup: function (e) {
var ch = e.keyCode || e.which;
for (var k in e.data._keys) {
if (e.data._keys[k] === ch) {
return;
}
}
e.data.value = "";
var v = e.data.dropDownInput.val();
if (v) {
e.data.suggestions.empty();
if (e.data.config.autocompleteAjax && typeof e.data.config.autocompleteAjax === "function") {
$.ajax(e.data.config.autocompleteAjax(e.data));
}
else {
var s = null, h, t = null, idx = 0, str = null;
$("option", e.data.selections).each(function (i, o) {
t = $(o).text();
if (t.indexOf(v) > -1) {
s = $("<li></li>");
s.attr("value", $(o).val());
idx = t.indexOf(v);
str = t.substring(0, idx);
str += "<b class=\"hit\">" + v + "</b>";
str += t.substring(idx + v.length);
s.html(str);
e.data.suggestions.append(s);
}
});
if (str) {
e.data.suggestionOnfocus = false;
e.data.suggestions.show();
}
}
}
else {
$("option:selected", e.data.selections).removeAttr("selected");
$("option", e.data.selections).each(function (i, o) {
if ($(o).text() === "") {
$(o).attr("selected", "selected");
return false;
}
});
}
}
}, config);
this.value = null;
if (this.config.id && !(typeof this.config.id === 'string')) {
throw new Error("控件id无效");
}
if (this.config.container && !(typeof this.config.container === 'object'
&& this.config.container.jquery)) {
throw new Error("container不是jquery对象");
}
if (this.config.id && !this.config.container) {
this.config.container = $("#" + this.config.id);
}
if (!this.config.id && !this.config.container) {
throw new Error("控件ID和container必须指定一项");
}
this.config.container.addClass("editabledropdown");
this.selections = $("select.selections", this.config.container);
if (this.selections.length === 0) {
this.selections = $("<select class=\"selections\"></select>");
this.config.container.append(this.selections);
}
if (this.config.selectionCss) {
this.selections.css(this.config.selectionCss);
}
if (!this.config.selectionTextField) {
this.config.selectionTextField = "text";
}
if (!this.config.selectionValueField) {
this.config.selectionValueField = "id";
}
if (this.config.selectionData && $.isArray(this.config.selectionData)) {
var op = null;
for (var i = 0; i < this.config.selectionData.length; i++) {
op = $("<option></option>");
op.attr("value", this.config.selectionData[i][this.config.selectionValueField]);
op.text(this.config.selectionData[i][this.config.selectionTextField]);
this.selections.append(op);
}
}
if (this.config.selectionChange) {
this.selections.change(this, this.config.selectionChange);
}
this.dropDownInput = $("input.dropdowninput", this.config.container);
if (this.dropDownInput.length === 0) {
this.dropDownInput = $("<input type=\"text\" class=\"dropdowninput\" autocomplete=\"off\">");
this.config.container.append(this.dropDownInput);
}
if (this.config.inputPlaceHolder) {
this.dropDownInput.attr("placeholder", this.config.inputPlaceHolder);
}
if (this.config.inputFocus) {
this.dropDownInput.focus(this, this.config.inputFocus);
}
if (this.config.inputBlur) {
this.dropDownInput.blur(this, this.config.inputBlur);
}
if (this.config.inputKeydown) {
this.dropDownInput.keydown(this, this.config.inputKeydown);
}
if (this.config.inputKeypress) {
this.dropDownInput.keypress(this, this.config.inputKeypress);
}
if (this.config.inputKeyup) {
this.dropDownInput.keyup(this, this.config.inputKeyup);
}
if (this.config.inputCss) {
this.dropDownInput.css(this.config.inputCss);
}
else {
this.dropDownInput.width(this.selections.innerWidth() - this.config.dropDownArrowWidth);
this.dropDownInput.height(this.selections.innerHeight() - 2);
}
this.suggestions = $("ul.autocomplete_suggestions", this.config.container);
if (this.suggestions.length === 0) {
this.suggestions = $("<ul class=\"autocomplete_suggestions\"></ul>");
this.config.container.append(this.suggestions);
}
if (this.config.suggestionCss) {
this.suggestions.css(this.config.suggestionCss);
}
else {
this.suggestions.width(this.selections.innerWidth());
}
this.suggestions.on("click", "li", this, function (e) {
e.data.suggestionOnfocus = true;
e.data.value = $(this).attr("value");
e.data.dropDownInput.val($(this).text());
e.data.suggestions.hide();
if (e.data.config.autocomplete && typeof e.data.config.autocomplete === "function") {
e.data.config.autocomplete(e.data, this);
}
});
}
使用:
window.productCategorySelector = new pl.editableDropDown({
id: "productCategoryAutoComplete",
selectionCss: { width: 300 },
autocompleteAjax: function (d) {
return {
url: "/admin/category/searchcategory",
type: "POST",
dataType: "json",
data: { name: d.dropDownInput.val(), count: 10 },
success: function (data) {
if (data && data.length > 0) {
var v = d.dropDownInput.val();
var s = null, h, t = null, idx = 0, str = null;
for (var i = 0; i < data.length; i++) {
t = data[i].Name;
s = $("<li></li>");
s.attr("value", data[i].CateId);
s.attr("data-path", data[i].Path);
idx = t.indexOf(v);
if (idx > -1) {
str = t.substring(0, idx);
str += "<b class=\"hit\">" + v + "</b>";
str += t.substring(idx + v.length);
}
else {
str = t;
}
s.html(str);
d.suggestions.append(s);
}
if (str) {
console.log(str);
d.suggestionOnfocus = false;
d.suggestions.show();
}
}
}
}
},
autocomplete: function (d,li) {
initCategory({
categoryPath: $(li).attr("data-path")
}, false);
}
});
效果: