1 | import React, { Component } from 'react';
|
2 | import PropTypes from 'prop-types';
|
3 | import classnames from 'classnames';
|
4 |
|
5 | const propTypes = {
|
6 | placeholder:PropTypes.string,
|
7 | options:PropTypes.any,
|
8 | onClick:PropTypes.func
|
9 | };
|
10 | const defaultProps = {
|
11 | placeholder:'请输入信息',
|
12 | options:null
|
13 | };
|
14 | let tem = [];
|
15 | let textStr=[];
|
16 | let parentVal ;
|
17 | let listArr = [];
|
18 | let restoreClick;
|
19 | class 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"></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 | };
|
144 | Cascader.propTypes = propTypes;
|
145 | Cascader.defaultProps = defaultProps;
|
146 | export default Cascader;
|