Skip to content

Instantly share code, notes, and snippets.

@JimmySorza
Created January 17, 2019 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JimmySorza/80104c52d1b6314b9e1510b31df1cbef to your computer and use it in GitHub Desktop.
Save JimmySorza/80104c52d1b6314b9e1510b31df1cbef to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import AutoComplete from 'material-ui/AutoComplete';
import FieldTitle from 'admin-on-rest/lib/util/FieldTitle';
import { connect } from 'react-redux';
import { crudGetList as crudGetListAction } from 'admin-on-rest/lib/actions/dataActions';
import _ from 'lodash';
export class AutocompleteRemoteInput extends Component {
static defaultProps = {
addField: true,
fields: [],
filter: AutoComplete.fuzzyFilter,
options: {},
optionText: 'name',
optionValue: 'id'
};
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
const { source, record } = this.props;
const value = _.get(record, source);
this.fetchChoices(value, true);
}
handleUpdateInput = _.debounce(val => {
if (_.isEmpty(val)) {
const { input } = this.props;
input.onChange('');
} else {
this.fetchChoices(val);
}
}, 400);
handleNewRequest = ({ value }, index) => {
const { input } = this.props;
if (index !== -1) {
input.onChange(value);
}
};
fetchChoices = (val, force = false) => {
const { reference, fields } = this.props;
const where = {};
if (!force && _.isEmpty(val)) return;
_.forEach(fields, field => {
_.set(where, field, {
like: `%${val}%`
});
});
this.props.crudGetList(
reference,
{ page: 1, perPage: 10 },
{},
where,
false
);
};
render() {
const {
choices,
elStyle,
filter,
input,
label,
options,
optionText,
optionValue,
source,
meta: { touched, error },
resource
} = this.props;
const selectedSourceFilter = {};
selectedSourceFilter[optionValue] = input.value;
const selectedSource = _.find(choices, selectedSourceFilter);
const option =
typeof optionText === 'function'
? optionText
: choice => choice[optionText];
const dataSource = _.map(choices, choice => ({
value: choice.id,
text: choice.id.toString()
}));
return (
<AutoComplete
listStyle={{ maxHeight: 230, overflow: 'auto' }}
searchText={selectedSource && option(selectedSource)}
dataSource={dataSource}
floatingLabelText={
<FieldTitle label={label} source={source} resource={resource} />
}
filter={filter}
onNewRequest={this.handleNewRequest}
onUpdateInput={this.handleUpdateInput}
openOnFocus
style={elStyle}
errorText={touched && error}
fullWidth
{...options}
/>
);
}
}
AutocompleteRemoteInput.propTypes = {
addField: PropTypes.bool,
reference: PropTypes.string.isRequired,
fields: PropTypes.array,
filter: PropTypes.func,
options: PropTypes.object,
optionText: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
optionValue: PropTypes.string,
source: PropTypes.string.isRequired,
record: PropTypes.object.isRequired,
input: PropTypes.object.isRequired,
crudGetList: PropTypes.func.isRequired,
choices: PropTypes.object.isRequired,
elStyle: PropTypes.object,
label: PropTypes.string.isRequired,
meta: PropTypes.object.isRequired,
resource: PropTypes.string.isRequired
};
function mapStateToProps(state, props) {
return {
choices: _.get(state, `admin.resources.${props.reference}.data`, [])
};
}
AutocompleteRemoteInput.defaultProps = {
elStyle: {}
};
const ConnectedAutocompleteRemoteInput = connect(mapStateToProps, {
crudGetList: crudGetListAction
})(AutocompleteRemoteInput);
ConnectedAutocompleteRemoteInput.defaultProps = {
addField: true
};
export default ConnectedAutocompleteRemoteInput;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment