Make NumberInput more tolerant to errors

This commit is contained in:
Lukas Martinelli 2016-12-30 16:18:53 +01:00
parent 89d497c73f
commit 1d7768e37c
2 changed files with 55 additions and 22 deletions

View file

@ -31,7 +31,7 @@ export default class PropertyGroup extends React.Component {
onPropertyChange(property, newValue) {
const group = getGroupName(this.props.layer.type, property)
this.props.onChange(group , property ,newValue)
this.props.onChange(group , property, newValue)
}
render() {
@ -40,7 +40,7 @@ export default class PropertyGroup extends React.Component {
const paint = this.props.layer.paint || {}
const layout = this.props.layer.layout || {}
const fieldValue = paint[fieldName] || layout[fieldName]
const fieldValue = fieldName in paint ? paint[fieldName] : layout[fieldName]
return <ZoomSpecField
onChange={this.onPropertyChange.bind(this)}

View file

@ -11,38 +11,71 @@ class NumberInput extends React.Component {
onChange: React.PropTypes.func,
}
onChange(e) {
const value = parseFloat(e.target.value)
/*TODO: we can do range validation already here?
if(this.props.min && value < this.props.min) return
if(this.props.max && value > this.props.max) return
*/
constructor(props) {
super(props)
this.state = {
value: props.value
}
}
if(isNaN(value)) {
this.props.onChange(this.props.default)
} else {
componentWillReceiveProps(nextProps) {
this.setState({ value: nextProps.value })
}
changeValue(newValue) {
const value = parseFloat(newValue)
const hasChanged = this.state.value !== value
if(this.isValid(value) && hasChanged) {
this.props.onChange(value)
} else {
this.setState({ value: newValue })
}
}
isValid(v) {
const value = parseFloat(v)
if(isNaN(value)) {
return false
}
if(!isNaN(this.props.min) && value < this.props.min) {
return false
}
if(!isNaN(this.props.max) && value > this.props.max) {
return false
}
return true
}
resetValue() {
// Reset explicitly to default value if value has been cleared
if(this.state.value === "") {
return this.changeValue(this.props.default)
}
// If set value is invalid fall back to the last valid value from props or at last resort the default value
if(!this.isValid(this.state.value)) {
if(this.isValid(this.props.value)) {
this.changeValue(this.props.value)
} else {
this.changeValue(this.props.default)
}
}
}
render() {
let stepSize = null
if(this.props.max && this.props.min) {
stepSize = (this.props.max - this.props.min) / 10
}
return <input
style={{
...input.input,
...this.props.style
}}
type={"number"}
min={this.props.min}
max={this.props.max}
step={stepSize}
placeholder={this.props.default}
value={this.props.value}
onChange={this.onChange.bind(this)}
value={this.state.value}
onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue.bind(this)}
/>
}
}