Reputation: 512
I am trying to implement a react js select element. I am giving a set of options to that element such that the user can select. In addition to that I need to add a place holder to that element and make it able to type values and enter as in a text box. Then the users can either enter custom values to it or select an element from the drop down.
Below is the code snippet I used for implementing the select element. But it only allows selecting. Can anyone help me to implement a select element which allows inputting text and place holder.
<select className="form-control form-control-sm" ref="LayerL6Select" name="LayerL6Select" id="LayerL6Select">
<option value="1">Apple</option>
<option value="2">Mango</option>
</select>
Upvotes: 2
Views: 5717
Reputation: 71
If I am not wrong, You want an a select field that should also take input text which can be searched over the options. If yes, then you can use a library called 'react-select'
There is a property in this component namely 'isSearchable' which is Boolean type.
Below is the component which I have created for my project. You can modify it according to your requirements.
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import ReactSelect, { components } from 'react-select';
import Icon from '../Icon';
import './Select.css';
const MultiValue = props => {
const values = props.selectProps.value;
const lastValue = values[values.length - 1];
let label = props.data.label;
if (lastValue.label !== label) {
label += ', ';
}
return <span>{label}</span>;
};
const Option = props => {
return (
<components.Option {...props}>
<div className="flex items-center">
<div className="h-2 w-2">
{props.isSelected ? (
<Icon name={'checkbox-active'} />
) : (
<Icon name={'checkbox-default'} />
)}
</div>
<label
id={props.data.value}
className="ml-3 mt-1"
>
<span>{props.value}</span>
</label>
</div>
</components.Option>
);
};
const Select = ({
id,
className = '',
closeMenuOnSelect = true,
hideSelectedOptions = false,
isClearable = true,
isDisabled = false,
isMulti = false,
isSearchable = true,
onChange,
options,
placeholder,
noIcons = false,
menuPlacement = 'auto',
components = {},
value = [],
}) => {
const _noIconComponents = {
DropdownIndicator: () => null,
IndicatorSeparator: () => null,
};
let _components = isMulti ? { Option, MultiValue } : {};
_components = noIcons
? { ..._components, ..._noIconComponents }
: { ..._components, ...components };
const selectedOptions = [];
// Map array of values to an array of selected options
if (value && Array.isArray(value)) {
value.forEach(val => {
const found = options.find(opt => opt.value === val);
if (found) {
selectedOptions.push(JSON.parse(JSON.stringify(found)));
}
});
}
return (
<ReactSelect
inputId={`input-${id}`}
className={classnames(className, 'ohif-select customSelect__wrapper flex flex-1 flex-col')}
data-cy={`input-${id}`}
classNamePrefix="customSelect"
isDisabled={isDisabled}
isClearable={isClearable}
isMulti={isMulti}
isSearchable={isSearchable}
menuPlacement={menuPlacement}
closeMenuOnSelect={closeMenuOnSelect}
hideSelectedOptions={hideSelectedOptions}
components={_components}
placeholder={placeholder}
options={options}
blurInputOnSelect={true}
menuPortalTarget={document.body}
styles={{
menuPortal: base => ({ ...base, zIndex: 9999 }),
}}
value={value && Array.isArray(value) ? selectedOptions : value}
onChange={(selectedOptions, { action }) => {
const newSelection = !selectedOptions.length
? selectedOptions
: selectedOptions.reduce((acc, curr) => acc.concat([curr.value]), []);
onChange(newSelection, action);
}}
/>
);
};
Select.propTypes = {
className: PropTypes.string,
closeMenuOnSelect: PropTypes.bool,
hideSelectedOptions: PropTypes.bool,
isClearable: PropTypes.bool,
isDisabled: PropTypes.bool,
isMulti: PropTypes.bool,
isSearchable: PropTypes.bool,
noIcons: PropTypes.bool,
menuPlacement: PropTypes.oneOf(['auto', 'bottom', 'top']),
onChange: PropTypes.func.isRequired,
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string,
label: PropTypes.string,
})
),
placeholder: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.any]),
};
export default Select;
Upvotes: 0
Reputation: 36594
You should use <input>
followed by <datalist>
.Here is example in html you can convert in into react.
Note that id
attribute of <datalist>
should be added list
attribute of the <input>
According to DOCS
The
datalist
element is hooked up to aninput
element using thelist
attribute on the input element
<input placeholder="myplaceholder" list="opts"/>
<datalist id="opts">
<option>One</option>
<option>Two</option>
<option>Three</option>
</datalist>
Upvotes: 5
Reputation: 865
If you looking for short time solution. I would suggest following react-select library which helps you to achieve what you want.
else if you ask this for your personal learning here its source code, you could learn from it source code.
https://github.com/JedWatson/react-select
Upvotes: 2