0

我正在使用 Kendo UI 控件KendoUI AutocompleteKendoUI MultiSelect。我需要在客户端以编程方式更改这些控件值及其显示,而无需用户对这些控件进行操作。

如何重现该行为:

  1. 请看这个JS fiddle链接,有两个 Autocomplete 控件。
  2. 请在每个控件中键入几个字符,然后从自动建议中选择一个结果。
  3. 然后单击 Reverse 按钮​​,JS 尝试更改(反向)值,但这不会完成,无需用户单击自动建议中填充的结果。

如何避免用户选择结果?如果用户单击 Reveres,则两个控件都应该有新的选定值,并且它的显示也应该反映它。如果我单击显示选择,那应该显示新的选定值吗?我对 MultiSelect 也有类似的问题,如果相信如果我解决了这个问题,同样的解决方案也适用于 MultiSelect。

HTML

<div class="demo-section k-content">
  <h4>Find a product</h4>
  <input id="From" style="width: 100%;" placeholder="From" />
  <div class="demo-hint">Hint: type "che"</div>
  <br />
  <input id="To" style="width: 100%;" placeholder="To" />
  <div class="demo-hint">Hint: type "unc"</div>
  <br />
  <p>Please select From and To then clcik on reverse</p>
  <button id="reverse">
    Reverse
  </button>
  <button id="show">
    Show Selection
  </button>
  <p id="result">

  </p>
</div>

JS

 $(document).ready(function() {
   $("#result").html("");
   $("#From").kendoAutoComplete({
     dataTextField: "ProductName",
     filter: "contains",
     minLength: 2,
     dataSource: {
       type: "odata",
       serverFiltering: true,
       transport: {
         read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
       }
     }
   });
   $("#To").kendoAutoComplete({
     dataTextField: "ProductName",
     filter: "contains",
     minLength: 2,
     dataSource: {
       type: "odata",
       serverFiltering: true,
       transport: {
         read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
       }
     }
   });

   $("#reverse").click(function(e) {
     $("#result").html("");
     var $departure = $("#From").data("kendoAutoComplete");
     var $destination = $("#To").data("kendoAutoComplete");

     var departureStation = $departure.dataItem();
     var destinationStation = $destination.dataItem();

     $departure.search(destinationStation.icao_id);
     $departure.select($departure.ul.children().eq(0));
     $departure.value(destinationStation.DisplayName);
     $departure.trigger("change");
     $departure.close();

     $destination.search(departureStation.icao_id);
     $destination.select($destination.ul.children().eq(0));
     $destination.value(departureStation.DisplayName);
     $destination.trigger("change");
     $destination.close();

   });

   $("#show").click(function(e) {
     $("#result").html("");
     var $departure = $("#From").data("kendoAutoComplete");
     var $destination = $("#To").data("kendoAutoComplete");

     var departureStation = $departure.dataItem();
     var destinationStation = $destination.dataItem();
     var from = JSON.stringify(departureStation);
     var to = JSON.stringify(destinationStation);
     $("#result").html("From :" + from + "<br/><br/><br/><br/>To: " + to);
   });
 });
4

1 回答 1

0

一个主要问题是您拥有serverFiltering: true并且正在发生异步活动。

search方法将导致将过滤器应用于数据源,这反过来会导致服务器交互,该交互将dataBound在完成时触发事件。

kendoAutoComplete 在输入过程中打开它的下拉菜单,并在每次新击键发生额外过滤(隐式搜索)时将其保持打开状态。

解决方案:

  • 安装dataBound事件处理程序,检查是否强制交换操作,如果是,则自动选择第一个下拉项目。
  • 使用就绪函数范围的标志变量来指示正在发生交换
  • 交换点击处理程序将:
    • 设置标志变量
    • 调用程序化搜索
      • 从文档中,搜索将附带打开 DDL。
    • 数据绑定处理程序:
      • 强制选择 DDL,因为标志处于活动状态。
      • 关闭 DDL
      • 触发变化
      • 关闭标志变量

来自这个Dojo的JS

 $(document).ready(function() {

   $("#From").kendoAutoComplete({
     dataTextField: "ProductName",
     filter: "contains",
     minLength: 2,
     dataBound: function(e) { swap1() },
     dataSource: {
       type: "odata",
       serverFiltering: true,
       transport: {
         read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
       }
     }
   });

   $("#To").kendoAutoComplete({
     dataTextField: "ProductName",
     filter: "contains",
     minLength: 2,
     dataBound: function(e) { swap2() },
     dataSource: {
       type: "odata",
       serverFiltering: true,
       transport: {
         read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
       }
     }
   });

   var one_swapping = false;
   var two_swapping = false;

   function swap1() {
     if (one_swapping) {
       var ac = $("#From").data('kendoAutoComplete');
       ac.select(ac.ul.children().eq(0));
       ac.close();
       ac.trigger("change");
       one_swapping = false;
     }
   }

   function swap2() {
     if (two_swapping) {
       var ac = $("#To").data('kendoAutoComplete');
       ac.select(ac.ul.children().eq(0));
       ac.close();
       ac.trigger("change");
       two_swapping = false;
     }
   }

   $("#swap").click(function(e) {
     $("#result").html("");     

     var one = $("#From").data("kendoAutoComplete");
     var two = $("#To").data("kendoAutoComplete");

     var one_val = one.element.val();
     var two_val = two.element.val();

     one_swapping = true;
     one.search(two_val);  // force the filter 

     two_swapping = true;
     two.search(one_val);  // force the filter
   });

   $("#show").click(function(e) {
     $("#result").html("");
     var $departure = $("#From").data("kendoAutoComplete");
     var $destination = $("#To").data("kendoAutoComplete");

     var departureStation = $departure.dataItem();
     var destinationStation = $destination.dataItem();
     var from = JSON.stringify(departureStation);
     var to = JSON.stringify(destinationStation);
     $("#result").html("From :" + from + "<br/><br/><br/><br/>To: " + to);
   });
 });
于 2020-02-19T17:32:24.183 回答