React实现checkbox group多组选项和标签组显示的联动
实现功能:勾选checkbox项,确定后,已勾选的checkbox项以tag标签的形式展示,tag标签可快捷删除。


实现过程:
- 使用React。
- 使用Ant Design的Checkbox、Tag组件。
- 整个组件主要分为两个部分:多选框组和Tag标签组。
1. 多选框组
class AddInfo extends React.Component {
constructor(props) {
super(props);
this.state = {
checkedList: [], // checkbox已选择的选项
indeterminate: [], // 全选框-已有选择非全选
checkAll: {}, // checkbox group 的全部title状态true/false
tempList: [], // 临时存储checkbox已选择的选项
checkTitle: {} // checkbox group中已选择的title(全选)
};
}
/* 确定勾选 */
handleOk = () => {
if (this.state.tempList.length > 0) {
// 将已选择信息传给Tags组件
this.props.getChecked({
checkedItem: this.state.tempList,
checkAll: this.state.checkAll,
indeterminate: this.state.indeterminate,
checkTitle: this.state.checkTitle
});
}
}
/* checkbox单选 */
onChange = (allCheckArr, checkedList) => {
let checkAll = this.state.checkAll;
let indeterminate = [];
let checkTitle = {};
Object.keys(allCheckArr).forEach((title) => {
checkTitle[title] = 0;
for (let checkedItem of checkedList || []) {
if (allCheckArr[title].includes(checkedItem)) {
checkTitle[title]++;
checkAll[title] = checkTitle[title] === allCheckArr[title].length;
indeterminate[title] = !!checkTitle[title] && (checkTitle[title] < allCheckArr[title].length);
}
}
if (checkTitle[title] === 0) { // 选项组下仅有一个选项时取消选中
checkAll[title] = false;
}
});
this.setState({
checkedList,
tempList:checkedList,
indeterminate: indeterminate,
checkAll: checkAll,
checkTitle: checkTitle
});
}
/* checkbox全选 */
onCheckAllChange = (allCheckArr, title, e) => {
this.state.checkAll[title] = e.target.checked;
let checkedListT = [];
checkedListT.push(...this.state.checkedList);
let indeterminate = this.state.indeterminate || [];
let checkTitle = this.state.checkTitle || {};
if (e.target.checked === true) { // 全选
checkedListT.push(...allCheckArr[title]);
checkedListT = Array.from(new Set(checkedListT)); // 去重(原先indeterminate为true的情况)
checkTitle[title] = allCheckArr[title].length;
} else { // 取消全选
let common = checkedListT.filter(v => allCheckArr[title].includes(v));
checkedListT = checkedListT.concat(common).filter(v => checkedListT.includes(v) && !common.includes(v));
checkTitle[title] = 0;
}
indeterminate[title] = false;
this.setState({
tempList: checkedListT,
checkedList: checkedListT,
indeterminate: indeterminate,
checkTitle: checkTitle
});
}
render() {
const { checkedList, checkAll, indeterminate } = this.state;
const { allCheckArr } = this.props;
return (
<div className={styles.modalcontent} >
{
allCheckArr.map( ({ title, value }, key ) => (
<div className={styles.checksgroup}>
<div>
<Checkbox
indeterminate={indeterminate[title]}
onChange={this.onCheckAllChange.bind(this, allCheckArr, title)}
checked={checkAll[title]}
>
{title}
</Checkbox>
</div>
<br />
<CheckboxGroup className={styles.contents} options={value} value={checkedList} onChange={this.onChange.bind(this, allCheckArr)} />
</div>
))}
</div>
);
}
}
export default AddInfo;
- 由于Ant Design官网上checkbox group的示例代码只有一个check group,本组件是可以有多组的情况,因此主要通过checkedList,checkAll,indeterminate,checkTitle几个状态控制checkbox group与单个的checkbox的全勾选、半勾选、无勾选几种情况的联动。
- checkbox单选的操作是传入当前选择的所有的选项,然后与原先的可选项对比,计算出checkAll,indeterminate,checkTitle的值。每次要先将checkAll,indeterminate,checkTitle置空,遍历所有的已选项和待选项。
- checkbox全选的函数本来是可以复用单选的操作,但是全选之后得出checkAll,indeterminate,checkTitle的值的过程比单选更简单一些,不用遍历选项数组,所以重写了全选的逻辑,没有复用单选的函数,虽然代码量多几行,但是执行过程更简单一些。
2. Tag标签组
import React from 'react';
import { Tag } from 'antd';
import styles from './index.less';
class Tags extends React.Component {
constructor(props) {
super(props);
this.state = {
items: this.props.items, // 需要显示的tag数组
checkAll: this.props.checkAll, // 该tag所在的数组元素是否全部作为tag存在
indeterminate: this.props.indeterminate, // 该tag所在的数组元素是否部分作为tag存在
allCheckArr: this.props.allCheckArr, // 该tag所在的数组
checkTitle: this.props.checkTitle // 该tag所在的数组元素作为tag存在的数量
};
}
componentWillReceiveProps = ( value, nextState) => {
this.setState({
items: value.items,
checkAll: value.checkAll,
indeterminate: value.indeterminate,
allCheckArr: value.allCheckArr,
checkTitle: value.checkTitle
});
}
delete = (key, value, e) => {
e.preventDefault();
let items = this.state.items;
let checkAll = this.state.checkAll;
let indeterminate = this.state.indeterminate;
let allCheckArr = this.state.allCheckArr;
let checkTitle = this.state.checkTitle;
items.splice(key, 1);
for (let title in allCheckArr) {
for (let item of allCheckArr[title]) {
if (item === value) {
checkTitle[title]--;
checkAll[title] = false;
if (checkTitle[title] === 0) { // 该选项组下的选项全部删除
indeterminate[title] = false;
} else {
indeterminate[title] = true;
}
}
}
}
this.setState({
items: items,
checkAll: checkAll,
indeterminate: indeterminate,
checkTitle: checkTitle
});
this.props.changeCheckeditems(items);
}
render() {
const items = this.state.items?this.state.items:[];
return (
<div>
{
items.map((value, key) => (
<Tag className={styles.singletag} closable key={key} onClose={this.delete.bind(this, key, value)}>{value}</Tag>
))}
</div>
);
}
}
export default Tags;
在多选框组对选项勾选之后,将选择结果传入Tags标签组件,该组件以Tag标签将已勾选的选项展示出来。Tag标签可以点击右边的“x”快捷删除,删除后,多选框组中相应的选项也会取消勾选。
3. 组件使用
这两个组件放在同一个父组件中使用,实现值传递。
class parent extends React.Component {
/* 获取待选择选项 */
getAllCheckArr = () => {
...
this.setState({
allCheckArr
...
});
...
}
/* 获取checkbox选择的选项 */
getChecked = (val) => {
this.setState({
checkedItem: val.checkedItem,
checkAll: val.checkAll,
indeterminate: val.indeterminate,
checkTitle: val.checkTitle
});
}
/* 获取tags删除后的选项 */
changeChecked = (val) => {
...
this.setState({
changedItem: val
});
...
}
render() {
const { checkedItem, changedItem,, checkAll, indeterminate, checkTitle } = this.state;
return (
...
<AddInfo
checkList={this.state.checkedItem}
allCheckArr={this.state.allCheckArr|| []}
getChecked={this.getChecked.bind(this)}
/>
<Tags
allCheckArr={this.state.allCheckArr|| []}
checkAll={checkAll}
checkTitle={checkTitle}
indeterminate={indeterminate}
items={checkedItem}
changeChecked={this.changeChecked.bind(this)}
/>
...
);
}
}
代码经过了比较大程度的删改,删除了许多无关功能,只保留了组件功能的核心部分,因此直接copy可能会有报错。。。
React实现checkbox group多组选项和标签组显示的联动的更多相关文章
- 关于 ant Checkbox.Group 数组checked 设置失效问题
最近在频繁使用ant UI框架.在使用到checkbox的时候,需要从后台获取数组显示,然后发现数组设置了checked:true,并不能使多选框处于选中状态,阅读 Checkbox Group 的属 ...
- 浅谈 Checkbox Group 的双向数据绑定
前言 不曾想在忙碌的工作面前,写一篇技术博客也成了奢求. Checkbox 作为表单中最常见的一类元素,使用方式分为单值和多值,其中单值的绑定很简单,就是 true 和 false,但是多值(Chec ...
- 【翻译】从Store生成Checkbox Group
原文:Ext JS: Generating a Checkbox Group from a Store Ext JS的checkbox group可以用来将复选框组合成一个单一的逻辑字段.由于复选框时 ...
- 重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
原文:重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示 [源码下载] 重新想象 Windows 8 Store Ap ...
- 含有GROUP BY子句的查询中如何显示COUNT()为0的成果(分享)
在SQL Server数据库查询中,为了对查询成果进行对比.解析,我们经常会用到GROUP BY子句以及COUNT()函数来对查询成果进行分类.统计等.然则我们在应用的过程中往往会存在一些题目,本文我 ...
- group by分组后获得每组中符合条件的那条记录
当group by单独使用时,只显示出每组的第一条记录.如下,未分组时查询出两条记录 SELECT info.id, info.switch_id, info.port_id, info.mac_ad ...
- JS判断checkbox至少选择一项
function Check() { if(checkboxs("checkboxname") == false){ // checkboxname: checkbox的名字 al ...
- CheckBox只选择一项
最近做一个问卷的页面,客户那边说要使用checkbox而且只能选择一项 就写了下面的代码 <html xmlns="http://www.w3.org/1999/xhtml" ...
- checkbox 最多选两项
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
随机推荐
- Python 细节与基础拾遗
locals():当前环境下的全部局部变量,字典(dict)类型,所有的 key 均为字符串类型: if 'sess' in locals() and sess is not None: print( ...
- 【基础练习】【线性DP】codevs3641 上帝选人题解
这道题目的数据最后一个有问题,特殊处理了 上题目 题目描写叙述 Description 世界上的人都有智商IQ和情商EQ.我们用两个数字来表示人的智商和情商,数字大就代表其对应智商或情商高. 如今你面 ...
- C# 软件编码规范
一.代码注释 并不是所有的代码均需要注释. 1.类头部注释 /// <summary> /// 描述类的用途 /// 作者: 张三 /// 日期: 2015/12/1 /// </s ...
- 修改VNC的分辨率
http://blog.csdn.net/jlds123/article/details/9064437 有时候用VNC View打开远程linux桌面时,桌面显示不出来,只有一个灰色背景加上一个命令 ...
- [TypeScript] Simplify asynchronous callback functions using async/await
Learn how to write a promise based delay function and then use it in async await to see how much it ...
- [Vue] Use Vue.js Watchers to Respond to Async Updates
Use watchers to keep an eye on your data. Watchers are methods that are invoked when the specified a ...
- .netcore consul实现服务注册与发现-单节点部署
原文:.netcore consul实现服务注册与发现-单节点部署 一.Consul的基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分 ...
- C++ 快速入门笔记:基本语法
数据类型 枚举类型 enum color { red, green, blue } colors; colors = blue; 默认情况下,第一个名称的值是 0,后面的依次加 1.也可以自定初始值: ...
- [SVG] Combine Multiple SVGs into an SVG Sprite
In this lesson, we’ll explore the process of combining all of your SVG icons into one SVG sprite, to ...
- 版本控制(1)——SVN
一.工具下载 下载SVN: http://subversion.apache.org/ 我们选择Windows系统中的可视化的VisualSVN 如下图,左边是客户端,右边是服务器端,我们下载服务器端 ...