index.jsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React, { Component } from "react";
  2. import { Button, message, Modal, Spin, Table, Checkbox, Collapse, } from "antd";
  3. import $ from "jquery/src/ajax";
  4. import "./index.less";
  5. class Cascaders extends Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. visible: false,
  10. authTree: [],
  11. checkedList: [],
  12. };
  13. this.itemHandle = this.itemHandle.bind(this);
  14. this.onSelect = this.onSelect.bind(this);
  15. this.onOks = this.onOks.bind(this);
  16. this.onCancel = this.onCancel.bind(this);
  17. }
  18. componentDidMount() {
  19. // 后端返回的数据,转成前端要用的数据保存页面使用
  20. // const authTree = [...params.authTree];
  21. // this.setState({
  22. // authTree
  23. // })
  24. }
  25. // 转成前端要用的数据
  26. authTreeFun() {
  27. const checkedList = this.state.checkedList;
  28. checkedList.forEach((item) => {
  29. this.itemHandle(item);
  30. });
  31. }
  32. // 点击选择部门
  33. onSelect() {
  34. const list = JSON.parse(localStorage.getItem("departmentData"))
  35. const authTree = list
  36. this.setState({
  37. visible: true,
  38. authTree: authTree,
  39. }, () => {
  40. this.authTreeFun();
  41. })
  42. }
  43. onOks() {
  44. const { authTree, checkedList } = this.state
  45. const { id = "id", children = "children", onSel } = this.props
  46. let list = []
  47. authTree.forEach((its) => {
  48. if (its[children]) {
  49. its[children].forEach((itl) => {
  50. if (itl.checked) {
  51. list.push(itl[id])
  52. }
  53. });
  54. }
  55. })
  56. this.setState({
  57. checkedList: list,
  58. visible: false,
  59. })
  60. onSel(checkedList)
  61. }
  62. onCancel() {
  63. this.setState({
  64. visible: false,
  65. })
  66. }
  67. // 代码三级联动核心就在这里
  68. itemHandle(iD, checked = true) {
  69. const { id = "id", children = "children" } = this.props
  70. const { authTree } = this.state
  71. // const authTree = [...this.state.authTree];
  72. authTree.forEach((item1) => {
  73. if (item1[id] == iD) {
  74. item1.checked = checked;
  75. if (item1[children]) {
  76. item1[children].forEach((item2) => {
  77. item2.checked = checked;
  78. });
  79. }
  80. } else {
  81. // 反向思路: 保存子选项框的个数, 子选项选中就-1, 等于0说明都选中了, 父选项就勾上
  82. let temp1 = !!item1[children] ? item1[children].length : 0;
  83. !!item1[children] && item1[children].forEach((item2) => {
  84. if (item2[id] == iD) {
  85. item2.checked = checked;
  86. }
  87. // 选中-1, 未选中不动
  88. item2.checked ? temp1 -= 1 : temp1;
  89. });
  90. // 长度是0, 父选项框就勾选
  91. !!item1[children] && temp1 === 0 ? item1.checked = true : item1.checked = false;
  92. }
  93. });
  94. this.setState({
  95. authTree,
  96. });
  97. }
  98. render() {
  99. const { Panel } = Collapse;
  100. const { visible, authTree, checkedList } = this.state
  101. const {
  102. placeholder = "选择部门",
  103. width = 200,
  104. height = 32,
  105. id = "id",
  106. name = "name",
  107. children = "children",
  108. } = this.props
  109. const authTreeMap = authTree.map((item1) => (
  110. // Panel是手风琴
  111. <Panel
  112. key={item1[id]}
  113. header={(
  114. <div className="item" onClick={(e) => { e.stopPropagation(); }}>
  115. {/* 一级复选框(向下操控二级三级) */}
  116. <Checkbox
  117. name={item1[id]}
  118. checked={item1.checked}
  119. onClick={(e) => {
  120. this.itemHandle(e.target.name, e.target.checked);
  121. }}
  122. >
  123. </Checkbox>
  124. <div className="iname">{item1[name]}</div>
  125. </div>
  126. )}
  127. >
  128. {/* 二级复选框(向下操控三级,向上联动一级) */}
  129. {!!item1[children] && item1[children].map((item2) => (
  130. <div key={item2[id]} className="item">
  131. <Checkbox
  132. name={item2[id]}
  133. checked={item2.checked}
  134. onClick={(e) => {
  135. this.itemHandle(e.target.name, e.target.checked);
  136. }}
  137. >
  138. </Checkbox>
  139. <div className="iname">{item2[name]}</div>
  140. </div>
  141. ))}
  142. </Panel>
  143. ));
  144. return (
  145. <div className="cascaders">
  146. <div
  147. className="cinput"
  148. style={{
  149. height: height,
  150. width: width,
  151. color: checkedList.length > 0 ? "rgba(0, 0, 0, 0.65)" : "rgba(191, 191, 191, 1)"
  152. }}
  153. onClick={this.onSelect}
  154. >{checkedList.length > 0 ? `已选择${checkedList.length}个部门` : placeholder}
  155. </div>
  156. {
  157. visible &&
  158. <div
  159. className="cpop"
  160. style={{
  161. width: width,
  162. }}
  163. >
  164. <div className="clist">
  165. <Collapse expandIconPosition="right">
  166. {authTreeMap}
  167. </Collapse>
  168. </div>
  169. <div className="cboot">
  170. <Button
  171. type="primary"
  172. style={{ marginLeft: 10 }}
  173. onClick={this.onOks}
  174. >确定</Button>
  175. <Button onClick={this.onCancel}>取消</Button>
  176. </div>
  177. </div>
  178. }
  179. </div>
  180. );
  181. }
  182. }
  183. export default Cascaders;