9

リモートデータにリンクされたKendoAutoCompleteフィールドがいくつかあります(数百の可能性があるため、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

このメソッドを使用すると、リストが開かない場合、ユーザーはオートコンプリートに好きなものを入力できます。これを修正するための2つの修正があります。

  1. falseとして有効な変数を初期化します。

    var valid = false;

  2. 変更イベントで有効な選択がないかどうかを確認しますが、閉じていないかどうかを確認します。

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

@Rock'n'museによって提案された回答に加えて、OPが投稿した回答は間違いなく良い提案ですが、どちらも重要で望ましい機能的側面を見逃しています。

change@Matによって提供されたソリューションを利用し、@ Rock'n'museからの-vice-提案を実装するclose場合、フィルター処理されたデータソースから選択が行われない場合、入力された値は実際にウィジェットからクリアされます。これは素晴らしい; ただし、ユーザーが有効なものを入力し、フィルターされたリストから値を選択した場合、値の最後にカーソル置き、値を無効にするものを入力します(データソースから有効な選択を返しません)。入力された値はウィジェットからクリアされません。

何が起こっているのかというと、以前に入力された(そして有効な)値を変更する必要がある場合でも、isValid値は残ります。これに対する解決策は、フィルタリングイベントがトリガーされるとすぐにtrueに設定isValidすることです。falseユーザーが入力された値を変更すると、ウィジェットは入力された値を検索するためにデータソースをフィルタリングしようとします。イベントがトリガーされるとすぐにに設定isValidすると、@ Rock'n'museのソリューションで提案されているように、イベントの「クリーンな状態」が保証されます。falsefilterchange

isValidイベントがトリガーされるとすぐにfalseに設定するため、filteringイベントでこれを行う必要はありませんopen(ユーザーが選択するオプションを表示する前に、データソースのフィルタリングを行う必要があるため)。このため、openイベントバインディングは@Matのソリューションから削除されました。falseこれは、宣言時の最初の代入が不要であることも意味しますが、宣言isValid時の変数代入は常に良い考えです。

以下は、@ Mattからの解決策と、@ 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
});

補遺として、@ Matが提案するように、イベントバインディングを使用しselect単純なブール値を設定および評価することは、入力された値がイベント内のデータソース。これは、@ Mat(このページ)から解決策を見つける前に解決策を検討する最初の考えでした。これが、彼の解決策と質問に賛成する理由です。$.each(...)change

于 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

2つの記号の最小長を超えた後に各キーストロークをインターセプトし、ユーザー文字列をオートコンプリートリストのどの項目とも一致させない文字を入力するオプションを防ぐカスタムロジックが必要になる可能性があります。

この目的のために、剣道オートコンプリートの変更イベントをインターセプトし、ユーザーからの現在の入力値をフィルターされたリストのアイテムと比較します。

于 2012-11-26T16:50:00.043 に答える
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は、オートコンプリートの値を格納するための非表示フィールドです。-場合によっては、dataTextField以外のdataValueFieldが必要になります。だから、それはその目的を果たします。

これで、要素autocomplete_idからオートコンプリート「id」の値を取得できます。これはサーバー側のdataValueFieldです。

データバインドでは、その値はnullに設定され、選択すると、「id」値が割り当てられます。

于 2013-05-02T06:54:38.157 に答える
0

受け入れられた答えは機能しますが、それは最善の解決策ではありません。

提供されているソリューションでは、剣道オートコンプリートウィジェットでさえ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

これは、変更イベントを使用するだけでTelerikのサイトで見つかりました。私にとって、これは最もうまくいきます。「value===''」チェックを追加しました。これは、ユーザーが選択を「クリア」したときにキャッチされます。

記事全文へのリンクは次のとおりです。

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

オートコンプリート変更イベントで、選択したアイテムを確認し、選択されていない場合はセルをクリアします。

    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 に答える