Skip to content
This repository was archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
Add defaultText for text placehold
Browse files Browse the repository at this point in the history
  • Loading branch information
kunyan committed Mar 9, 2017
1 parent bb1f8b1 commit a7e1b9d
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 83 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const options = [
| select2| :thought_balloon: |   |

## TypeScript:
Comming soon.
d.ts already intergrated. just import it.

## Known Issues:

Expand Down
18 changes: 18 additions & 0 deletions config/webpack.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ module.exports = webpackMerge(commonConfig, {
library: 'ReactBootstrapXEditable',
libraryTarget: 'umd',
},
externals: [
{
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react',
},
},
{
'react-dom': {
root: 'ReactDOM',
commonjs2: 'react-dom',
commonjs: 'react-dom',
amd: 'react-dom',
},
},
],
plugins: [
new webpack.DefinePlugin({
'process.env': {
Expand Down
8 changes: 5 additions & 3 deletions d.ts/EditableSelect.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import React from 'react';
// <EditableSelect />
// ----------------------------------------
export interface EditableSelectProps extends React.Props<EditableSelectClass> {
name: string;
id?: string;
name?: string;
value?: string;
options: Array<any>;
className?: string;
options?: Array<any>;
onUpdate: Function;
defaultOptionText?: string;
defaultText?: any;
}
export interface EditableSelect extends React.ReactElement<EditableSelectProps> { }
export interface EditableSelectClass extends React.ComponentClass<EditableSelectProps> { }
Expand Down
7 changes: 6 additions & 1 deletion d.ts/EditableTextArea.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import React from 'react';
// <EditableTextArea />
// ----------------------------------------
export interface EditableTextAreaProps extends React.Props<EditableTextAreaClass> {
name: string;
id?: string;
name?: string;
value?: string;
className?: string;
rows: number,
cols: number,
placeholder?: string;
onUpdate: Function;
defaultText?: any;
}
export interface EditableTextArea extends React.ReactElement<EditableTextAreaProps> { }
export interface EditableTextAreaClass extends React.ComponentClass<EditableTextAreaProps> { }
Expand Down
5 changes: 4 additions & 1 deletion d.ts/EditableTextField.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import React from 'react';
// <EditableTextField />
// ----------------------------------------
export interface EditableTextFieldProps extends React.Props<EditableTextFieldClass> {
name: string;
id?: string;
name?: string;
value?: string;
className?: string;
placeholder?: string;
onUpdate: Function;
defaultText?: any;
}
export interface EditableTextField extends React.ReactElement<EditableTextFieldProps> { }
export interface EditableTextFieldClass extends React.ComponentClass<EditableTextFieldProps> { }
Expand Down
54 changes: 37 additions & 17 deletions example/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const XSelect = class XSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'UK'
value: null,
};
this.setState = this.setState.bind(this);
}
Expand All @@ -32,26 +32,44 @@ const XSelect = class XSelect extends React.Component {
alert('Value Changed:' + value);
}
render() {
// const options = [
// {
// text: 'China',
// value: 'CN'
// }, {
// text: 'India',
// value: 'IN'
// }, {
// text: 'United Kingdom (UK)',
// value: 'UK'
// }, {
// text: 'United States of America (USA)',
// value: 'USA'
// }
// ];
const options2 = [
'Hello', 'World', 'Sky', 'Air',
// 'UK',
];
return (<EditableSelect name='country' onUpdate={this.handleUpdate} value={this.state.value} options={options2} defaultOptionText='Not select'/>);
return (<EditableSelect name='country' onUpdate={this.handleUpdate} value={this.state.value} options={options2}/>);
}
};

const XSelect2 = class XSelect extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
this.setState = this.setState.bind(this);
}
handleUpdate = (name, value) => {
this.setState({value: value});
alert('Value Changed:' + value);
}
render() {
const options = [
{
text: 'China',
value: 'CN'
}, {
text: 'India',
value: 'IN'
}, {
text: 'United Kingdom (UK)',
value: 'UK'
}, {
text: 'United States of America (USA)',
value: 'USA'
}
];
const defaultText = <span className="glyphicon glyphicon-pencil"/>;
return (<EditableSelect name='country' onUpdate={this.handleUpdate} value={this.state.value} options={options} defaultText={defaultText}/>);
}
};

Expand All @@ -74,5 +92,7 @@ ReactDOM.render(
<XTextField/>, document.getElementById('demo-textfield'));
ReactDOM.render(
<XSelect/>, document.getElementById('demo-select'));
ReactDOM.render(
<XSelect2/>, document.getElementById('demo-select-custom'));
ReactDOM.render(
<XTextArea/>, document.getElementById('demo-textarea'));
6 changes: 5 additions & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ <h1>React-xeditable Demo</h1>
<td width="65%" id='demo-textfield'></td>
</tr>
<tr>
<td width="35%">Select, local array, custom display</td>
<td width="35%">Select, local array</td>
<td width="65%" id='demo-select'></td>
</tr>
<tr>
<td width="35%">Select, local array, custom display</td>
<td width="65%" id='demo-select-custom'></td>
</tr>
<tr>
<td width="35%">Textarea</td>
<td width="65%" id='demo-textarea'></td>
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"build:es": "./node_modules/.bin/rimraf es && ./node_modules/.bin/cross-env BABEL_ENV=es ./node_modules/.bin/babel src --out-dir es",
"build:umd": "./node_modules/.bin/rimraf dist && ./node_modules/.bin/cross-env BABEL_ENV=commonjs ./node_modules/.bin/webpack --config config/webpack.prod.js --progress --profile --bail",
"build": "npm run build:commonjs && npm run build:es && npm run build:umd",
"test": "./node_modules/.bin/ava -v"
"test": "./node_modules/.bin/ava -v",
"prepublish": "npm run test && npm run build"
},
"files": [
"dist",
Expand Down
70 changes: 37 additions & 33 deletions src/EditableSelect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,87 @@ import React from 'react';
import XEditable from './XEditable';

export default class EditableSelect extends React.Component {
static defaultProps = {
name: null
}
static propTypes = {
name: React.PropTypes.string.isRequired,
id: React.PropTypes.string,
name: React.PropTypes.string,
className: React.PropTypes.string,
value: React.PropTypes.node,
onUpdate: React.PropTypes.func.isRequired,
options: React.PropTypes.array.isRequired,
defaultOptionText: React.PropTypes.string
options: React.PropTypes.array,
defaultText: React.PropTypes.node,
}

constructor(props) {
super(props);
this.setState = this.setState.bind(this);

const options = this.convertOptions(this.props.options);
if (this.props.defaultOptionText) {
options.unshift({text: this.props.defaultOptionText, value: null});
}
const selected = options.find((opt) => {
this.state = {
isEditing: false,
value: this.props.value,
defaultText: this.props.defaultText || 'not selected',
};

this.state.options = this.convertOptions(this.props.options);

const selected = this.state.options && this.state.options.find((opt) => {
if (opt.value === this.props.value) {
return opt;
}
});

let text = 'Invalid value';

if (selected) {
text = selected.text;
} else if (this.props.defaultOptionText) {
text = this.props.defaultOptionText;
}
this.state = {
isEditing: false,
options: options,
text: text,
value: this.props.value
};
this.setLinkText(selected && selected.text);

}

save = (event) => {
event.preventDefault();
this.props.onUpdate(this.props.name, this.refs.el.value);
this.props.onUpdate(this.refs.el.name, this.refs.el.value);
const text = this.refs.el.options && this.refs.el.options[this.refs.el.selectedIndex] && this.refs.el.options[this.refs.el.selectedIndex].text;
this.setState({
isEditing: false,
text: this.refs.el.options[this.refs.el.selectedIndex].text,
value: this.refs.el.value
});
this.setLinkText(text);
}
cancel = () => {
this.setState({isEditing: false});
}
handleLinkClick = () => {
this.setState({isEditing: true});
}

setLinkText(text) {
this.state.text = text;
this.state.textStyle = {
color: !text && !this.props.defaultText
? 'gray'
: null
};
}
convertOptions = (options) => {
if (!options) {
return null;
}
return options.map((opt) => {
if (typeof opt === 'string' || typeof opt === 'number' || typeof opt === 'boolean') {
return {text: opt, value: opt};
}
return {text: opt.text, value: opt.value};
});
}

render() {
if (this.state.isEditing) {
const options = this.state.options.map((opt, index) => {
return <option key={index} value={opt.value}>{opt.text}</option>;
const options = this.state.options && this.state.options.map((opt, i) => {
return <option key={i} value={opt.value}>{opt.text}</option>;
});
const selectClassName = `form-control input-sm ${this.props.className}`;
return (
<XEditable isLoading={false} save={this.save} cancel={this.cancel}>
<select ref='el' className='form-control input-sm' name={this.props.name} defaultValue={this.state.value}>
<select ref='el' className={selectClassName} id={this.props.id} name={this.props.name} defaultValue={this.state.value}>
{options}
</select>
</XEditable>
);
} else {
return <a href='javascript:;' className='editable editable-click' onClick={this.handleLinkClick}>{this.state.text}</a>;
return <a href='javascript:;' className='editable editable-click' style={this.state.textStyle} onClick={this.handleLinkClick}>{this.state.text || this.state.defaultText }</a>;
}
}
}
35 changes: 22 additions & 13 deletions src/EditableTextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@ import React from 'react';
import XEditable from './XEditable';

export default class EditableTextArea extends React.Component {
static defaultProps = {
name: null,
value: '',
placeholder: ''
};
static propTypes = {
name: React.PropTypes.string.isRequired,
value: React.PropTypes.string,
id: React.PropTypes.string,
name: React.PropTypes.string,
className: React.PropTypes.string,
value: React.PropTypes.node,
rows: React.PropTypes.number,
cols: React.PropTypes.number,
placeholder: React.PropTypes.string,
onUpdate: React.PropTypes.func.isRequired
onUpdate: React.PropTypes.func.isRequired,
defaultText: React.PropTypes.node
};
constructor(props) {
super(props);
this.state = {
isEditing: false
isEditing: false,
value: this.props.value,
defaultText: this.props.defaultText || 'Empty',
};
this.setState = this.setState.bind(this);
}
save = (event) => {
event.preventDefault();
this.props.onUpdate(this.props.name, this.refs.el.value);
this.setState({isEditing: false});
this.setState({isEditing: false, value: this.refs.el.value});
}
cancel = () => {
this.setState({isEditing: false});
Expand All @@ -36,14 +38,21 @@ export default class EditableTextArea extends React.Component {
}
render() {
if (this.state.isEditing) {
const textareaClassName = `form-control ${this.props.className}`;
return (
<XEditable isLoading={false} save={this.save} cancel={this.cancel}>
<textarea ref='el' className='form-control' rows='3' name={this.props.name} defaultValue={this.props.value} placeholder={this.props.placeholder}/>
<textarea ref='el' id={this.props.id} className={textareaClassName} rows={this.props.rows} cols={this.props.cols} name={this.props.name} defaultValue={this.props.value} placeholder={this.props.placeholder}/>
</XEditable>
);
} else {
return <a href='javascript:;' className='editable editable-click' onClick={this.handleLinkClick}>
<pre>{this.props.value}</pre>
let aClassName = 'editable editable-click';
let content = <pre>{this.state.value}</pre>;
if (!this.state.value) {
aClassName += ' editable-empty';
content = this.state.defaultText;
}
return <a href='javascript:;' className={aClassName} style={this.state.textStyle} onClick={this.handleLinkClick}>
{content}
</a>;
}
}
Expand Down
Loading

0 comments on commit a7e1b9d

Please sign in to comment.