From 3d775bfea16b5ac26ff0baac10f43b3367b0bf95 Mon Sep 17 00:00:00 2001 From: whycq <913841844@qq.com> Date: 星期日, 08 十月 2023 13:28:42 +0800 Subject: [PATCH] # --- uni_modules/uni-table/components/uni-th/filter-dropdown.vue | 503 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 503 insertions(+), 0 deletions(-) diff --git a/uni_modules/uni-table/components/uni-th/filter-dropdown.vue b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue new file mode 100644 index 0000000..fe8cd96 --- /dev/null +++ b/uni_modules/uni-table/components/uni-th/filter-dropdown.vue @@ -0,0 +1,503 @@ +<template> + <view class="uni-filter-dropdown"> + <view class="dropdown-btn" @click="onDropdown"> + <view class="icon-select" :class="{active: canReset}" v-if="isSelect || isRange"></view> + <view class="icon-search" :class="{active: canReset}" v-if="isSearch"> + <view class="icon-search-0"></view> + <view class="icon-search-1"></view> + </view> + <view class="icon-calendar" :class="{active: canReset}" v-if="isDate"> + <view class="icon-calendar-0"></view> + <view class="icon-calendar-1"></view> + </view> + </view> + <view class="uni-dropdown-cover" v-if="isOpened" @click="handleClose"></view> + <view class="dropdown-popup dropdown-popup-right" v-if="isOpened" @click.stop> + <!-- select--> + <view v-if="isSelect" class="list"> + <label class="flex-r a-i-c list-item" v-for="(item,index) in dataList" :key="index" + @click="onItemClick($event, index)"> + <check-box class="check" :checked="item.checked" /> + <view class="checklist-content"> + <text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text> + </view> + </label> + </view> + <view v-if="isSelect" class="flex-r opera-area"> + <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSelectReset"> + {{resource.reset}}</view> + <view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{resource.submit}}</view> + </view> + <!-- search --> + <view v-if="isSearch" class="search-area"> + <input class="search-input" v-model="filterValue" /> + </view> + <view v-if="isSearch" class="flex-r opera-area"> + <view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{resource.search}}</view> + <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSearchReset"> + {{resource.reset}}</view> + </view> + <!-- range --> + <view v-if="isRange"> + <view class="input-label">{{resource.gt}}</view> + <input class="input" v-model="gtValue" /> + <view class="input-label">{{resource.lt}}</view> + <input class="input" v-model="ltValue" /> + </view> + <view v-if="isRange" class="flex-r opera-area"> + <view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleRangeReset"> + {{resource.reset}}</view> + <view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{resource.submit}}</view> + </view> + <!-- date --> + <view v-if="isDate"> + <uni-datetime-picker ref="datetimepicker" :value="dateRange" type="datetimerange" return-type="timestamp" @change="datetimechange" @maskClick="timepickerclose"> + <view></view> + </uni-datetime-picker> + </view> + </view> + </view> +</template> + +<script> + import checkBox from '../uni-tr/table-checkbox.vue' + + const resource = { + "reset": "閲嶇疆", + "search": "鎼滅储", + "submit": "纭畾", + "filter": "绛涢��", + "gt": "澶т簬绛変簬", + "lt": "灏忎簬绛変簬", + "date": "鏃ユ湡鑼冨洿" + } + + const DropdownType = { + Select: "select", + Search: "search", + Range: "range", + Date: "date", + Timestamp: "timestamp" + } + + export default { + name: 'FilterDropdown', + emits:['change'], + components: { + checkBox + }, + options: { + virtualHost: true + }, + props: { + filterType: { + type: String, + default: DropdownType.Select + }, + filterData: { + type: Array, + default () { + return [] + } + }, + mode: { + type: String, + default: 'default' + }, + map: { + type: Object, + default () { + return { + text: 'text', + value: 'value' + } + } + } + }, + computed: { + canReset() { + if (this.isSearch) { + return this.filterValue.length > 0 + } + if (this.isSelect) { + return this.checkedValues.length > 0 + } + if (this.isRange) { + return (this.gtValue.length > 0 && this.ltValue.length > 0) + } + if (this.isDate) { + return this.dateSelect.length > 0 + } + return false + }, + isSelect() { + return this.filterType === DropdownType.Select + }, + isSearch() { + return this.filterType === DropdownType.Search + }, + isRange() { + return this.filterType === DropdownType.Range + }, + isDate() { + return (this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp) + } + }, + watch: { + filters(newVal) { + this._copyFilters() + }, + indeterminate(newVal) { + this.isIndeterminate = newVal + } + }, + data() { + return { + resource, + enabled: true, + isOpened: false, + dataList: [], + filterValue: '', + checkedValues: [], + gtValue: '', + ltValue: '', + dateRange: [], + dateSelect: [] + }; + }, + created() { + this._copyFilters() + }, + methods: { + _copyFilters() { + let dl = JSON.parse(JSON.stringify(this.filterData)) + for (let i = 0; i < dl.length; i++) { + if (dl[i].checked === undefined) { + dl[i].checked = false + } + } + this.dataList = dl + }, + openPopup() { + this.isOpened = true + if (this.isDate) { + this.$nextTick(() => { + if (!this.dateRange.length) { + this.resetDate() + } + this.$refs.datetimepicker.show() + }) + } + }, + closePopup() { + this.isOpened = false + }, + handleClose(e) { + this.closePopup() + }, + resetDate() { + let date = new Date() + let dateText = date.toISOString().split('T')[0] + this.dateRange = [dateText + ' 0:00:00', dateText + ' 23:59:59'] + }, + onDropdown(e) { + this.openPopup() + }, + onItemClick(e, index) { + let items = this.dataList + let listItem = items[index] + if (listItem.checked === undefined) { + items[index].checked = true + } else { + items[index].checked = !listItem.checked + } + + let checkvalues = [] + for (let i = 0; i < items.length; i++) { + const item = items[i] + if (item.checked) { + checkvalues.push(item.value) + } + } + this.checkedValues = checkvalues + }, + datetimechange(e) { + this.closePopup() + this.dateRange = e + this.dateSelect = e + this.$emit('change', { + filterType: this.filterType, + filter: e + }) + }, + timepickerclose(e) { + this.closePopup() + }, + handleSelectSubmit() { + this.closePopup() + this.$emit('change', { + filterType: this.filterType, + filter: this.checkedValues + }) + }, + handleSelectReset() { + if (!this.canReset) { + return; + } + var items = this.dataList + for (let i = 0; i < items.length; i++) { + let item = items[i] + this.$set(item, 'checked', false) + } + this.checkedValues = [] + this.handleSelectSubmit() + }, + handleSearchSubmit() { + this.closePopup() + this.$emit('change', { + filterType: this.filterType, + filter: this.filterValue + }) + }, + handleSearchReset() { + if (!this.canReset) { + return; + } + this.filterValue = '' + this.handleSearchSubmit() + }, + handleRangeSubmit(isReset) { + this.closePopup() + this.$emit('change', { + filterType: this.filterType, + filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)] + }) + }, + handleRangeReset() { + if (!this.canReset) { + return; + } + this.gtValue = '' + this.ltValue = '' + this.handleRangeSubmit(true) + } + } + } +</script> + +<style lang="scss"> + .flex-r { + display: flex; + flex-direction: row; + } + + .flex-f { + flex: 1; + } + + .a-i-c { + align-items: center; + } + + .j-c-c { + justify-content: center; + } + + .icon-select { + width: 14px; + height: 16px; + border: solid 6px transparent; + border-top: solid 6px #ddd; + border-bottom: none; + background-color: #ddd; + background-clip: content-box; + box-sizing: border-box; + } + + .icon-select.active { + background-color: #1890ff; + border-top-color: #1890ff; + } + + .icon-search { + width: 12px; + height: 16px; + position: relative; + } + + .icon-search-0 { + border: 2px solid #ddd; + border-radius: 8px; + width: 7px; + height: 7px; + } + + .icon-search-1 { + position: absolute; + top: 8px; + right: 0; + width: 1px; + height: 7px; + background-color: #ddd; + transform: rotate(-45deg); + } + + .icon-search.active .icon-search-0 { + border-color: #1890ff; + } + + .icon-search.active .icon-search-1 { + background-color: #1890ff; + } + + .icon-calendar { + color: #ddd; + width: 14px; + height: 16px; + } + + .icon-calendar-0 { + height: 4px; + margin-top: 3px; + margin-bottom: 1px; + background-color: #ddd; + border-radius: 2px 2px 1px 1px; + position: relative; + } + .icon-calendar-0:before, .icon-calendar-0:after { + content: ''; + position: absolute; + top: -3px; + width: 4px; + height: 3px; + border-radius: 1px; + background-color: #ddd; + } + .icon-calendar-0:before { + left: 2px; + } + .icon-calendar-0:after { + right: 2px; + } + + .icon-calendar-1 { + height: 9px; + background-color: #ddd; + border-radius: 1px 1px 2px 2px; + } + + .icon-calendar.active { + color: #1890ff; + } + + .icon-calendar.active .icon-calendar-0, + .icon-calendar.active .icon-calendar-1, + .icon-calendar.active .icon-calendar-0:before, + .icon-calendar.active .icon-calendar-0:after { + background-color: #1890ff; + } + + .uni-filter-dropdown { + position: relative; + font-weight: normal; + } + + .dropdown-popup { + position: absolute; + top: 100%; + background-color: #fff; + box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d; + min-width: 150px; + z-index: 1000; + } + + .dropdown-popup-left { + left: 0; + } + + .dropdown-popup-right { + right: 0; + } + + .uni-dropdown-cover { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + background-color: transparent; + z-index: 100; + } + + .list { + margin-top: 5px; + margin-bottom: 5px; + } + + .list-item { + padding: 5px 10px; + text-align: left; + } + + .list-item:hover { + background-color: #f0f0f0; + } + + .check { + margin-right: 5px; + } + + .search-area { + padding: 10px; + } + + .search-input { + font-size: 12px; + border: 1px solid #f0f0f0; + border-radius: 3px; + padding: 2px 5px; + min-width: 150px; + text-align: left; + } + + .input-label { + margin: 10px 10px 5px 10px; + text-align: left; + } + + .input { + font-size: 12px; + border: 1px solid #f0f0f0; + border-radius: 3px; + margin: 10px; + padding: 2px 5px; + min-width: 150px; + text-align: left; + } + + .opera-area { + cursor: default; + border-top: 1px solid #ddd; + padding: 5px; + } + + .opera-area .btn { + font-size: 12px; + border-radius: 3px; + margin: 5px; + padding: 4px 4px; + } + + .btn-default { + border: 1px solid #ddd; + } + + .btn-default.disable { + border-color: transparent; + } + + .btn-submit { + background-color: #1890ff; + color: #ffffff; + } +</style> -- Gitblit v1.9.1