Kendo AutoComplete - 强制用户进行有效选择

时间:2012-11-26 11:54:08

标签: kendo-ui

我有一些链接到远程数据的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中的数据执行其他操作,并且需要进行有效选择。

由于

解决: 我想我可能过于复杂了。答案很简单,发布在下面。

9 个答案:

答案 0 :(得分: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
});

答案 1 :(得分:8)

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

  1. 将变量初始化为false:

    var valid = false;

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

    ...
    change: function(e){ if (!valid) this.value(''); }
    

答案 2 :(得分: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);
});

您可以查看this fiddle

答案 3 :(得分:1)

除了@ Rock&#39;缪斯提出的答案之外,OP发布的答案肯定是很好的主张,但两者都错过了重要且理想的功能方面。

在利用@Mat提供的解决方案并实施@ Rock&#39;缪斯的change - 反 - close建议时,输入的值确实会从小部件中清除如果没有从过滤的数据源中进行选择。这很棒;但是,如果用户输入有效内容并从筛选列表中选择一个值,则然后将光标放在值的末尾并键入现在使值无效的内容(不会从数据源返回任何有效选择),不会从窗口小部件中清除键入的值。

如果应更改先前输入的(和有效)值,那么isValid值仍为true。解决此问题的方法是,一旦触发过滤事件,就将isValid设置为false。当用户更改键入的值时,窗口小部件会尝试过滤数据源以搜索键入的值。触发isValid事件后立即将false设置为filter可确保&#34;干净的平板&#34;来自@ Rock&#39;缪斯的解决方案所建议的change活动。

由于我们在isValid事件被触发后立即将filtering设置为false,因此我们无需在open事件中执行此操作(作为数据源过滤)必须在用户看到选项之前发生)。因此,从@ Mat的解决方案中删除了open事件绑定。这也意味着false在声明isValid时的初始分配是多余的,但在声明时的变量赋值总是一个好主意。

以下是来自@Mat的解决方案以及来自@ Rock&#39;缪斯的建议以及应用了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建议更清洁,比使用jQuery更简单,更快{{1}在数据源上,以确保键入的值与$.each(...)事件中数据源的实际项匹配。在我从@Mat(本页)找到解决方案之前,这是我第一次想到解决方案,这就是我推荐他的解决方案和他的问题的理由。

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

希望这有帮助,

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

仅供参考,autocomplete_id是一个隐藏字段,用于存储自动填充的值。 - 有时,我们希望dataWalueField不是dataTextField。因此,它有助于实现其目的。

在此,您可以从元素autocomplete_id获取自动完成“id”的值 - 这是来自serverside的dataValueField。

在数据绑定中,其值设置为null,而在选择时,它被赋予“id”值。

答案 6 :(得分:0)

尽管accepted answer有效,但它不是最佳解决方案。

如果用户在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
});

如您所见,此方法需要加载服务器端的数组,以便在窗口小部件的过滤事件期间匹配。

答案 7 :(得分:0)

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

Here's the link to the full article.

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

答案 8 :(得分:0)

在“自动完成更改”事件中,我检查了选中的项目,并清除了未选中的单元格。

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

相关问题