Skip to content

Instantly share code, notes, and snippets.

@kaleem-elahi
Created August 21, 2018 07:24
Show Gist options
  • Save kaleem-elahi/fbdbe05a0aff42fe01b22d0bfe00ab12 to your computer and use it in GitHub Desktop.
Save kaleem-elahi/fbdbe05a0aff42fe01b22d0bfe00ab12 to your computer and use it in GitHub Desktop.
Logic on react-select for material-ui redux-form field. Supports for Async, Async-Creatable, Creatable & Normal one with single as well as milti-select
import React from 'react';
import Select from 'react-select';
import PropTypes from 'prop-types';
import 'react-select/dist/react-select.css';
import BASE_URL from '../../constants';
const SelectType = (type, props, asyncProps) => {
const {
searchKey,
getOptions,
options,
apiUrl,
} = props;
switch (type) {
case 'Async':
return (
<Select.Async
{...props}
{...asyncProps}
onBlurResetsInput={false}
loadOptions={getOptions.bind(null, `${BASE_URL}${apiUrl}`, searchKey)} // eslint-disable-line
/>
);
case 'AsyncCreatable':
return (
<Select.AsyncCreatable
{...props}
{...asyncProps}
onBlurResetsInput={false}
loadOptions={getOptions.bind(null, `${BASE_URL}${apiUrl}`, searchKey)} // eslint-disable-line
/>
);
case 'Creatable':
return (
<Select.Creatable
{...props}
{...asyncProps}
onBlurResetsInput={false}
/>
);
default:
return (
<Select
{...props}
{...asyncProps}
options={options}
onBlurResetsInput={false}
/>
);
}
};
SelectType.propTypes = {
apiUrl: PropTypes.string,
options: PropTypes.arrayOf(PropTypes.object),
getOptions: PropTypes.func,
apiParams: PropTypes.string,
searchKey: PropTypes.string,
};
SelectType.defaultProps = {
apiUrl: '',
options: [],
getOptions: () => { },
apiParams: '',
searchKey: '',
};
const MultiSelect = (props) => {
const {
type,
input,
meta,
} = props;
const { error, touched } = meta;
// console.log('=>', input.value, props.multi);
const asyncProps = {
multi: props.multi,
valueKey: props.valueKey,
labelKey: props.labelKey,
value: props.multi ? input.value && input.value.length > 0 // eslint-disable-line
? typeof input.value[0] === 'string'
? input.value.map(val => ({ value: val }))
: input.value
: [] : input.value,
onBlur: () => input.onBlur(input.value),
onChange: (values) => {
if (input.onChange && values) {
input.onChange(values);
} else {
input.onChange(null);
}
return values;
},
};
return (
<div>
<div className={`select-wrapper ${touched && error ? 'select-wrapper-error' : ''}`}>
{SelectType(type, props, asyncProps)}
</div>
{
touched && error &&
<p className="error">{error}</p>
}
</div>
);
};
MultiSelect.propTypes = {
input: PropTypes.object.isRequired, // eslint-disable-line
meta: PropTypes.object.isRequired, // eslint-disable-line
type: PropTypes.oneOf(['Async', 'AsyncCreatable', 'Creatable', '']),
valueKey: PropTypes.string,
labelKey: PropTypes.labelKey,
multi: PropTypes.bool,
};
MultiSelect.defaultProps = {
multi: true,
type: '',
valueKey: 'value',
labelKey: 'value',
};
export default MultiSelect;
@kaleem-elahi
Copy link
Author

For multi-select just use:
multi={true}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment