UNPKG

3.7 kBJavaScriptView Raw
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import classnames from 'classnames';
4
5const propTypes = {
6 placeholder:PropTypes.string,
7 options:PropTypes.any,
8 onClick:PropTypes.func
9};
10const defaultProps = {
11 placeholder:'请输入信息',
12 options:null
13};
14let tem = [];//用于临时存储点击的节点
15let textStr=[];//存储选择的节点
16let parentVal ;//存储parent的value
17let listArr = [];
18let restoreClick;//记录点击的名字
19class Cascader extends Component {
20 constructor(props) {
21 super(props);
22 let options = this.props.options;
23 for (let i = options.length - 1; i >= 0; i--) {
24 options[i]['parent'] = true
25 }
26 this.state = {
27 option : options,
28 origin:null,//用于存储点击的第一级节点
29 ulArr:null,
30 textStr:[]
31 }
32 this.formatData = this.formatData.bind(this);
33 this.clickHandler = this.clickHandler.bind(this);
34 this.focusHandler = this.focusHandler.bind(this);
35 this.clear = this.clear.bind(this);
36 this.uniqueID = this.uniqueID.bind(this);
37 }
38 uniqueID() {
39 function s4(){
40 return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
41 }
42 return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
43 s4() + '-' + s4() + s4() + s4();
44 }
45 formatData(data = this.state.option){
46 let option = data;
47 let liArr = [],
48 ulArr = [];
49 for (let i = option.length - 1; i >= 0; i--) {
50 if('children' in option[i]){
51 liArr.push(<li data-parent = {option[i]['parent']} onClick = {this.clickHandler} key={this.uniqueID()} data-id = {i}>{option[i]['value']}<i className="icon uf">&#xe611;</i></li>)
52 }else{
53 liArr.push(<li data-parent = {option[i]['parent']} onClick = {this.clickHandler} key={this.uniqueID()} data-id = {i}>{option[i]['value']}</li>)
54 }
55 }
56 let ulStr = (
57 <ul key={this.uniqueID()}>
58 {liArr}
59 </ul>
60 );
61 listArr.push(ulStr);
62 this.setState({
63 ulArr : listArr
64 });
65 }
66 focusHandler(e){
67 e.stopPropagation();
68 e.preventDefault();
69 textStr = [];
70
71 if(this.state.ulArr){
72 let firstUl = this.state.ulArr[0];
73 listArr = [];
74 listArr.push(firstUl)
75 this.setState({
76 ulArr : listArr
77 });
78 }
79 tem = [];
80 listArr = [];
81 this.setState({
82 textStr:textStr
83 })
84 if(!this.state.ulArr){
85 this.formatData();
86 }
87 }
88 clickHandler(e){
89 e.stopPropagation();
90 e.preventDefault();
91 let i = e.currentTarget.dataset.id;
92 if(!parentVal)parentVal = this.state.option[i].value;
93 let data = (tem[i])||(this.state.option[i].parent&&this.state.option[i]);
94 if(e.currentTarget.dataset.parent){
95 parentVal = e.currentTarget.innerText;
96 let urlArr = this.state.ulArr[0];
97 data = this.state.option[i];
98 textStr = [];
99 tem = [];
100 listArr = [];
101 listArr.push(urlArr)
102 this.setState({
103 ulArr : listArr
104 });
105 }
106 if(restoreClick!=e.currentTarget.innerText){
107 restoreClick = e.currentTarget.innerText;
108 textStr.push(data.value);
109 this.setState({
110 textStr:textStr
111 })
112 if(data.children){
113 tem = data.children;
114 this.formatData(data.children);
115 }else{
116 this.clear();
117 }
118 }
119 if(this.props.onClick){
120 this.props.onClick(textStr);
121 }
122 }
123 clear(){
124 tem = [];
125 listArr = [];
126 this.setState({
127 ulArr:null
128 })
129 }
130 render(){
131 let va = this.state.textStr.join('/');
132 return(
133 <div className={classnames("cascader-container",this.props.className)}>
134 <div className="cascader-header">
135 <input onFocus = {this.focusHandler} type="text" placeholder = {this.props.placeholder} value={va} />
136 </div>
137 <div className="cascader-content" >
138 {this.state.ulArr}
139 </div>
140 </div>
141 )
142 }
143};
144Cascader.propTypes = propTypes;
145Cascader.defaultProps = defaultProps;
146export default Cascader;