简体   繁体   English

自定义jquery-ui自动完成组合框的一些麻烦

[英]Some troubles to custom jquery-ui Autocomplete combobox

I want use a autocomplete/ComboBox like a filter. 我想使用像过滤器一样的自动填充/组合框。 I customize the code from jqueryUI to give same form like a selectMenu. 我自定义jqueryUI的代码以提供与selectMenu相同的形式。 And I want use select and change event and triger change event on Enter keypress. 我想在Enter键上使用选择和更改事件以及触发更改事件。

Here my code : 这是我的代码:

$.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(); }
});

TO create my custom autocomplete I use thsi function 要创建我的自定义自动完成功能,请使用此功能

 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);
        }
    });
}

And my CSS: 而我的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;
}

And I've 2 Problems/ The first is when I select with mouse it's fired select event (good) When I use up/down and press entrer to select an item, it's fired change event and after select event. 我有2个问题/第一个是当我用鼠标选择时触发了选择事件(好)当我使用上/下键并按entrer选择一个项目时,它触发了更改事件和选择事件之后。 And I just need change not the select) The second problem and I want fire autocompletechange event when I write directly in my autocomplete and press enter key. 我只需要更改而不是select)第二个问题,当我直接在自动完成中编写并按Enter键时,我希望触发fire autocompletechange事件。 I've capture the event enterkeypress but I can't fired the research properly. 我已经捕获了EnterEnterpress事件,但是无法正确触发研究。

If someone can help me. 如果有人可以帮助我。 I work on that since 3 days, passed lot of problem but now I've no more idea to solve this 2 points. 自3天以来,我一直在努力,解决了很多问题,但是现在我再也没有解决这2点的想法了。

Finnally I solved the first big part of problems. 最后,我解决了问题的第一部分。

$.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(); }
});

The solution is simple, when I capture Enter KeyPress I close autocomplete and put focus otherthere :-) to trigger autocompletechange event. 解决方案很简单,当我捕获Enter KeyPress时,我关闭自动完成功能并将焦点放在其他位置(-)以触发自动完成更改事件。

Now JUST stay the problem of double fired event when I use up/down and selecting by EnterKeyPress on list 现在,当我使用向上/向下并在列表中按EnterKeyPress选择时,只需解决双重触发事件的问题

UPDATE I change the _createAutocomplete with a variable to memorize the last value... Too simple that I can see it. 更新我更改了_createAutocomplete变量以存储最后一个值...太简单了,我看不到它。 All Resolved. 全部解决。 Enjoy a good autocomplete combobox seems selectmenu 享受一个不错的自动完成组合框似乎选择菜单

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM