Bumped Material UI version (fixing issues with AutoComplete) (#2790)

Fixed issues with Searchable addresses
This commit is contained in:
Nicolas Gotchac 2016-10-21 17:01:06 +02:00 committed by Jaco Greeff
parent c24f4e87ad
commit dc5dd6b941
4 changed files with 87 additions and 23 deletions

View File

@ -116,7 +116,7 @@
"js-sha3": "^0.5.2", "js-sha3": "^0.5.2",
"lodash": "^4.11.1", "lodash": "^4.11.1",
"marked": "^0.3.6", "marked": "^0.3.6",
"material-ui": "^0.15.4", "material-ui": "^0.16.1",
"material-ui-chip-input": "^0.8.0", "material-ui-chip-input": "^0.8.0",
"moment": "^2.14.1", "moment": "^2.14.1",
"react": "^15.2.1", "react": "^15.2.1",

View File

@ -37,13 +37,14 @@ export default class AddressSelect extends Component {
} }
state = { state = {
entries: {} entries: {},
value: ''
} }
componentWillMount () { componentWillMount () {
const { accounts, contacts } = this.props; const { accounts, contacts, value } = this.props;
const entries = Object.assign({}, accounts || {}, contacts || {}); const entries = Object.assign({}, accounts || {}, contacts || {});
this.setState({ entries }); this.setState({ entries, value });
} }
componentWillReceiveProps (newProps) { componentWillReceiveProps (newProps) {
@ -55,34 +56,36 @@ export default class AddressSelect extends Component {
render () { render () {
const { disabled, error, hint, label } = this.props; const { disabled, error, hint, label } = this.props;
const { entries } = this.state; const { entries } = this.state;
const value = this.getSearchText();
return ( return (
<div className={ styles.container }> <div className={ styles.container }>
<AutoComplete <AutoComplete
className={ error ? '' : styles.paddedInput } className={ (error || !value) ? '' : styles.paddedInput }
disabled={ disabled } disabled={ disabled }
label={ label } label={ label }
hint={ `search for ${hint}` } hint={ hint ? `search for ${hint}` : 'search for an address' }
error={ error } error={ error }
onChange={ this.onChange } onChange={ this.onChange }
value={ this.getSearchText() } value={ value }
filter={ this.handleFilter } filter={ this.handleFilter }
entries={ entries } entries={ entries }
entry={ this.getEntry() || {} }
renderItem={ this.renderItem } renderItem={ this.renderItem }
/> />
{ this.renderIdentityIcon() } { this.renderIdentityIcon(value) }
</div> </div>
); );
} }
renderIdentityIcon () { renderIdentityIcon (inputValue) {
if (this.props.error) { const { error, value } = this.props;
if (error || !inputValue) {
return null; return null;
} }
const { value } = this.props;
return ( return (
<IdentityIcon <IdentityIcon
className={ styles.icon } className={ styles.icon }
@ -125,14 +128,18 @@ export default class AddressSelect extends Component {
} }
getSearchText () { getSearchText () {
const entry = this.getEntry();
if (!entry) return '';
return entry.name ? entry.name.toUpperCase() : '';
}
getEntry () {
const { value } = this.props; const { value } = this.props;
if (!value) return ''; if (!value) return '';
const { entries } = this.state; const { entries } = this.state;
const entry = entries[value]; return entries[value];
if (!entry) return '';
return entry.name ? entry.name.toUpperCase() : '';
} }
handleFilter = (searchText, address) => { handleFilter = (searchText, address) => {
@ -143,8 +150,11 @@ export default class AddressSelect extends Component {
.some(text => text.toLowerCase().indexOf(lowCaseSearch) !== -1); .some(text => text.toLowerCase().indexOf(lowCaseSearch) !== -1);
} }
onChange = (entry) => { onChange = (entry, empty) => {
const address = entry ? entry.address : ''; const address = entry && entry.address
? entry.address
: (empty ? '' : this.state.value);
this.props.onChange(null, address); this.props.onChange(null, address);
} }
} }

View File

@ -16,6 +16,7 @@
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui'; import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui';
import { PopoverAnimationVertical } from 'material-ui/Popover';
export default class AutoComplete extends Component { export default class AutoComplete extends Component {
static propTypes = { static propTypes = {
@ -28,14 +29,22 @@ export default class AutoComplete extends Component {
className: PropTypes.string, className: PropTypes.string,
filter: PropTypes.func, filter: PropTypes.func,
renderItem: PropTypes.func, renderItem: PropTypes.func,
entry: PropTypes.object,
entries: PropTypes.oneOfType([ entries: PropTypes.oneOfType([
PropTypes.array, PropTypes.array,
PropTypes.object PropTypes.object
]) ])
} }
state = {
lastChangedValue: undefined,
entry: null,
open: false
}
render () { render () {
const { disabled, error, hint, label, value, className, filter } = this.props; const { disabled, error, hint, label, value, className, filter } = this.props;
const { open } = this.state;
return ( return (
<MUIAutoComplete <MUIAutoComplete
@ -47,9 +56,13 @@ export default class AutoComplete extends Component {
onNewRequest={ this.onChange } onNewRequest={ this.onChange }
searchText={ value } searchText={ value }
onFocus={ this.onFocus } onFocus={ this.onFocus }
onBlur={ this.onBlur }
animation={ PopoverAnimationVertical }
filter={ filter } filter={ filter }
popoverProps={ { open } }
openOnFocus openOnFocus
menuCloseDelay={ 0 }
fullWidth fullWidth
floatingLabelFixed floatingLabelFixed
dataSource={ this.getDataSource() } dataSource={ this.getDataSource() }
@ -78,18 +91,45 @@ export default class AutoComplete extends Component {
} }
onChange = (item, idx) => { onChange = (item, idx) => {
const { onChange, entries } = this.props; if (idx === -1) {
return;
}
const { entries } = this.props;
const entriesArray = (entries instanceof Array) const entriesArray = (entries instanceof Array)
? entries ? entries
: Object.values(entries); : Object.values(entries);
const entry = (idx === -1) ? null : entriesArray[idx]; const entry = entriesArray[idx];
onChange(entry); this.handleOnChange(entry);
this.setState({ entry, open: false });
}
onBlur = () => {
window.setTimeout(() => {
const { entry } = this.state;
this.handleOnChange(entry);
}, 100);
} }
onFocus = () => { onFocus = () => {
this.props.onChange(null); const { entry } = this.props;
this.setState({ entry, open: true }, () => {
this.handleOnChange(null, true);
});
}
handleOnChange = (value, empty) => {
const { lastChangedValue } = this.state;
if (value !== lastChangedValue) {
this.setState({ lastChangedValue: value });
this.props.onChange(value, empty);
}
} }
} }

View File

@ -44,10 +44,24 @@ class InputAddress extends Component {
componentWillMount () { componentWillMount () {
const { value, text, accountsInfo, tokens } = this.props; const { value, text, accountsInfo, tokens } = this.props;
const account = accountsInfo[value] || tokens[value]; const account = accountsInfo[value] || tokens[value];
const hasAccount = account && !account.meta.deleted; const hasAccount = account && !account.meta.deleted;
const inputValue = text && hasAccount ? account.name : value; const inputValue = text && hasAccount ? account.name : value;
const isEmpty = (inputValue.length === 0); const isEmpty = (!inputValue || inputValue.length === 0);
this.setState({ isEmpty });
}
componentWillReceiveProps (newProps) {
const { value, text } = newProps;
if (value === this.props.value && text === this.props.text) {
return;
}
const inputValue = text || value;
const isEmpty = (!inputValue || inputValue.length === 0);
this.setState({ isEmpty }); this.setState({ isEmpty });
} }