10 changed files with 453 additions and 23 deletions
@ -0,0 +1,174 @@ |
|||
Component({ |
|||
properties: { |
|||
// 是否显示底部弹出页面
|
|||
isShow: { |
|||
type: Boolean, |
|||
observer: function (newVal) { |
|||
if(newVal) { |
|||
this.show() |
|||
} else { |
|||
this.hide() |
|||
} |
|||
} |
|||
}, |
|||
// 返回给父组件的值是label还是value,默认value
|
|||
getTypeValue: { |
|||
type: Boolean, |
|||
value: true |
|||
}, |
|||
// 列表数据,转换为checkList
|
|||
listData: { |
|||
type: Array, |
|||
value: [] |
|||
}, |
|||
// 默认数据,复显
|
|||
defaultList: { |
|||
type: Array, |
|||
value: [] |
|||
}, |
|||
// listData中的label 名,默认 label
|
|||
label: { |
|||
type: String, |
|||
value: 'label' |
|||
}, |
|||
// listData中的value 名,默认 value
|
|||
value: { |
|||
type: String, |
|||
value: 'value' |
|||
}, |
|||
// 单选还是多选,默认多选 (未实现)
|
|||
// isSingle: {
|
|||
// type: Boolean,
|
|||
// value: false
|
|||
// }
|
|||
}, |
|||
data: { |
|||
checkList: [], |
|||
checkedItemLabels: [], // 选中的label集合
|
|||
checkedItemValues: [], // 选中的value集合
|
|||
searchList: [], // 搜索结果列表
|
|||
searchKey: '', // 搜索的值
|
|||
searchFocus: false, |
|||
initAnimation: '', |
|||
}, |
|||
lifetimes: { |
|||
attached () { |
|||
this.animation = wx.createAnimation({ |
|||
duration: 600, |
|||
timingFunction: 'ease' |
|||
}) |
|||
this.hide() |
|||
|
|||
this.initData() |
|||
} |
|||
}, |
|||
methods: { |
|||
// pageLifetimes 无效
|
|||
show () { |
|||
this.animation.translateY(0).step() |
|||
this.setData({ |
|||
initAnimation: this.animation.export() |
|||
}) |
|||
this.initData() |
|||
}, |
|||
hide () { |
|||
this.animation.translateY(500).step() |
|||
this.setData({ |
|||
initAnimation: this.animation.export() |
|||
}) |
|||
}, |
|||
initData () { |
|||
this.data.checkList = [] |
|||
this.data.checkedItemLabels = [] |
|||
this.data.checkedItemValues = [] |
|||
this.data.listData.forEach((item, key) => { |
|||
let checkListItem = { |
|||
label: item[this.data.label], |
|||
value: item[this.data.value], |
|||
checked: false |
|||
} |
|||
this.data.checkList.push(checkListItem) |
|||
}) |
|||
if (this.data.defaultList.length > 0) { |
|||
this.data.defaultList.forEach(item => { |
|||
this.data.checkList.forEach(checkItem => { |
|||
if(item == checkItem.value) { |
|||
checkItem.checked = true |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
let checkedLabel = [] |
|||
let checkedValue = [] |
|||
this.data.checkList.forEach(item => { |
|||
if (item.checked) { |
|||
checkedLabel.push(item.label) |
|||
checkedValue.push(item.value) |
|||
} |
|||
}) |
|||
this.setData({ |
|||
checkList: this.data.checkList, |
|||
checkedItemLabels: checkedLabel, |
|||
checkedItemValues: checkedValue |
|||
}) |
|||
}, |
|||
changeCheckedItem(e) { |
|||
let changeItem = e.currentTarget.dataset.item |
|||
changeItem.checked = !changeItem.checked |
|||
this.data.checkList.forEach(item => { |
|||
if (changeItem.value == item.value) { |
|||
item.checked = changeItem.checked |
|||
} |
|||
}) |
|||
let checkedLabels = this.data.checkedItemLabels |
|||
let checkedValues = this.data.checkedItemValues |
|||
if (changeItem.checked) { |
|||
checkedLabels.push(changeItem.label) |
|||
checkedValues.push(changeItem.value) |
|||
} else { |
|||
let delIndex = checkedValues.indexOf(changeItem.value) |
|||
if (delIndex > -1) { |
|||
checkedLabels.splice(delIndex, 1) |
|||
checkedValues.splice(delIndex, 1) |
|||
} |
|||
} |
|||
this.setData({ |
|||
checkList: this.data.checkList, |
|||
checkedItemLabels: checkedLabels, |
|||
checkedItemValues: checkedValues, |
|||
searchList: [], |
|||
searchKey: '' |
|||
}) |
|||
}, |
|||
onInput (e) { |
|||
let value = e.detail.value.toLowerCase() |
|||
let list = [] |
|||
this.data.checkList.forEach(item => { |
|||
if (item.label.toLowerCase().indexOf(value) > -1) { |
|||
list.push(item) |
|||
} |
|||
}) |
|||
this.setData({ |
|||
searchList: list, |
|||
searchKey: value |
|||
}) |
|||
}, |
|||
onFocus () { |
|||
this.setData({ |
|||
searchFocus: true |
|||
}) |
|||
}, |
|||
onblur () { |
|||
this.setData({ |
|||
searchFocus: false |
|||
}) |
|||
}, |
|||
confirm () { |
|||
let values = this.data.getTypeValue ? this.data.checkedItemValues : this.data.checkedItemLabels |
|||
this.triggerEvent('onConfirm', { itemList: values }) |
|||
}, |
|||
cancel () { |
|||
this.triggerEvent('onCancel') |
|||
} |
|||
} |
|||
}) |
@ -0,0 +1,4 @@ |
|||
{ |
|||
"component": true, |
|||
"usingComponents": {} |
|||
} |
@ -0,0 +1,31 @@ |
|||
<view class="box" wx:if="{{isShow}}"> |
|||
<view class="bottom-box" animation="{{initAnimation}}"> |
|||
<view class="menu-box"> |
|||
<view class="menu-left" bindtap="cancel">取消</view> |
|||
<view class="menu-title">请选择</view> |
|||
<view class="menu-right" bindtap="confirm">确定</view> |
|||
</view> |
|||
<block wx:if="{{checkList.length > 0}}"> |
|||
<view class="input-box" bindtap="onFocus"> |
|||
<view class="select-item" wx:for="{{checkedItemLabels}}" wx:key="index">{{item}}</view> |
|||
<view class="input-item"> |
|||
<input class="input-content" type="text" bindinput="onInput" value="{{searchKey}}" focus="{{searchFocus}}" bindblur="onblur"/> |
|||
</view> |
|||
</view> |
|||
<!-- 正常状态显示 --> |
|||
<view class="check-box" wx:if="{{searchKey == ''}}"> |
|||
<view class="check-item {{item.checked ? 'check-item-active' : ''}}" wx:for="{{checkList}}" wx:key="index" bindtap="changeCheckedItem" data-item="{{item}}"> |
|||
<view class="check-title">{{item.label}}</view> |
|||
<view class="check-icon" wx:if="{{item.checked}}">√</view> |
|||
</view> |
|||
</view> |
|||
<!-- 搜索时显示 --> |
|||
<view class="check-box" wx:else> |
|||
<view class="check-item {{item.checked ? 'check-item-active' : ''}}" wx:for="{{searchList}}" wx:key="index" bindtap="changeCheckedItem" data-item="{{item}}"> |
|||
<view class="check-title">{{item.label}}</view> |
|||
<view class="check-icon" wx:if="{{item.checked}}">√</view> |
|||
</view> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
</view> |
@ -0,0 +1,99 @@ |
|||
/* components/nodata/nodata.wxss */ |
|||
.box{ |
|||
width: 100%; |
|||
height: 100vh; |
|||
box-sizing: border-box; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 9999; |
|||
background: rgba(50, 50, 50, 0.6); |
|||
} |
|||
.bottom-box-show { |
|||
} |
|||
.bottom-box-hide { |
|||
} |
|||
.bottom-box { |
|||
width: 100%; |
|||
max-height: 65%; |
|||
background: #fff; |
|||
position: absolute; |
|||
bottom: 0; |
|||
padding: 10rpx 30rpx 30rpx 30rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
.bottom-box .menu-box { |
|||
width: 100%; |
|||
height: 60rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-around; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
.bottom-box .menu-box .menu-left { |
|||
width: 15%; |
|||
text-align: left; |
|||
/* color: #16b64f; */ |
|||
} |
|||
.bottom-box .menu-box .menu-title { |
|||
width: 70%; |
|||
text-align: center; |
|||
} |
|||
.bottom-box .menu-box .menu-right { |
|||
width: 15%; |
|||
text-align: right; |
|||
color: #108af6; |
|||
} |
|||
.bottom-box .input-box { |
|||
width: 100%; |
|||
min-height: 100rpx; |
|||
max-height: 240rpx; |
|||
background: #f7f7f7; |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 20rpx; |
|||
box-sizing: border-box; |
|||
overflow: scroll; |
|||
flex-wrap: wrap; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
.bottom-box .input-box .select-item { |
|||
padding: 4rpx 10rpx; |
|||
box-sizing: border-box; |
|||
/* background: #0fb0ee70; */ |
|||
background: #dddddd; |
|||
margin-right: 10rpx; |
|||
margin-bottom: 10rpx; |
|||
border-radius: 8rpx; |
|||
/* color: #fff; |
|||
border: 1px solid #0fb0ee; */ |
|||
word-break: break-all; |
|||
} |
|||
.bottom-box .input-box .input-item .input-content{ |
|||
width: 100rpx; |
|||
} |
|||
.bottom-box .check-box { |
|||
max-height: 400rpx; |
|||
overflow-y: scroll; |
|||
padding-right: 12rpx; |
|||
margin-bottom: 60rpx; |
|||
} |
|||
.check-box .check-item { |
|||
width: 100%; |
|||
min-height: 80rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
border-bottom: 1px solid #e7e7e7; |
|||
} |
|||
.check-box .check-item-active { |
|||
color: #108af6; |
|||
} |
|||
.check-box .check-item .check-title{ |
|||
width: 620rpx; |
|||
overflow: hidden; |
|||
word-break: break-all; |
|||
} |
|||
.check-box .check-item .check-icon { |
|||
|
|||
} |
Loading…
Reference in new issue