Created
February 9, 2018 07:36
-
-
Save igrek8/a233d3fda10b11b9c60e9847134a58c0 to your computer and use it in GitHub Desktop.
Simple implementation of AutoComplete & Select in Material UI with Redux Form
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { Field, reduxForm } from 'redux-form'; | |
import { AutoComplete, FlatButton } from 'material-ui'; | |
// Component | |
const mapError = ( | |
{ | |
meta: { touched, error, warning } = {}, | |
input, | |
...props | |
}, | |
errorProp = 'errorText', | |
) => | |
(touched && (error || warning) | |
? { | |
...props, | |
...input, | |
[errorProp]: error || warning, | |
} | |
: { ...input, ...props }); | |
class SelectAutoComplete extends React.Component { | |
constructor(props) { | |
super(props); | |
const searchText = props.input.value; | |
this.state = { searchText }; | |
} | |
onUpdateInput = (searchText) => { | |
const { input } = this.props; | |
const { onChange } = input; | |
this.setState({ searchText }, () => { | |
onChange(this.getSelectedIndex()); | |
}); | |
} | |
getSelectedIndex = () => { | |
const { dataSource, dataSourceConfig, filter } = this.props; | |
const searchText = this.state.searchText; | |
const selectedIndex = dataSource.findIndex((item, index) => { | |
switch (typeof item) { | |
case 'string': | |
return searchText === item; | |
case 'object': | |
if (item && typeof item[dataSourceConfig.text] === 'string') { | |
const itemText = item[dataSourceConfig.text]; | |
return searchText === itemText; | |
} | |
break; | |
default: // Do nothing | |
} | |
return false; | |
}); | |
return selectedIndex; | |
} | |
render() { | |
const { input, onUpdateInput } = this.props; | |
const { onChange, onBlur } = input; | |
return ( | |
<AutoComplete | |
{ ...mapError(this.props) } | |
searchText={ this.state.searchText } | |
onNewRequest={ (value, index) => onChange(index) } | |
onBlur={ () => onBlur(this.getSelectedIndex()) } | |
onChange={ this.onUpdateInput } | |
onUpdateInput={ (searchText) => { | |
this.onUpdateInput(searchText); | |
if (onUpdateInput) { | |
onUpdateInput(searchText); | |
} | |
} } | |
/> | |
); | |
} | |
} | |
// Real example | |
const mapFetchedItemsToAutoComplete = { | |
value: 'id', text: 'name', | |
}; | |
const UIForm = props => ( | |
<form | |
onSubmit={ props.handleSubmit } | |
> | |
<Field | |
name="field1" | |
component={ SelectAutoComplete } | |
dataSourceConfig={ mapFetchedItemsToAutoComplete } | |
dataSource={ props.dataSource } | |
openOnFocus | |
filter={ AutoComplete.fuzzyFilter } | |
/> | |
<FlatButton | |
primary | |
label="Submit" | |
type="submit" | |
style={ { marginLeft: 15 } } | |
/> | |
</form> | |
); | |
const formValidator = (values) => { | |
const errors = {}; | |
if (typeof values.field1 === 'undefined' || values.field1 === -1) { | |
errors.field1 = 'None of the items has been selected'; | |
} | |
return errors; | |
}; | |
const Form = reduxForm({ | |
form: 'form1', | |
validate: formValidator, | |
})(UIForm); | |
class Application extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
dataSource: [ | |
{ id: 1, name: 'Solution' }, | |
{ id: 2, name: 'Problem' }, | |
{ id: 3, name: 'Fix' }, | |
], | |
}; | |
} | |
componentWillMount() { | |
const interval = setInterval(() => { | |
if (this.state.dataSource.length > 10) { | |
clearInterval(interval); | |
return; | |
} | |
const id = this.state.dataSource.length + 1; | |
this.setState({ | |
dataSource: [ | |
...this.state.dataSource, | |
{ id, name: `Solution ${id}` }, | |
], | |
}); | |
}, 1000); | |
setTimeout(() => { | |
this.setState({ | |
dataSource: this.state.dataSource.filter(e => e.name !== 'Fix'), | |
}); | |
}, 3000); | |
} | |
render() { | |
return ( | |
<Form | |
dataSource={ this.state.dataSource.sort((a, b) => a.name > b.name) } | |
onSubmit={ (values) => alert(JSON.stringify(values, null, 2)) } | |
/> | |
); | |
} | |
} | |
export default () => ( | |
<Application /> | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment