9

我有一些链接到远程数据的 Kendo AutoComplete 字段(有数百种可能性,所以 DropDownList 不是一个选项)。

如何强制用户从显示的列表中进行选择?

我还在检索从数据源返回的附加数据,例如

$("#station").kendoAutoComplete({
    dataSource: stationData,
    minLength: 2,
    dataTextField: 'name',
    select: function(e){
        var dataItem = this.dataItem(e.item.index());
        console.dir(dataItem);
    }
});

我正在用数据做额外的事情,dataItem它需要是一个有效的选择。

谢谢

已解决:我想我可能把事情复杂化了。答案很简单,贴在下面。

4

9 回答 9

16
var valid;
$("#staton").kendoAutoComplete({
  minLength: 2,
  dataTextField: "name",
  open: function(e) {
    valid = false;
  },
  select: function(e){
    valid = true;
  },
  close: function(e){
    // if no valid selection - clear input
    if (!valid) this.value('');
  },
  dataSource: datasource
});
于 2012-11-28T21:12:10.873 回答
8

如果列表未打开,此方法允许用户在自动完成中键入他们喜欢的任何内容。有两个更正可以解决此问题:

  1. 初始化变量valid为false:

    变量有效 = 假;

  2. 检查更改事件中是否没有有效选择,但未关闭:

    ...
    change: function(e){ if (!valid) this.value(''); }
    
于 2015-03-11T11:35:56.423 回答
3

除了@Rock'n'muse 提出的答案之外,OP 发布的答案绝对是很好的提议,但都错过了一个重要且理想的功能方面。

当利用@Mat 给出的解决方案并实现@Rock'n'muse 的change-vice-close建议时,如果没有从过滤的数据源中进行选择,输入的值确实会从小部件中清除。这很棒; 但是,如果用户输入有效的内容并从过滤列表中选择一个值,然后将光标放在值的末尾并输入一些现在使该值无效的内容(不从数据源返回任何有效的选择),输入的值不会从小部件中清除。

发生的情况是,如果应该更改先前输入的(和有效的)值,则该isValid值仍然存在。true对此的解决方案是一旦触发过滤事件就设置为isValidfalse当用户更改输入值时,小部件会尝试过滤数据源以搜索输入值。正如@Rock'n'muse 的解决方案所建议的那样,一旦触发事件,就设置isValid为确保事件的“干净状态”。falsefilterchange

因为我们在事件触发后isValid立即设置为 false filtering,所以我们不需要在open事件中这样做(因为必须在用户看到可供选择的选项之前进行数据源过滤)。因此,open从@Mat 的解决方案中删除了事件绑定。这也意味着false声明时的初始赋值isValid是多余的,但声明时变量赋值总是一个好主意。

以下是来自@Mat 的解决方案以及来自@Rock'n'muse 的建议以及应用的filtering实现:

var isValid = false;
$("#staton").kendoAutoComplete({
    minLength: 2,
    dataTextField: "name",
    select: function () {
        valid = true;
    },
    change: function (e) {
        // if no valid selection - clear input
        if (!valid) {
            e.sender.value("");
        }
    },
    filtering: function () {
        valid = false;
    },
    dataSource: datasource
});

作为附录,使用select事件绑定来设置和评估一个简单的布尔值,正如@Mat 所建议的那样$.each(...)在数据源上使用 jQuery 来确保输入的值与事件中的数据源change。这是我在从@Mat(此页面)找到解决方案之前第一个想到解决方案的想法,这就是我对他的解决方案和他的问题进行投票的理由。

于 2017-01-17T21:38:09.770 回答
1

blur也许,您可以使用事件进行自己的验证:

$("#station").blur(function() {
    var data = stationData,
        nbData = data.length,
        found = false;

    for(var iData = 0; iData < nbData; iData++) {
         if(this.value === data[iData].yourfieldname) // replace "yourfieldname" by the corresponding one if needed
             found = true;
    }
    console.log(found);
});

你可以检查这个小提琴

于 2012-11-26T16:41:45.200 回答
0

Hope this helps,

$("#autocomplete_id").val("");

$("#autocomplete").kendoAutoComplete({
    dataSource: datasource,
    minLength: 1,
    dataTextField: "catname",
    dataValueField:"id",
    select: function(e) {                
        var dataItem = this.dataItem(e.item.index());                
        $("#autocomplete_id").val(dataItem.id);
    },
    dataBound: function(e){
        $("#autocomplete_id").val("");
    }
}); 

FYI, autocomplete_id is a hidden field to store the value of the autocomplete. - Sometimes, we would like to have the dataValueField other than dataTextField. So, it serves its purpose.

In this you can get the value of the autocomplete "id" from the element autocomplete_id - which is dataValueField from serverside.

In databound, its values is set to null, and on select, it is assigned the "id" value.

于 2013-05-02T06:54:38.157 回答
0

您很可能需要一些自定义逻辑来在超过两个符号的最小长度后拦截每个击键,并防止输入使用户字符串与自动完成列表中的任何项目不匹配的字符的选项。

为此,拦截 Kendo 自动完成的更改事件,并将用户的当前输入值与过滤列表中的项目进行比较。

于 2012-11-26T16:50:00.043 回答
0

我通过使用 change 事件在 Telerik 的网站上找到了这个。对我来说,这效果最好。我添加了“值 === ''”检查。这将在用户“清除”选择时捕获。

这是完整文章的链接。

      $("#countries").kendoAutoComplete({
        dataSource: data,
        filter: "startswith",
        placeholder: "Select country...",
        change: function() {
          var value = this.value();
          if (value === '') return;
          var found = false;
          var data = this.dataSource.view();

          for(var idx = 0, length = data.length; idx < length; idx++) {
            if (data[idx] === value) {
              found = true;
              break;
            }
          }

          if (!found) {
            this.value("");
            alert("Custom values are not allowed");
          }
        }
      });
于 2018-03-05T15:18:07.827 回答
0

尽管公认的答案有效,但它不是最佳解决方案。

如果用户在 kendo AutoComplete 小部件触发 open 事件之前输入值,则提供的解决方案没有考虑到。结果,输入的值不是强制的,因此输入/选择无效。

我的方法假设应用程序在MVC中运行,并且数组在ViewData中传递。但这可以更改以适应您的环境。

我的做法:

var validSelect, isSelected;
$("#staton").kendoAutoComplete({
    minLength: 2,
    filter: "startswith",
    dataTextField: "name",
    filtering: function(e) {
        validSelect = false;
        dataArr = @Html.Raw(Json.Encode(ViewData["allStatons"]));
        // for loop within the ViewData array to find for matching ID
        for (var i = 0; i < dataArr .length; i++){
            if (dataArr[i].ID.toString().match("^" + $("#staton").val())) {
                validSelect = true;
                break;
            }
        }

        // if value entered was not found in array - clear input
        if (!validSelect) $("#staton").val("");
    },
    select: function(e){
        isSelected = true;
    },
    close: function(e){
        // if selection is invalid or not selected from the list - clear input
        if (!validSelect || !isSelected) $("#staton").val("");
    },
    dataSource: datasource
});

如您所见,这种方法需要加载来自服务器端的数组,以便它可以在小部件的过滤事件期间匹配。

于 2016-07-08T15:57:22.387 回答
0

在我的 AutoComplete Change 事件中,我检查选定的项目,如果未选中则清除单元格。

    function myAutoComplete_OnChange(e)
    {
        if (this.dataItem())
        {
            // Don't use filtered value as display, instead use this value.
            e.sender.element[0].value = this.dataItem().WidgetNumber;
        }
        else
        {
            var grid = $("#grid").data("kendoGrid");
            grid.dataItems()[grid.select().index()].WidgetKey = null;
            grid.dataItems()[grid.select().index()].WidgetNumber = null;
        }
    }

于 2019-04-24T20:50:53.807 回答