自定义 jquery-ui 自动完成组合框的一些麻烦
Some troubles to custom jquery-ui Autocomplete combobox
我想使用 autocomplete/ComboBox 作为过滤器。我从 jqueryUI 自定义代码以提供与 selectMenu 相同的形式。我想使用 select 并在 Enter 按键上更改事件和触发更改事件。
这是我的代码:
$.widget("custom.TFOAutoCombo", {
_create: function () {
var nam = this.element.attr("id").split("lstFiltreAuto");
this.element.hide();
this.wrapper = $("<span>", { "class": "ui-state-default TFOcustom-combobox SizCol" + nam[1] }).appendTo($('#acc-container' + nam[1]));
this._createAutocomplete(nam[1]);
this._createShowAllButton(nam[1]);
},
_createAutocomplete: function (nam) {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $('<input class="ui-state-default TFOcustom-combobox-Input ui-corner-all" placeholder="TOUS">').appendTo(this.wrapper).val(value)
.autocomplete({ delay: 0, minLength: 0, source: $.proxy(this, "_source"), appendTo: '#acc-container' + nam })
.tooltip({ classes: { "ui-tooltip": "ui-state-highlight" } });
this._on(this.input, {
autocompleteselect: function (event, ui) { ui.item.option.selected = true; this._trigger("select", event, { item: ui.item.option }); },
autocompletechange: function (event, ui) { var ret = this._removeIfInvalid(event, ui); if (ret != null) { this._trigger("change", event, { item: ret }); } }
});
this.input.keypress(function (e,ui) {
if (e.which == 13) {
var ret = this._removeIfInvalid(e, ui); if (ret != null) { this._trigger("change", event, { item: ret }); }
}
});
},
_createShowAllButton: function (nam) {
var input = this.input, wasOpen = false;
$('<span class="ui-icon ui-icon-triangle-1-s TFOcustom-combobox-Fleche">').appendTo(this.wrapper)
.on("mousedown", function () { wasOpen = input.autocomplete("widget").is(":visible"); })
.on("click", function () {
input.trigger("focus");
if (wasOpen) { return; }// Close if already visible
input.autocomplete("search", "");// Pass empty string as value to search for, displaying all results
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text))) return { label: text, value: text, option: this };
}));
},
_removeIfInvalid: function (event, ui) {
if (ui.item) { return null; }// Selected an item, nothing to do
// Search for a match (case-insensitive)
var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; var Koi = null;
this.element.children("option").each(function () { if ($(this).text().toLowerCase() === valueLowerCase) { this.selected = valid = true; Koi = this; return false; } });
if (valid) { return Koi; } // Found a match, nothing to do
// Remove invalid value
this.input.val("").attr("title", "Aucun enregistrement correspondant à " + value).tooltip("open");
this.element.val("");
this._delay(function () { this.input.tooltip("close").attr("title", ""); }, 2500);
this.input.autocomplete("instance").term = "";
return Koi;
},
_destroy: function () { this.wrapper.remove(); this.element.show(); }
});
为了创建我的自定义自动完成,我使用了这个函数
function CustomComboAuto($r, q) {
var s = (q == null ? "select.TFOAutoCombo" : q); $r.find(s).TFOAutoCombo({
select: function (event, ui) {
alert("select:" + ui.item.value);
},
change: function (event, ui) {
alert("Change" + ui.item.value);
}
});
}
还有我的CSS:
.TFOcustom-combobox {
position: relative;
display: inline-block;
vertical-align:middle;
padding: 0 10px 0 0;
border:none !important;
background:none !important;
}
.TFOcustom-combobox-Fleche {
position:absolute;
right:0.5em;
top:50%;
margin-top:-8px;
z-index:100;
}
.TFOcustom-combobox-Input{
width:95%;
font-size:small !important;
padding:0.7em 0 0.7em 1em;
line-height:1.4;
}
我有 2 个问题/
第一个是当我 select 用鼠标触发 select 事件(好)
当我使用 up/down 并按 entrer 到 select 一个项目时,它会在 select 事件之后触发更改事件。我只需要改变而不是 select)
第二个问题,当我直接在自动完成中写入并按回车键时,我想触发自动完成更改事件。我捕获了事件 enterkeypress 但我无法正确启动研究。
如果有人能帮助我。我从 3 天开始就在努力,解决了很多问题,但现在我没有更多的想法来解决这 2 点。
终于解决了第一大块问题
$.widget("custom.TFOAutoCombo", {
_create: function () {
var nam = this.element.attr("id").split("lstFiltreAuto");
this.element.hide();
this.wrapper = $("<span>", { "class": "ui-state-default TFOcustom-combobox SizCol" + nam[1] }).appendTo($('#acc-container' + nam[1]));
this._createAutocomplete(nam[1]);
this._createShowAllButton(nam[1]);
},
_createAutocomplete: function (nam) {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
var selectedName = '';
this.input = $('<input class="ui-state-default TFOcustom-combobox-Input ui-corner-all" placeholder="TOUS">').appendTo(this.wrapper).val(value)
.autocomplete({ delay: 0, minLength: 0, source: $.proxy(this, "_source"), appendTo: '#acc-container' + nam })
.keypress(function (e, ui) {
if (e.which == 13) {
e.preventDefault(); $(this).autocomplete("close"); var inputs = $(this).closest('body').find(':focusable'); inputs.eq(inputs.index(this) + 1).focus();
}
})
.tooltip({ classes: { "ui-tooltip": "ui-state-highlight" } });
this._on(this.input, {
autocompleteselect: function (event, ui) { if (selectedName === ui.item.value) { return; } else { selectedName = ui.item.value; ui.item.option.selected = true; this._trigger("select", event, { item: ui.item.option }); } },
autocompletechange: function (event, ui) { if (selectedName === this.input.val()) { return; } else { var ret = this._removeIfInvalid(event, ui); if (ret != null) { selectedName = this.input.val(); this._trigger("select", event, { item: ret }); } } }
});
},
_createShowAllButton: function (nam) {
var input = this.input, wasOpen = false;
$('<span class="ui-icon ui-icon-triangle-1-s TFOcustom-combobox-Fleche">').appendTo(this.wrapper)
.on("mousedown", function () { wasOpen = input.autocomplete("widget").is(":visible"); })
.on("click", function () {
input.trigger("focus");
if (wasOpen) { return; }// Close if already visible
input.autocomplete("search", "");// Pass empty string as value to search for, displaying all results
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text))) return { label: text, value: text, option: this };
}));
},
_removeIfInvalid: function (event, ui) {
if (ui.item) { return null; }// Selected an item, nothing to do
// Search for a match (case-insensitive)
var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; var Koi = null;
this.element.children("option").each(function () { if ($(this).text().toLowerCase() === valueLowerCase) { this.selected = valid = true; Koi = this; return false; } });
if (valid) { return Koi; } // Found a match, nothing to do
// Remove invalid value
this.input.val("").attr("title", "Aucun enregistrement correspondant à " + value).tooltip("open");
this.element.val("");
this._delay(function () { this.input.tooltip("close").attr("title", ""); }, 2500);
this.input.autocomplete("instance").term = "";
return Koi;
},
_destroy: function () { this.wrapper.remove(); this.element.show(); }
});
解决方案很简单,当我捕获 Enter KeyPress 时我关闭自动完成并将焦点放在其他地方 :-) 以触发自动完成更改事件。
当我使用 up/down 并在列表中按 EnterKeyPress 选择时,现在只剩下双重触发事件的问题了
更新
我用一个变量更改 _createAutocomplete 以记住最后一个值...太简单了,我看不到它。
全部解决。享受一个很好的自动完成组合框似乎 selectmenu
我想使用 autocomplete/ComboBox 作为过滤器。我从 jqueryUI 自定义代码以提供与 selectMenu 相同的形式。我想使用 select 并在 Enter 按键上更改事件和触发更改事件。
这是我的代码:
$.widget("custom.TFOAutoCombo", {
_create: function () {
var nam = this.element.attr("id").split("lstFiltreAuto");
this.element.hide();
this.wrapper = $("<span>", { "class": "ui-state-default TFOcustom-combobox SizCol" + nam[1] }).appendTo($('#acc-container' + nam[1]));
this._createAutocomplete(nam[1]);
this._createShowAllButton(nam[1]);
},
_createAutocomplete: function (nam) {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $('<input class="ui-state-default TFOcustom-combobox-Input ui-corner-all" placeholder="TOUS">').appendTo(this.wrapper).val(value)
.autocomplete({ delay: 0, minLength: 0, source: $.proxy(this, "_source"), appendTo: '#acc-container' + nam })
.tooltip({ classes: { "ui-tooltip": "ui-state-highlight" } });
this._on(this.input, {
autocompleteselect: function (event, ui) { ui.item.option.selected = true; this._trigger("select", event, { item: ui.item.option }); },
autocompletechange: function (event, ui) { var ret = this._removeIfInvalid(event, ui); if (ret != null) { this._trigger("change", event, { item: ret }); } }
});
this.input.keypress(function (e,ui) {
if (e.which == 13) {
var ret = this._removeIfInvalid(e, ui); if (ret != null) { this._trigger("change", event, { item: ret }); }
}
});
},
_createShowAllButton: function (nam) {
var input = this.input, wasOpen = false;
$('<span class="ui-icon ui-icon-triangle-1-s TFOcustom-combobox-Fleche">').appendTo(this.wrapper)
.on("mousedown", function () { wasOpen = input.autocomplete("widget").is(":visible"); })
.on("click", function () {
input.trigger("focus");
if (wasOpen) { return; }// Close if already visible
input.autocomplete("search", "");// Pass empty string as value to search for, displaying all results
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text))) return { label: text, value: text, option: this };
}));
},
_removeIfInvalid: function (event, ui) {
if (ui.item) { return null; }// Selected an item, nothing to do
// Search for a match (case-insensitive)
var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; var Koi = null;
this.element.children("option").each(function () { if ($(this).text().toLowerCase() === valueLowerCase) { this.selected = valid = true; Koi = this; return false; } });
if (valid) { return Koi; } // Found a match, nothing to do
// Remove invalid value
this.input.val("").attr("title", "Aucun enregistrement correspondant à " + value).tooltip("open");
this.element.val("");
this._delay(function () { this.input.tooltip("close").attr("title", ""); }, 2500);
this.input.autocomplete("instance").term = "";
return Koi;
},
_destroy: function () { this.wrapper.remove(); this.element.show(); }
});
为了创建我的自定义自动完成,我使用了这个函数
function CustomComboAuto($r, q) {
var s = (q == null ? "select.TFOAutoCombo" : q); $r.find(s).TFOAutoCombo({
select: function (event, ui) {
alert("select:" + ui.item.value);
},
change: function (event, ui) {
alert("Change" + ui.item.value);
}
});
}
还有我的CSS:
.TFOcustom-combobox {
position: relative;
display: inline-block;
vertical-align:middle;
padding: 0 10px 0 0;
border:none !important;
background:none !important;
}
.TFOcustom-combobox-Fleche {
position:absolute;
right:0.5em;
top:50%;
margin-top:-8px;
z-index:100;
}
.TFOcustom-combobox-Input{
width:95%;
font-size:small !important;
padding:0.7em 0 0.7em 1em;
line-height:1.4;
}
我有 2 个问题/ 第一个是当我 select 用鼠标触发 select 事件(好) 当我使用 up/down 并按 entrer 到 select 一个项目时,它会在 select 事件之后触发更改事件。我只需要改变而不是 select) 第二个问题,当我直接在自动完成中写入并按回车键时,我想触发自动完成更改事件。我捕获了事件 enterkeypress 但我无法正确启动研究。
如果有人能帮助我。我从 3 天开始就在努力,解决了很多问题,但现在我没有更多的想法来解决这 2 点。
终于解决了第一大块问题
$.widget("custom.TFOAutoCombo", {
_create: function () {
var nam = this.element.attr("id").split("lstFiltreAuto");
this.element.hide();
this.wrapper = $("<span>", { "class": "ui-state-default TFOcustom-combobox SizCol" + nam[1] }).appendTo($('#acc-container' + nam[1]));
this._createAutocomplete(nam[1]);
this._createShowAllButton(nam[1]);
},
_createAutocomplete: function (nam) {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
var selectedName = '';
this.input = $('<input class="ui-state-default TFOcustom-combobox-Input ui-corner-all" placeholder="TOUS">').appendTo(this.wrapper).val(value)
.autocomplete({ delay: 0, minLength: 0, source: $.proxy(this, "_source"), appendTo: '#acc-container' + nam })
.keypress(function (e, ui) {
if (e.which == 13) {
e.preventDefault(); $(this).autocomplete("close"); var inputs = $(this).closest('body').find(':focusable'); inputs.eq(inputs.index(this) + 1).focus();
}
})
.tooltip({ classes: { "ui-tooltip": "ui-state-highlight" } });
this._on(this.input, {
autocompleteselect: function (event, ui) { if (selectedName === ui.item.value) { return; } else { selectedName = ui.item.value; ui.item.option.selected = true; this._trigger("select", event, { item: ui.item.option }); } },
autocompletechange: function (event, ui) { if (selectedName === this.input.val()) { return; } else { var ret = this._removeIfInvalid(event, ui); if (ret != null) { selectedName = this.input.val(); this._trigger("select", event, { item: ret }); } } }
});
},
_createShowAllButton: function (nam) {
var input = this.input, wasOpen = false;
$('<span class="ui-icon ui-icon-triangle-1-s TFOcustom-combobox-Fleche">').appendTo(this.wrapper)
.on("mousedown", function () { wasOpen = input.autocomplete("widget").is(":visible"); })
.on("click", function () {
input.trigger("focus");
if (wasOpen) { return; }// Close if already visible
input.autocomplete("search", "");// Pass empty string as value to search for, displaying all results
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text))) return { label: text, value: text, option: this };
}));
},
_removeIfInvalid: function (event, ui) {
if (ui.item) { return null; }// Selected an item, nothing to do
// Search for a match (case-insensitive)
var value = this.input.val(), valueLowerCase = value.toLowerCase(), valid = false; var Koi = null;
this.element.children("option").each(function () { if ($(this).text().toLowerCase() === valueLowerCase) { this.selected = valid = true; Koi = this; return false; } });
if (valid) { return Koi; } // Found a match, nothing to do
// Remove invalid value
this.input.val("").attr("title", "Aucun enregistrement correspondant à " + value).tooltip("open");
this.element.val("");
this._delay(function () { this.input.tooltip("close").attr("title", ""); }, 2500);
this.input.autocomplete("instance").term = "";
return Koi;
},
_destroy: function () { this.wrapper.remove(); this.element.show(); }
});
解决方案很简单,当我捕获 Enter KeyPress 时我关闭自动完成并将焦点放在其他地方 :-) 以触发自动完成更改事件。
当我使用 up/down 并在列表中按 EnterKeyPress 选择时,现在只剩下双重触发事件的问题了
更新 我用一个变量更改 _createAutocomplete 以记住最后一个值...太简单了,我看不到它。 全部解决。享受一个很好的自动完成组合框似乎 selectmenu