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

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.

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;

DatePicker not getting disabled on change in state

Please see the following code. I have a dropdown with 3 values, the DatePicker should conditionally get disabled when the user chooses 1, or 2 from the dropdown. But this is not happening.
import React, { useState } from 'react';
import ReactDatePicker from "react-datepicker";
export default function DateRangePicker() {
const [startDate, setStartDate] = useState("");
const [rangeType, setRangeType] = useState(1);
return <div>
<select value={rangeType} onChange={e => setRangeType(e.target.value)}>
<option value="1">This Month</option>
<option value="2">This Year</option>
<option value="3">Date Range</option>
</select>
<br />
<ReactDatePicker
disabled={rangeType !== 3}
selected={startDate}
onChange={e => setStartDate(e)}
/>
</div>;
}
What am I doing wrong here?
Thanks
Print a console log on the onChange, but from what I'm reading I suppose that the problem is the type: you're comparing string and numbers.

How do I use component state as props in another non-child component?

I have a form inside of a component that adds items to an array when submitted using useState. I want to use these array values as options in a select input of another component. The problem is that there's not a parent-child relationship. What would be the best way to go about this?
The component generating processes array:
import React, {useState, useEffect} from 'react';
import {useForm} from 'react-hook-form';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
function AddProcessForm () {
const {register, handleSubmit, watch, errors} = useForm();
const [processes, setProcesses] = useState([]);
const onSubmit = data => {
setProcesses(processes => [...processes, data])
console.log(data)
document.getElementById("process-entry-form").reset();
}
useEffect(() =>{
console.log(processes);
})
return (
<Form id="process-entry-form" onSubmit={handleSubmit(onSubmit)}>
<Form.Group controlId="" className="mx-2">
<Form.Label>Add Process</Form.Label>
<Form.Control name="processname" type="text" placeholder="Enter Process Name" ref={register}/>
</Form.Group>
<Button variant="primary" type="submit" className="mb-2">
Submit
</Button>
</Form>
)
}
export default AddProcessForm;
The component that needs to use processes as select options:
import React from 'react';
import Form from 'react-bootstrap/Form';
function ActivitytoProcessInput () {
return (
<Form.Group controlId="" className="mx-2">
<Form.Label>Belongs to Process</Form.Label>
<Form.Control as="select">
<option value="" selected>Select a Process</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
)
}
export default ActivitytoProcessInput;

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.

How to use Multi-Select Dropdown in react-bootstrap

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>

Resources