Skip to content

Cascader 'loadData' work with 'showSearch' #7043

@qzsiniong

Description

@qzsiniong

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch ant-design-vue@3.2.19 for the project I'm working on.

My problem is that:I want to use showSearch for server search(mybe the first column), and use loadData to lazy load others data.

Demo: https://codesandbox.io/p/sandbox/amazing-hofstadter-r8t2yy

<template>
  <div>
    <h3>search first level and lazy load others</h3>
    <Cascader
      style="width: 450px"
      :options="options"
      :load-data="loadData"
      :show-search="true"
      placeholder="typing keyword for search"
      @search="handleSearch"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { Cascader, CascaderProps } from "ant-design-vue";

const options = ref<CascaderProps["options"]>([]);

const handleSearch: CascaderProps["onSearch"] = async (keyword) => {
  if (!keyword) return;

  setTimeout(() => {
    options.value = [
      {
        label: `${keyword}-A`,
        value: "1",
        isLeaf: false,
      },
      {
        label: `${keyword}-B`,
        value: "2",
        isLeaf: false,
      },
      {
        label: `${keyword}-C`,
        value: "3",
      },
    ];
  }, 1000);
};

const loadData: CascaderProps["loadData"] = async (selectedOptions) => {
  const targetOption = selectedOptions[selectedOptions.length - 1];
  const { children } = targetOption;

  // not load
  const isLoaded = children && children.length > 0;
  if (isLoaded) {
    return;
  }

  // show loading
  targetOption.loading = true;

  setTimeout(() => {
    const parentLabel = targetOption.label;
    const parentValue = targetOption.label;
    targetOption.loading = false;
    targetOption.children = [
      {
        label: `${parentLabel}-1`,
        value: `${parentValue}-1`,
      },
      {
        label: `${parentLabel}-2`,
        value: `${parentValue}-2`,
      },
    ];
  }, 1000);
};
</script>

Here is the diff that solved my problem:

diff --git a/node_modules/ant-design-vue/es/vc-cascader/Cascader.js b/node_modules/ant-design-vue/es/vc-cascader/Cascader.js
index 9e46e09..104024b 100644
--- a/node_modules/ant-design-vue/es/vc-cascader/Cascader.js
+++ b/node_modules/ant-design-vue/es/vc-cascader/Cascader.js
@@ -186,6 +186,10 @@ export default defineComponent({
       _useMergedState4 = _slicedToArray(_useMergedState3, 2),
       mergedSearchValue = _useMergedState4[0],
       setSearchValue = _useMergedState4[1];
+
+    var mergedSearchValue1 = computed(function () {
+      return !!loadData.value? '': mergedSearchValue.value;
+    });
     var onInternalSearch = function onInternalSearch(searchText, info) {
       setSearchValue(searchText);
       if (info.source !== 'blur' && props.onSearch) {
@@ -195,7 +199,7 @@ export default defineComponent({
     var _useSearchConfig = useSearchConfig(toRef(props, 'showSearch')),
       mergedShowSearch = _useSearchConfig.showSearch,
       mergedSearchConfig = _useSearchConfig.searchConfig;
-    var searchOptions = useSearchOptions(mergedSearchValue, mergedOptions, mergedFieldNames, computed(function () {
+    var searchOptions = useSearchOptions(mergedSearchValue1, mergedOptions, mergedFieldNames, computed(function () {
       return props.dropdownPrefixCls || props.prefixCls;
     }), mergedSearchConfig, toRef(props, 'changeOnSelect'));
     // =========================== Values ===========================
@@ -395,12 +399,12 @@ export default defineComponent({
       'children']);
     });
     return function () {
-      var emptyOptions = !(mergedSearchValue.value ? searchOptions.value : mergedOptions.value).length;
+      var emptyOptions = !(mergedSearchValue1.value ? searchOptions.value : mergedOptions.value).length;
       var _props$dropdownMatchS = props.dropdownMatchSelectWidth,
         dropdownMatchSelectWidth = _props$dropdownMatchS === void 0 ? false : _props$dropdownMatchS;
       var dropdownStyle =
       // Search to match width
-      mergedSearchValue.value && mergedSearchConfig.value.matchInputWidth ||
+      mergedSearchValue1.value && mergedSearchConfig.value.matchInputWidth ||
       // Empty keep the width
       emptyOptions ? {} : {
         minWidth: 'auto'
diff --git a/node_modules/ant-design-vue/es/vc-cascader/OptionList/index.js b/node_modules/ant-design-vue/es/vc-cascader/OptionList/index.js
index 3ca9497..96edc4b 100644
--- a/node_modules/ant-design-vue/es/vc-cascader/OptionList/index.js
+++ b/node_modules/ant-design-vue/es/vc-cascader/OptionList/index.js
@@ -44,7 +44,7 @@ export default defineComponent({
     var loadingKeys = shallowRef([]);
     var internalLoadData = function internalLoadData(valueCells) {
       // Do not load when search
-      if (!loadData.value || baseProps.searchValue) {
+      if (!loadData.value) {
         return;
       }
       var optionList = toPathOptions(valueCells, options.value, fieldNames.value);
@@ -108,7 +108,7 @@ export default defineComponent({
     };
     // ========================== Option ==========================
     var mergedOptions = computed(function () {
-      if (baseProps.searchValue) {
+      if (baseProps.searchValue && !loadData.value) {
         return searchOptions.value;
       }
       return options.value;

This issue body was partially generated by patch-package.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions