下邪__ 发表于 2020-6-15 21:30:04

AutoComplete 如何清空上一次筛选数据,选中状态

本帖最后由 下邪__ 于 2020-6-15 21:30 编辑

在开发过程中遇到两个问题第一个问题
1,首先输入一个"no",会出现下拉列表,选择一条后删掉,然后移出焦点,想在焦点移出后让下拉列表为空。

开始以为修改一下itemsSourceFunction 的callback值,就试了null和new array,但并不能清空,还是上一次筛选出的值。请问有方法让text框为空或者输入空格的时候,清空下拉列表。


AutoComplete 异步加载示例
https://demo.grapecity.com.cn/wijmo/demos/Input/AutoComplete/AsyncLoading/react
如图,先输入no,筛选出来值,删除后,移除出焦点,或者输入空格,都不能清除现有的下拉列表

输入no

随意选择一条

删除后移出焦点或者输入空格,都没法让下拉列表清空




第二个问题
输入一个完全匹配的项目,点开下拉列表,没有自动选中。有没有方法让完全匹配的这种数据自动被选中
完全匹配的样子

鼠标点击的样子,想让上面的状态和下面的状态相同




KevinChen 发表于 2020-6-15 21:30:05

你好,textChanged的确不行,首先如你所说它的触发顺序在itemsSource之前,其次这个示例是远程加载数据,所以这里还有一个异步请求。因此要实现这个功能,只能在异步请求内部来做。

参考以下完整代码:



import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
//
import * as wijmo from '@grapecity/wijmo';
import * as input from '@grapecity/wijmo.input';
//
document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
    // AutoComplete with async search using OData source
    let theAutoComplete = new input.AutoComplete('#theAutoComplete', {
      placeholder: 'Product Name',
      displayMemberPath: 'ProductName',
      itemsSourceFunction: (query, max, callback) => {
            if (!query) {
                callback(null);
                return;
            }
            //
            wijmo.httpRequest('https://services.odata.org/Northwind/Northwind.svc/Products', {
                data: {
                  $format: 'json',
                  $select: 'ProductID,ProductName',
                  $filter: 'indexof(ProductName, \'' + query + '\') gt -1'
                },
                success: (xhr) => {
                  let response = JSON.parse(xhr.response);
                  let value = response.value;
                  if(value){
                        value.forEach(function(val){
                            if(query == val.ProductName){
                              setTimeout(function(){
                                    theAutoComplete.selectedItem = val;
                                    if(theAutoComplete.isDroppedDown){
                                        theAutoComplete.isDroppedDown = false;
                                    }
                              }, 10);
                            }
                        });
                  }
                  callback(response.d ? response.d.results : response.value);
                }
            });
      },
      selectedIndexChanged: function () {
            let product = theAutoComplete.selectedItem;
            document.querySelector('#msg').textContent = product
                ? wijmo.format('{ProductName} (ID: {ProductID})', product)
                : 'None';
      },
      lostFocus: function (e) {
            if(!e.text || e.text.length == 0){
                e.listBox.itemsSource.items.splice(0)
                e.listBox.itemsSource.refresh()
            }
      }
    });
}



示例地址:

https://demo.grapecity.com.cn/wi ... AsyncLoading/purejs

KevinChen 发表于 2020-6-16 10:21:16

您好,您的两个问题,需要一些时间来调研,可能还要写一些自定义代码来实现,今天下午18点前回复

KevinChen 发表于 2020-6-16 11:28:37

问题一,用lostFocus事件实现,关键代码如下:

lostFocus: function (e) {
            if(!e.text || e.text.length == 0){
                e.listBox.itemsSource.items.splice(0)
                e.listBox.itemsSource.refresh()
            }
      }

完整代码如下:

import 'bootstrap.css';
import '@grapecity/wijmo.styles/wijmo.css';
import './styles.css';
//
import * as wijmo from '@grapecity/wijmo';
import * as input from '@grapecity/wijmo.input';
//
document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
    // AutoComplete with async search using OData source
    let theAutoComplete = new input.AutoComplete('#theAutoComplete', {
      placeholder: 'Product Name',
      displayMemberPath: 'ProductName',
      itemsSourceFunction: (query, max, callback) => {
            if (!query) {
                callback(null);
                return;
            }
            //
            wijmo.httpRequest('https://services.odata.org/Northwind/Northwind.svc/Products', {
                data: {
                  $format: 'json',
                  $select: 'ProductID,ProductName',
                  $filter: 'indexof(ProductName, \'' + query + '\') gt -1'
                },
                success: (xhr) => {
                  let response = JSON.parse(xhr.response);
                  callback(response.d ? response.d.results : response.value);
                }
            });
      },
      selectedIndexChanged: function () {
            let product = theAutoComplete.selectedItem;
            document.querySelector('#msg').textContent = product
                ? wijmo.format('{ProductName} (ID: {ProductID})', product)
                : 'None';
      },
      lostFocus: function (e) {
            if(!e.text || e.text.length == 0){
                e.listBox.itemsSource.items.splice(0)
                e.listBox.itemsSource.refresh()
            }
      }
    });
}


将完整代码复制替换示例的app.js即可:

https://demo.grapecity.com.cn/wijmo/demos/Input/AutoComplete/AsyncLoading/purejs

KevinChen 发表于 2020-6-16 11:34:14

问题二:可以实现。与一同理,可以用textChanged事件来监听 用户输入的内容,每次内容变化时判断dataSource中有没有对应的item,有item时直接选中即可。

下邪__ 发表于 2020-6-17 13:21:11

本帖最后由 下邪__ 于 2020-6-17 13:22 编辑

KevinChen 发表于 2020-6-16 11:34
问题二:可以实现。与一同理,可以用textChanged事件来监听 用户输入的内容,每次内容变化时判断dataSource ...
第一个问题很顺利的解决了,很感谢
但是第二个还是存在一定的问题

对于版主说的方法进行了实验,并没有成功
debug发现,更改输入内容后是先触发了textChanged事件,后触发了itemsSourceFunction
这样就导致在textChanged事件中设定的代码失效。感觉是因为在itemsSourceFunction设定了新的list数据。
不清楚是我代码实现的不正确还是确实不太可以。麻烦再帮忙调查一下。谢谢
页: [1]
查看完整版本: AutoComplete 如何清空上一次筛选数据,选中状态