forked from kaivi/ReactInlineEdit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.jsx
100 lines (87 loc) · 3.31 KB
/
index.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import React from 'react';
import ReactDOM from 'react-dom';
function SelectInputText(element) {
element.setSelectionRange(0, element.value.length);
}
class InlineEdit extends React.Component {
constructor(props) {
super(props);
this.startEditing = this.startEditing.bind(this);
this.finishEditing = this.finishEditing.bind(this);
this.textChanged = this.textChanged.bind(this);
this.isInputValid = this.isInputValid.bind(this);
this.componentDidUpdate = this.componentDidUpdate.bind(this);
this.commitEditing = this.commitEditing.bind(this);
this.keyDown = this.keyDown.bind(this);
this.state = {
editing: false,
text: this.props.text,
minLength: this.props.minLength || 1,
maxLength: this.props.maxLength || 256
};
this.isInputValid = this.props.validate || this.isInputValid.bind(this);
}
startEditing() {
this.setState({editing: true, text: this.props.text});
}
finishEditing() {
if(this.isInputValid(this.state.text) && this.props.text != this.state.text){
this.commitEditing();
} else if (this.props.text === this.state.text || !this.isInputValid(this.state.text)) {
this.cancelEditing();
}
}
cancelEditing() {
this.setState({editing: false, text: this.props.text});
}
commitEditing() {
this.setState({editing: false, text: this.state.text});
let newProp = {};
newProp[this.props.paramName] = this.state.text;
this.props.change(newProp);
}
isInputValid(text) {
return (text.length >= this.state.minLength && text.length <= this.state.maxLength);
}
keyDown(event) {
if(event.keyCode === 13) {
this.finishEditing();
} else if (event.keyCode === 27) {
this.cancelEditing();
}
}
textChanged(event) {
this.setState({
text: event.target.value.trim()
})
}
componentDidUpdate(prevProps, prevState) {
var inputElem = ReactDOM.findDOMNode(this.refs.input);
if (this.state.editing && !prevState.editing) {
inputElem.focus();
SelectInputText(inputElem);
} else if (this.state.editing && prevProps.text != this.props.text) {
this.finishEditing();
}
}
render() {
if(!this.state.editing) {
return <span className={this.props.className} onClick={this.startEditing}>{this.state.text || this.props.placeholder}</span>
} else {
const Element = this.props.element || 'input';
return <Element className={this.props.activeClassName} onKeyDown={this.keyDown} onBlur={this.finishEditing} ref="input" placeholder={this.props.placeholder} defaultValue={this.state.text} onChange={this.textChanged} onReturn={this.finishEditing} />
}
}
}
InlineEdit.propTypes = {
text: React.PropTypes.string.isRequired,
paramName: React.PropTypes.string.isRequired,
change: React.PropTypes.func.isRequired,
placeholder: React.PropTypes.string,
activeClassName: React.PropTypes.string,
minLength: React.PropTypes.number,
maxLength: React.PropTypes.number,
validate: React.PropTypes.func,
element: React.PropTypes.string
};
export default InlineEdit;