/*node
* @Author: wangxinyue react
* @Date: 2018-12-28 18:13:04 數組
* @Last Modified by: wangxinyueantd
* @Last Modified time: 2018-12-29 11:14:28函數
* groupList 全選的數組集合ui
* checkboxKey 對象型數組時使用(惟一標識)this
* changeCheck 多選框的回調函數返回數據(isSelectAll是否全選,checked 是否選中, checkedArr選中數組, changeArr變化數組, checkedList選中集合數組, changeList變化集合數組)component
* checkboxGroupChild 子元素nodecdn
* defaultCheckedArr 默認選中的數組對象
* selectAllClass 全選樣式
* selectAllNode 全選node
* disabledOption 禁用函數
*/
import React, { Component } from 'react'
import { Checkbox } from 'antd';
import PropTypes from 'prop-types'
const CheckboxGroup = Checkbox.Group;
class WXYCheckboxGroup extends Component {
static propTypes = {
groupList: PropTypes.array.isRequired,//全選集合
checkboxGroupChild: PropTypes.node.isRequired,//多選框子元素
changeCheck: PropTypes.func,//獲取數據變化信息
checkboxKey: PropTypes.string,//多選框的惟一標識
defaultCheckedArr: PropTypes.array,//默認選中的數組
}
state = {
checkedArr: [],//當前選中的多選框數組
indeterminate: true,//全選框狀態
checkAll: false,//是否全選
lastcheckedArr: [],//上一次選中的多選框數組
allCheckedAll: [],//全選數組
disableAndCheckedArr: []
};
componentDidMount = () => {
const { defaultCheckedArr = [], checkboxKey, groupList, disabledOption } = this.props
let allCheckedAll = []
if (disabledOption) {
//過濾掉禁用未選中的數據
allCheckedAll = groupList.filter(one => !disabledOption(one) || defaultCheckedArr.includes(one[checkboxKey]))
}
allCheckedAll = checkboxKey ? allCheckedAll.map(one => one[checkboxKey]) : allCheckedAll
this.setState({
checkedArr: defaultCheckedArr,
lastcheckedArr: defaultCheckedArr,
allCheckedAll: allCheckedAll,
disableAndCheckedArr: this.getDisableAndChecked()
})
}
//獲取禁用且選中的數據
getDisableAndChecked = () => {
const { defaultCheckedArr = [], checkboxKey, groupList, disabledOption } = this.props
let disableAndChecked = groupList.filter(one => disabledOption(one) && defaultCheckedArr.includes(one[checkboxKey]))
//只返回key
return disableAndChecked.map(one => one[checkboxKey])
}
//單選操做
onChange = (checkedArr) => {
const { allCheckedAll } = this.state
this.setState({
checkedArr,
lastcheckedArr: checkedArr,
indeterminate: !!checkedArr.length && (checkedArr.length < allCheckedAll.length),
checkAll: checkedArr.length === allCheckedAll.length,
});
this.getChangeObject(checkedArr, false)
}
//全選操做
onCheckAllChange = (e) => {
const { disabledOption } = this.props
const { allCheckedAll, disableAndCheckedArr } = this.state
let checkedArr = e.target.checked ? allCheckedAll : []
if (disabledOption) {
checkedArr = [...checkedArr, ...disableAndCheckedArr]
}
this.setState({
checkedArr: checkedArr,
lastcheckedArr: checkedArr,
indeterminate: false,
checkAll: e.target.checked,
});
this.getChangeObject(checkedArr, true)
}
//獲取並返回變化數據
getChangeObject = (checkedArr, isSelectAll) => {
const { changeCheck } = this.props
const { lastcheckedArr } = this.state
let checked = checkedArr.length > lastcheckedArr.length
let changeArr = this.diff(checkedArr, lastcheckedArr)
changeCheck && changeCheck(isSelectAll, checked, checkedArr, changeArr, this.getListByArr(checkedArr), this.getListByArr(changeArr))
}
//根據字符串數組返回對象型數組
getListByArr = (arr) => {
const { groupList, checkboxKey } = this.props
return groupList && checkboxKey ? groupList.filter(one => arr.includes(one[checkboxKey])) : []
}
//比較兩個數組中不一樣的元素[1,2,3] [1,2] 返回[3]
diff(arr1, arr2) {
var newArr = [];
var arr3 = [];
for (var i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) === -1)
arr3.push(arr1[i]);
}
var arr4 = [];
for (var j = 0; j < arr2.length; j++) {
if (arr1.indexOf(arr2[j]) === -1)
arr4.push(arr2[j]);
}
newArr = arr3.concat(arr4);
return newArr;
}
render() {
const { checkboxGroupChild, selectAllClass, selectAllNode = "全選" } = this.props
return (
<div>
<div className={selectAllClass}>
<Checkbox
indeterminate={this.state.indeterminate}
onChange={this.onCheckAllChange}
checked={this.state.checkAll}>
{selectAllNode}
</Checkbox>
</div>
<CheckboxGroup value={this.state.checkedArr} onChange={(checkedValues) => this.onChange(checkedValues, this)}>
{checkboxGroupChild}
</CheckboxGroup>
</div>
);
}
}
class Test extends Component {
constructor(props) {
super(props);
this.state = {};
}
changeCheck = (checked, checkedArr, changeArr, checkedList, changeList) => {
console.log("checked", checked,
"checkedArr", checkedArr,
"changeArr", changeArr,
"checkedList", checkedList,
"changeList", changeList);
}
disabledOption = (one) => {
return one.disabled
}
render() {
const defaultcheckedArr = ['pite', 'jiake', 'xuzi'];
const plainList = [
{ name: "皮特", key: "pite" },
{ name: "夾克", key: "jiake" },
{ name: "徐子", key: "xuzi", disabled: true },
{ name: "孟獲", key: "menghuo" },
{ name: "秋季", key: "qiuji" },
{ name: "子曰", key: "ziyue", disabled: true },
{ name: "雪兒", key: "xueer", disabled: true },
]
return (
<WXYCheckboxGroup
defaultCheckedArr={defaultcheckedArr}
groupList={plainList}
checkboxKey='key'
checkboxGroupChild={plainList.map(one => <Item key={one.key} one={one} />)}
changeCheck={this.changeCheck}
disabledOption={this.disabledOption} />
);
}
}
export default Test;
class Item extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { one } = this.props
return (
<div>
<Checkbox value={one.key} disabled={one.disabled} />
{one.name}
</div>
);
}
}