diff --git a/src/components/Form/src/smart-boot/components/SmartPulldownTable.tsx b/src/components/Form/src/smart-boot/components/SmartPulldownTable.tsx index 79007d380..3c19e8a90 100644 --- a/src/components/Form/src/smart-boot/components/SmartPulldownTable.tsx +++ b/src/components/Form/src/smart-boot/components/SmartPulldownTable.tsx @@ -6,6 +6,7 @@ import { Icon } from '@/components/Icon'; import './style/SmartPullownTable.less'; import { useRuleFormItem } from '@/hooks/component/useFormItem'; +import { Row, Col } from 'ant-design-vue'; /** * 下拉表格 @@ -28,14 +29,74 @@ export default defineComponent({ api: { type: Function as PropType<() => Promise>, }, + showSearch: propTypes.bool.def(true), + allowClear: propTypes.bool.def(true), + filterOption: { + type: Function as PropType<(searchValue: string, row: Recordable) => boolean>, + }, + searchIgnoreCase: propTypes.bool.def(true), + // 弹窗高度 + height: propTypes.number, }, - emits: ['select', 'change', 'update:value'], + emits: ['select', 'change', 'update:value', 'visible-change'], setup(props, { emit, slots, attrs }) { - const { showField, dropdownWidth, value: valueRef } = toRefs(props); + const { + showField, + dropdownWidth, + value: valueRef, + showSearch: showSearchRef, + allowClear: allowClearRef, + height: heightRef, + } = toRefs(props); const pulldownRef = ref(); const dataLoadingRef = ref(false); const tableDataRef = ref([]); const tableRef = ref(); + const searchValueRef = ref(''); + + const filterOptionFunction = props.filterOption + ? props.filterOption + : (searchValue: string, row: Recordable) => { + if (!searchValue || searchValue.trim().length === 0) { + return true; + } + const searchValueTrim = searchValue.trim(); + let showValue = ''; + if (props.showFunction) { + showValue = props.showFunction(row); + } else { + showValue = row[props.showField]; + } + if ( + (props.searchIgnoreCase ? showValue.toUpperCase() : showValue).includes(searchValueTrim) + ) { + return true; + } + const fieldValue: string = row[props.valueField].toString(); + return (props.searchIgnoreCase ? fieldValue.toUpperCase() : fieldValue).includes( + searchValueTrim, + ); + }; + const computeTableData = computed(() => { + const tableData = unref(tableDataRef); + if (tableData.length === 0) { + return tableData; + } + const searchValue = unref(searchValueRef); + if (!searchValue) { + return tableData; + } + return tableData.filter((item) => + filterOptionFunction( + props.searchIgnoreCase ? searchValue.toUpperCase() : searchValue, + item, + ), + ); + }); + /** + * 下拉框是否显示 + */ + const isVisibleRef = ref(false); // 选中的行 const selectRowRef = ref(null); const computedSelectRowValue = computed(() => { @@ -85,46 +146,67 @@ export default defineComponent({ * 下拉容器样式 */ const computedDropdownContainerStyle = computed(() => { - return { + const style: Recordable = { width: unref(dropdownWidth) + 'px', }; + const height = unref(heightRef); + if (height) { + style.height = `${height}px`; + } + return style; }); watch([valueRef, tableDataRef], ([value, tableData]) => { - const tableInstance: VxeGridInstance = unref(tableRef)?.tableAction.getTableInstance(); let row: Recordable | null = null; - if (!value) { - tableInstance && tableInstance.clearCurrentRow(); - selectRowRef.value = null; - return; - } - const selectRows = tableData.filter( - (item) => item[props.valueField].toString() === value.toString(), - ); - if (selectRows.length === 0) { - tableInstance && tableInstance.clearCurrentRow(); - } else { - row = selectRows[0]; - tableInstance && tableInstance.setCurrentRow(selectRows[0]); + if (value) { + const selectRows = tableData.filter( + (item) => item[props.valueField].toString() === value.toString(), + ); + if (selectRows.length > 0) { + row = selectRows[0]; + } } selectRowRef.value = row; + setCurrentRow(); }); /** * 显示弹窗 */ const handleShow = async () => { + isVisibleRef.value = true; unref(pulldownRef)?.showPanel(); if (props.alwaysLoad) { await loadTableData(); } + emit('visible-change', true); + setCurrentRow(); + }; + + /** + * 设置当前行 + */ + const setCurrentRow = () => { nextTick(() => { const tableInstance: VxeGridInstance = unref(tableRef)?.tableAction.getTableInstance(); + if (!tableInstance) { + return; + } const row = unref(selectRowRef); - row && tableInstance && tableInstance.setCurrentRow(row); + if (!row) { + tableInstance.clearCurrentRow(); + } else { + tableInstance.setCurrentRow(row); + } }); }; + const handleHide = () => { + isVisibleRef.value = false; + searchValueRef.value = ''; + emit('visible-change', false); + }; + const dropdownTableProps = { size: 'mini', ...props.tableProps, @@ -135,6 +217,7 @@ export default defineComponent({ onCellClick: ({ row }) => { changeValue(row); unref(pulldownRef)?.hidePanel(); + handleHide(); }, }; @@ -143,20 +226,58 @@ export default defineComponent({ state.value = row?.[props.valueField]; }; - const inputIconSlots = { - addonAfter: () => , - clearIcon: () => changeValue()} icon="ant-design:close-circle-filled" />, + /** + * 搜索框变化触发 + * @param value + */ + const handleSearchChange = (value: string) => { + searchValueRef.value = value; + setCurrentRow(); + }; + + // const inputIconSlots = { + // addonAfter: () => , + // clearIcon: () => changeValue()} icon="ant-design:close-circle-filled" />, + // }; + // + // const selectSlots = { + // suffixIcon: () => , + // }; + + const handleUpdateValue = () => { + changeValue(); + handleShow(); }; const pulldownSlots = { default: () => ( - - {inputIconSlots} - + //
+ // + // {inputIconSlots} + // + // abc + //
+ + + + + + + + ), dropdown: () => (
- +
), ...slots, @@ -164,6 +285,7 @@ export default defineComponent({ return () => (