How to use Multi-Select Dropdown in react-bootstrap - reactjs

I am using react-bootstrap library. This library having a module called DropdownButton. So i am able to display data in dropdown. This is single selection data.
<DropdownButton
bsStyle="success"
title={this.state.addLeadStageSelectTitle}
key={"addleadstageDropDown"}
id={"addleadstageIDAdd"}
onSelect={this.handleSelectLeadStageAdd}
>
{this.state.vtx_sales_lead_status.map(objs => {
return (
<MenuItem eventKey={objs.id}>{objs.name}</MenuItem>
)
}
)}
</DropdownButton>
But I am trying to create it multiselect with same library.

Here is a multi-select example using hooks and react-bootstrap.
import React, { useState } from "react";
import { Col, Form } from "react-bootstrap";
export default function App() {
const [field, setField] = useState([]);
return (
<Form.Group as={Col} controlId="my_multiselect_field">
<Form.Label>My multiselect</Form.Label>
<Form.Control as="select" multiple value={field} onChange={e => setField([].slice.call(e.target.selectedOptions).map(item => item.value))}>
<option value="field1">Field 1</option>
<option value="field2">Field 2</option>
<option value="field3">Field 3</option>
</Form.Control>
</Form.Group>
);
}

I've checked the react-bootstrap documentation and it looks like there isn't a multiselect functionality.
So you can use a third party library, like: react-bootstrap-multiselect.
It's a Multiselect component for React (with Bootstrap). This is a React wrapper around an existing jQuery / Bootstrap library: bootstrap-multiselect
Basic usage:
import Multiselect from 'react-bootstrap-multiselect'
const data = [{ value:'One', selected:true }, { value: 'Two' }, { value:'Three' }]
const App = props => {
return <Multiselect onChange={props.handleChange} data={data} multiple />
}
Demo.

It is supported now:
import { Form } from 'react-bootstrap';
// [...]
<Form>
<Form.Control as="select" multiple value={options} onChange={onSelectedOptionsChange}>
{options.map(options => (
<option key={option.name} value={option.value}>
{option.name}
</option>
))}
</Form.Control>
</Form>

Related

Search only with text ignoring emoji in antd Select component

I have select component of antd where option label is not text. Option label has text along with emoji. Now If user want to search for particular text, the select component is not able to search the text which has emojis.
What I want to have is User should search a particular text ignoring the emoji.
import React from 'react';
import 'antd/dist/antd.css';
import './index.css';
import { Select } from 'antd';
const { Option } = Select;
const App = () => (
<Select
showSearch
style={{
width: 200,
}}
placeholder="Search to Select"
optionFilterProp="children"
filterOption={(input, option) => option.children.includes(input)}
>
<Option value="1"><span>😁</span> Not Identified</Option>
<Option value="2"><span>🙄</span> Closed</Option>
<Option value="3"><span>😪</span> Communicated</Option>
<Option value="4"><span>😚</span> Identified</Option>
<Option value="5"><span>🥱</span> Resolved</Option>
<Option value="6"><span>😫</span> Cancelled</Option>
</Select>
);
export default App;
If need, I have a codesandbox link.
here just use toLowerCase() string function it's work i just updated pls check here codesandbox link
import React from "react";
import "antd/dist/antd.css";
import "./index.css";
import { Select } from "antd";
const { Option } = Select;
const onHandleSearch = (input, option) => {
let optionChildren = option.children.filter(
(item) => typeof item === "string"
);
return optionChildren[0].toLowerCase().includes(input.toLowerCase());
};
const App = () => (
<Select
showSearch
style={{
width: 200
}}
placeholder="Search to Select"
optionFilterProp="children"
filterOption={(input, option) => onHandleSearch(input, option)}
>
<Option value="1">
<span>😁</span> Not Identified
</Option>
<Option value="2">
<span>🙄</span> Closed
</Option>
<Option value="3">
<span>😪</span> Communicated
</Option>
<Option value="4">
<span>😚</span> Identified
</Option>
<Option value="5">
<span>🥱</span> Resolved
</Option>
<Option value="6">
<span>😫</span> Cancelled
</Option>
</Select>
);
export default App;

Add search to Select React Bootstrap React JS

i'm working with react-bootstrap to create a select list, by default there is a search in list but by just the first caracter. there is a way to add search in my select like the select from react-select. any help please ?
facture.js
import Select from '../retour/bloc/select';
export default function Facture() {
return (
<Select
label="Bordereaux"
name="Bordereaux"
changed={selectPick}
options={listBordereaux ? listBordereaux : []}
onClick={toggleOpen}
search
/>)}
Select.js
import React, { Component } from 'react';
import { Form, Row, Col } from 'react-bootstrap';
import PropTypes from 'prop-types';
import '../retour.css'
export default class Select extends Component {
render() {
let { label, name, value, changed, options } = this.props;
return (
<Form.Group as={Row}>
<Form.Label column lg={4} sm={10} className=""> {label} : </Form.Label>
<Col lg={6} sm={10}>
<Form.Control
name={name}
// size="sm"
as="select"
className="retour-select"
value={value}
onChange={(event) => changed(event, name)}
>
<option value="" hidden> {label} </option>
{label === "Bordereaux" ?
options.map(el =>
<option key={el.id} value={el.ref}>
}
</Form.Control>
</Col>
</Form.Group>
);
}
}
Select.propTypes = {
label: PropTypes.string,
};

React - Ant Design Form-Item name props broke Select value

I m using antD and if I use select component inside of form item and if this form item has name as props I can not set value to my select component while page was rendering.
Just make it clear what I tried to say, I prepared a example and you can copy and paste it to the codesandbox or etc.
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, Button, Select } from 'antd';
const { Option } = Select;
export const Demo =()=> {
let formRef = React.createRef();
return (
<Form ref={formRef} name="control-ref">
<Form.Item
label="Gender"
rules={[
{
required: true,
},
]}
>
<Select value="male">
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
</Form>
);
}
ReactDOM.render(<Demo />, document.getElementById('container'));
If you try to give name props to form item in this example your select component's initial value will not
be set.
More over using hooks not solved my problem.
I do not fully understand your question, but as far as I do, I'll try to help.
You can try useRef.
import React,{useRef, useEffect} from 'react';
export const Demo =()=> {
var formRef = useRef();
useEffect(() => {
formRef.current.setFieldsValue({
select:"male"
})
});
<Form ref={formRef} name="control-ref">
<Form.Item
label="Gender"
name="select"
rules={[
{
required: true,
},
]}
>
<Select>
<Option value="male">male</Option>
<Option value="female">female</Option>
<Option value="other">other</Option>
</Select>
</Form.Item>
</Form>
);}
Do not forget to give the name of the relevant Form.Item.

React | Select Amount

I have a Dialog where the user is able to create a new Tour. I want to add a Select option to choose the amount of Tours being created. Currently the component is not rerendering onChange and the amount is not being saved. I would really appreciate help :)
My Code looks like this :
const [selectedOption, setSelectedOption] = useState({amount:''});
const handleSelectChange = (event) => {
const amount = event.target.amount;
setSelectedOption({
...selectedOption,
[amount]: event.target.value,
});
};
<FormControl className={classes.formControl}>
<InputLabel
htmlFor="text-simple"
required
>{t('Anzahl Touren')}</InputLabel>
<Select
native
value={selectedOption.amount}
onChange={handleSelectChange}
inputProps={{
amount: 'amount'
}}
>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
</Select>
</FormControl>
EDIT:
Getting error: Every child in a list should have a unique key prop.
const numberList = ['1','2','3','4','5']
<FormControl className={classes.formControl}>
<InputLabel
htmlFor="text-simple"
required
>{t('Anzahl Touren')}</InputLabel>
<Select
name="amount"
input={<Input id="text-simple"/>}
required
native
value={selectedOption.amount}
onChange={handleSelectChange}
>
{numberList.map((amount,index) => {
return(
<option
key={index}
value={amount}>
{amount}
</option>
)
})}
</Select>
</FormControl>
Try this approach,
Set a name field for select. And update the state based on the name field.
like below,
<Select
name="amount" <--- Add this change
native
value={selectedOption.amount}
onChange={handleSelectChange}
inputProps={{
amount: "amount"
}}
>
handleSelectChange method:-
const amount = event.target.name;
Complete Code:-
import { FormControl, InputLabel, Select } from "#material-ui/core";
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [selectedOption, setSelectedOption] = useState({ amount: "" });
const handleSelectChange = (event) => {
console.log(event.target.name, event.target.value);
const amount = event.target.name;
setSelectedOption({
...selectedOption,
[amount]: event.target.value
});
};
return (
<>
<FormControl>
<InputLabel htmlFor="text-simple" required>
Anzahl Touren
</InputLabel>
<Select
name="amount"
native
value={selectedOption.amount}
onChange={handleSelectChange}
inputProps={{
amount: "amount"
}}
>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
</Select>
</FormControl>
Selected Amount - {selectedOption.amount}
</>
);
}
Working code - https://codesandbox.io/s/proud-wave-4dz0u?file=/src/App.js:0-1080

import huge option list into main component

I'm using React 16.12, and I have a component that contains a select dropdown box for a form. The option field section is huge...like over 75 choices. With it being so long, I don't want to clutter up my main form component.
So I tried putting it in a separate file called options.js like this:
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
But whenever I try to import, I just get this error:
Failed to compile
Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment
<>...</>?
I want it do look something like this in the main form component:
import React from "react";
import "./options" As OptionListing;
const App = () => (
<Form>
<select name="optionTypes">
<OptionListing>
</select>
</Form>
);
render(<App />, document.getElementById("root"));
Is this possible?
Thanks!
This is possible but you need one encapsulating component, try this.
import React from "react";
const OptionList = () => {
return (
<React.Fragment>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</React.Fragment>
)
}
export default OptionList
This is an alternate way of doing the same thing in shorthand (newer React versions)
import React from "react";
const OptionList = () => {
return (
<>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</>
)
}
export default OptionList
https://reactjs.org/docs/fragments.html
try modifying Options.js like below
<React.Fragment>
<option selected>Open this select menu</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</React.Fragment>
OR return array of elements like
const options = [
<option selected>Open this select menu</option>,
<option value="1">One</option>,
<option value="2">Two</option>,
<option value="3">Three</option>,
];
and use as
<Form>
<select name="optionTypes">
{options}
</select>
You can create a reusable Select component like this:
export default function Select({ name, options, handleSelected }) {
return (
<select name={name} onChange={e => handleSelected(e.target.value)}>
{options.map(({ key, title }) => (
<option key={key} value={key}>
{title}
</option>
))}
</select>
);
}
App.js
import React from "react";
import Select from "./Select";
const options = [
{
key: 1,
title: "Option 1"
},
{
key: 2,
title: "Option 2"
},
{
key: 3,
title: "Option 3"
}
];
export default function App() {
const onSelected = option => {
console.log(option);
};
return (
<div>
<form>
<Select
name="optionTypes"
options={options}
handleSelected={onSelected}
/>
</form>
</div>
);
}
You can also put the options to a file, and import it to the App.js.
For example:
options.json
[
{
"key": 1,
"title": "Option 1"
},
{
"key": 2,
"title": "Option 2"
},
{
"key": 3,
"title": "Option 3"
}
]
App.js
import React from "react";
import Select from "./Select";
import options from './options.json';
export default function App() {
const onSelected = option => {
console.log(option);
};
return (
<div>
<form>
<Select
name="optionTypes"
options={options}
handleSelected={onSelected}
/>
</form>
</div>
);
}
Codesandbox
If your options fields keys are different from key and title, before passing the options, you may use Array.map() to transform.

Resources