Skip to content

Commit

Permalink
add filterbar
Browse files Browse the repository at this point in the history
  • Loading branch information
skyvow committed Dec 27, 2017
1 parent 2ec62f7 commit 799bb42
Show file tree
Hide file tree
Showing 28 changed files with 2,382 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#### v 2.0.1 (2017-12-27)

- 【增强】 增加 vcode 组件
- 【增强】 增加 filterbar 组件

#### v 2.0.0 (2017-12-11)

- 【优化】 引入 CSS BEM 命名规范重构组件
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* [CountDown - 倒计时](https://github.com/skyvow/wux/blob/master/docs/components/countdown.md)
* [CountUp - 计数器](https://github.com/skyvow/wux/blob/master/docs/components/countup.md)
* [Dialog - 对话框](https://github.com/skyvow/wux/blob/master/docs/components/dialog.md)
* [FilterBar - 筛选栏](https://github.com/skyvow/wux/blob/master/docs/components/filterbar.md)
* [Gallery - 画廊](https://github.com/skyvow/wux/blob/master/docs/components/gallery.md)
* [KeyBoard - 键盘](https://github.com/skyvow/wux/blob/master/docs/components/keyboard.md)
* [Loading - 指示器](https://github.com/skyvow/wux/blob/master/docs/components/loading.md)
Expand Down Expand Up @@ -108,6 +109,8 @@

<img src="https://github.com/skyvow/wux/blob/master/screenshots/screenshorts-27.png" width="375px" style="display:inline;">

<img src="https://github.com/skyvow/wux/blob/master/screenshots/screenshorts-28.png" width="375px" style="display:inline;">

## 贡献

有任何意见或建议都欢迎提 issue
Expand Down
1 change: 1 addition & 0 deletions dist/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"pages/calendar/index",
"pages/button/index",
"pages/vcode/index",
"pages/filterbar/index",
"pages/about/index"
],
"window": {
Expand Down
Binary file added dist/assets/images/iconfont-filterbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
244 changes: 244 additions & 0 deletions dist/components/filterbar/filterbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
import Component from '../component'

export default {
/**
* 初始化筛选栏
* @param {Object} opts 配置项
* @param {Array} opts.items 按钮的配置数组
* @param {Function} opts.onChange 选中值变化的回调函数
*/
init(opts = {}) {
const options = Object.assign({}, opts)

// 实例化组件
const component = new Component({
scope: `$wux.filterbar`,
data: options,
methods: {
/**
* 隐藏
*/
hide() {
if (this.removed) return !1
this.removed = !0
this.setHidden()
},
/**
* 显示
*/
show() {
if (this.removed) return !1
this.setVisible()
},
/**
* 重置按钮
* @param {Object} e 事件对象
*/
onReset(e) {
const { index, item } = e.currentTarget.dataset
const children = item.children.map((n) => {
return Object.assign({}, n, {
children: n.children.map((m) => Object.assign({}, m, {
checked: false,
})),
selected: '',
})
})
this.setData({
[`$wux.filterbar.items[${index}].children`]: children,
})
},
/**
* 确认按钮
* @param {Object} e 事件对象
*/
onConfirm(e) {
const { index } = e.currentTarget.dataset
this.setData({
[`$wux.filterbar.items[${index}].visible`]: false,
}, this.onChange)
},
/**
* 筛选栏内单项选择触发 change 事件
* @param {Object} e 事件对象
*/
onRadioChange(e) {
const { value } = e.detail
const { index, item, parentIndex } = e.currentTarget.dataset
const children = item.children.map((n) => Object.assign({}, n, {
checked: n.value === value,
}))
const selected = children.filter((n) => n.checked).map((n) => n.label).join(',')
this.setData({
[`$wux.filterbar.items[${parentIndex}].children[${index}].children`]: children,
[`$wux.filterbar.items[${parentIndex}].children[${index}].selected`]: selected,
})
},
/**
* 筛选栏内多项选择触发 change 事件
* @param {Object} e 事件对象
*/
onCheckboxChange(e) {
const { value } = e.detail
const { index, item, parentIndex } = e.currentTarget.dataset
const children = item.children.map((n) => Object.assign({}, n, {
checked: value.includes(n.value),
}))
const selected = children.filter((n) => n.checked).map((n) => n.label).join(',')
this.setData({
[`$wux.filterbar.items[${parentIndex}].children[${index}].children`]: children,
[`$wux.filterbar.items[${parentIndex}].children[${index}].selected`]: selected,
})
},
/**
* 下拉框内单项选择触发 change 事件
* @param {Object} e 事件对象
*/
radioChange(e) {
const { value } = e.detail
const { index, item } = e.currentTarget.dataset
const children = item.children.map((n) => Object.assign({}, n, {
checked: n.value === value,
}))
this.setData({
[`$wux.filterbar.items[${index}].children`]: children,
}, this.onChange)
},
/**
* 下拉框内多项选择触发 change 事件
* @param {Object} e 事件对象
*/
checkboxChange(e) {
const { value } = e.detail
const { index, item } = e.currentTarget.dataset
const children = item.children.map((n) => Object.assign({}, n, {
checked: value.includes(n.value),
}))
this.setData({
[`$wux.filterbar.items[${index}].children`]: children,
}, this.onChange)
},
/**
* 点击事件
* @param {Object} e 事件对象
*/
onClick(e) {
const { index } = e.currentTarget.dataset
this.onOpenSelect(this.page.data.$wux.filterbar.items, index)
},
/**
* 打开下拉框
* @param {Array} data 菜单数据
* @param {Number} index 当前索引
*/
onOpenSelect(data = [], index = 0) {
const current = data[index]
const items = data.map((n, i) => {
const params = Object.assign({}, n, {
checked: index === i ? !n.checked : false,
})

// 判断已选择的元素是否同组
if (n.checked) {
const has = this.getDifference(n.groups, current.groups)

params.checked = !!has.length

// 判断非同组的元素清空选择内容
if (index !== i && !has.length) {
if (typeof params.children === 'object') {
if (['radio', 'checkbox'].includes(n.type)) {
params.children = params.children.map((n) => Object.assign({}, n, {
checked: false,
}))
}

if (['filter'].includes(n.type)) {
params.children = params.children.map((n) => {
return Object.assign({}, n, {
children: n.children.map((m) => Object.assign({}, m, {
checked: false,
})),
selected: '',
})
})
}
}

if (['sort'].includes(n.type)) {
params.sort = undefined
}
}
}

// 展开或隐藏下拉框
if (['radio', 'checkbox', 'filter'].includes(n.type)) {
params.visible = index === i ? !n.visible : false
}

// 当前点击排序做出处理
if (index === i && ['sort'].includes(n.type)) {
params.sort = typeof params.sort === 'number' ? -params.sort : 1
}

return params
})

this.setData({
[`$wux.filterbar.items`]: items,
}, () => {
if (!['radio', 'checkbox', 'filter'].includes(current.type)) {
this.onChange()
}
})
},
/**
* 关闭下拉框
*/
onCloseSelect() {
const items = this.page.data.$wux.filterbar.items
const params = {}

items.forEach((n, i) => {
if (n.checked && n.visible) {
params[`$wux.filterbar.items[${i}].visible`] = false
}
})

this.setData(params)
},
/**
* 获取两个数组相同的元素
* @param {Array} data 数组
* @param {Array} values 数组
*/
getDifference(data = [], values = []) {
return data.filter(v => values.includes(v))
},
/**
* 重置元素
* @param {Object} item 数据对象
*/
resetValue(item = {}) {
items.children.map((n) => Object.assign({}, n, {
checked: false,
}))
},
/**
* 元素发生变化时的事件
*/
onChange() {
const items = this.page.data.$wux.filterbar.items
const checkedItems = items.filter((n) => n.checked)
if (typeof options.onChange === 'function') {
options.onChange.call(this, checkedItems, items)
}
},
},
})

component.show()

return component
},
}
76 changes: 76 additions & 0 deletions dist/components/filterbar/filterbar.wxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<template name="filterbar">
<view class="wux-filterbar {{ animateCss }}" wx:if="{{ visible }}">
<view class="wux-filterbar__bd">
<block wx:for="{{ items }}" wx:key="">
<view class="wux-filterbar__item {{ item.checked ? 'wux-filterbar__item--checked' : '' }}" bindtap="{{ onClick }}" data-index="{{ index }}">
<text class="wux-filterbar__text">{{ item.label }}</text>
<text class="wux-filterbar__icon {{ 'wux-filterbar__icon--' + item.type }} {{ item.sort === 1 ? 'wux-filterbar__icon--sort-asc' : item.sort === -1 ? 'wux-filterbar__icon--sort-desc' : '' }}" wx:if="{{ item.type === 'radio' || item.type === 'checkbox' || item.type === 'sort' || item.type === 'filter' }}"></text>
</view>
</block>
</view>
<block wx:for="{{ items }}" wx:key="">
<view class="wux-backdrop {{ animateCss }}" hidden="{{ !item.visible }}" wx:if="{{ item.type === 'filter' }}"></view>
<view class="wux-filterbar__pop {{ item.visible ? 'wux-animate--slide-in-right' : 'wux-animate--slide-out-right' }}" hidden="{{ !item.visible }}" wx:if="{{ item.type === 'filter' }}">
<scroll-view class="wux-filterbar__scroll-view" scroll-y>
<block wx:for="{{ item.children }}" wx:for-item="p" wx:for-index="pIndex" wx:key="">
<view class="wux-filterbar__panel">
<view class="wux-filterbar__panel-hd">
<div class="wux-filterbar__panel-title">{{ p.label }}</div>
<div class="wux-filterbar__panel-selected">{{ p.selected }}</div>
</view>
<view class="wux-filterbar__panel-bd">
<radio-group name="{{ p.value }}" bindchange="{{ onRadioChange }}" data-parent-index="{{ index }}" data-index="{{ pIndex }}" data-item="{{ p }}" wx:if="{{ p.type === 'radio' }}">
<view class="wux-filterbar__groups">
<block wx:for="{{ p.children }}" wx:for-item="g" wx:key="">
<view class="wux-filterbar__group">
<radio class="wux-filterbar__radio" value="{{ g.value }}" checked="{{ g.checked }}" />
<view class="wux-filterbar__btn {{ g.checked ? 'wux-filterbar__btn--checked' : '' }}">{{ g.label }}</view>
</view>
</block>
</view>
</radio-group>
<checkbox-group name="{{ p.value }}" bindchange="{{ onCheckboxChange }}" data-parent-index="{{ index }}" data-index="{{ pIndex }}" data-item="{{ p }}" wx:else="{{ p.type === 'checkbox' }}">
<view class="wux-filterbar__groups">
<block wx:for="{{ p.children }}" wx:for-item="g" wx:key="">
<view class="wux-filterbar__group">
<checkbox class="wux-filterbar__check" value="{{ g.value }}" checked="{{ g.checked }}" />
<view class="wux-filterbar__btn {{ g.checked ? 'wux-filterbar__btn--checked' : '' }}">{{ g.label }}</view>
</view>
</block>
</view>
</checkbox-group>
</view>
</view>
</block>
</scroll-view>
<div class="wux-filterbar__btns">
<view class="wux-filterbar__btn" data-index="{{ index }}" data-item="{{ item }}" bindtap="{{ onReset }}">重置</view>
<view class="wux-filterbar__btn wux-filterbar__btn--danger" data-index="{{ index }}" bindtap="{{ onConfirm }}">确定</view>
</div>
</view>
<view class="wux-cells wux-cells--pos" hidden="{{ !item.visible }}" wx:if="{{ item.type === 'radio' }}">
<radio-group name="{{ item.value }}" bindchange="{{ radioChange }}" data-index="{{ index }}" data-item="{{ item }}">
<label class="wux-cell wux-check__label" wx:for="{{ item.children }}" wx:for-item="p" wx:key="{{ item.value }}">
<radio class="wux-check" value="{{ p.value }}" checked="{{ p.checked }}" />
<view class="wux-cell__bd">{{ p.label }}</view>
<view class="wux-cell__ft wux-cell__ft--in-radio" wx:if="{{ p.checked }}">
<icon class="wux-icon-radio" type="success_no_circle" size="16"></icon>
</view>
</label>
</radio-group>
</view>
<view class="wux-cells wux-cells--pos" hidden="{{ !item.visible }}" wx:if="{{ item.type === 'checkbox' }}">
<checkbox-group name="{{ item.value }}" bindchange="{{ checkboxChange }}" data-index="{{ index }}" data-item="{{ item }}">
<label class="wux-cell wux-check__label" wx:for="{{ item.children }}" wx:for-item="p" wx:key="{{ item.value }}">
<checkbox class="wux-check" value="{{ p.value }}" checked="{{ p.checked }}" />
<view class="wux-cell__hd wux-check__hd--in-checkbox">
<icon class="wux-icon-checkbox--circle" type="circle" size="23" wx:if="{{ !p.checked }}"></icon>
<icon class="wux-icon-checkbox--success" type="success" size="23" wx:if="{{ p.checked }}"></icon>
</view>
<view class="wux-cell__bd">{{ item.label }}</view>
</label>
</checkbox-group>
</view>
</block>
</view>
</template>
Loading

0 comments on commit 799bb42

Please sign in to comment.