how to dynamically add SelectOption in React.js - javascript

There is a list l:
l = [
["a","b"],
["c","d"]
]
I want to make a SelectOption field dynamically with this list for which I write:
<Field
name="successData.val"
render={({ field: { name } }) => (
<Column>
<Select
onChange={value => setFieldValue(name, value)}
placeholder="dummy"
width={300}
>
{l.forEach(key => (
<SelectOption
value={key[0]}
label={key[1]}
/>
))}
</Select>
</Column>
)}
/>
But when I click the drop down button, the list doesn't appear, just the upper borderline of the box gets highlighted, it seems the drop down is getting generated, but not correctly.
Can anyone please suggest what might be wrong in this implementation?

Use map()
{l.map(key => (
<SelectOption
value={key[0]}
label={key[1]}
/>
))}

Related

Checking checkbox inside Autocompletion with MUI

[
{ label: 'First', checked: false },
{ label: 'Second', checked: true }
]
Here is a very short snippet of how the data could look like.
I am using Material UI's Autocomplete, to make it possible for searching on labels.
These labels are having a checkbox.
Problem is, I can't use onChange on <Checkbox /> when its a renderOption
The Autocomplete just closes, without doing any action
<Autocomplete
disableCloseOnSelect={true}
options={array}
getOptionLabel={option => option.label.toString()}
renderInput={params => (
<TextField
{...params}
fullWidth
label="Select label"
variant="outlined"
error={false}
/>
)}
renderOption={opt => (
<div>
<Checkbox
checked={opt.checked}
onChange={() => alert('not being fired...')}
/>
<p>{opt.label}</p>
</div>
)}
/>
You shouldn't use onChange in Checkbox, You should use onChange prop of Autocomplete, and set default value by value prop
and Checkbox receive its props from renderOption's props
const [selectedOptions, setSelectedOptions] = useState([]);
useEffect(() => {
setSelectedOptions(options.filter(op => op.checked));
}, []);
<Autocomplete
options={options}
value={selectedOptions}
onChange={(event, newValue) => {
setSelectedUsers(newValue);
}
renderOption={(props, option, { selected }) => (
<div {...props}>
<Checkbox checked={selected} />
<p>{option.name}</p>
</div>
)}
disableCloseOnSelect
/>
onChange event will work in Checkbox provided in renderOption function but it only works when you click on checkbox not anywhere else on list item. You can use onClick on the parent div if that fulfills your purpose.

React chip input field

I'm using React 17 and tried to use different chip input fields like material-ui-chip-input etc. Unfortunately, all npm packages I tried do not work with react version 17.
Do you know of any component that works with this version or how I could create one myself?
Thanks in advance
Edit:
I have managed to do what I wanted, but unfortunately, I now get the following error when pressing enter / adding a new item:
index.js:1 Warning: Cannot update a component (CreatePoll) while rendering a different component (ForwardRef(Autocomplete))
Here is the codesandbox which shows the problem:
https://codesandbox.io/s/compassionate-greider-wr9wq?file=/src/App.tsx
why don't you use this instead of a new package?
Autocomplete exactly do that.
const [receivers, setReceivers] = React.useState<string[]>([]);
import Autocomplete from '#mui/material/Autocomplete';
<Autocomplete
multiple
onChange={(e, value) => setReceivers((state) => value)}
id="tags-filled"
options={top100Films.map((option) => option.title)}
defaultValue={[top100Films[13].title]}
freeSolo
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip variant="outlined" label={option} {...getTagProps({ index })} />
))
}
renderInput={(params) => (
<TextField
{...params}
variant="filled"
label="freeSolo"
placeholder="Favorites"
/>
)}
/>
import React from 'react'
import { MuiChipsInput } from 'mui-chips-input'
const MyComponent = () => {
const [chips, setChips] = React.useState([])
const handleChange = (newChips) => {
setChips(newChips)
}
return (
<MuiChipsInput value={chips} onChange={handleChange} />
)
}
Source:
https://github.com/viclafouch/mui-chips-input
Supports both React 17 / 18 and MUI V5
Use the freeSolo prop of Autocomplete, and just set the options prop to an empty array:
<Autocomplete
multiple
freeSolo
options={[]}
renderTags={(value, getTagProps) =>
value.map(option, index) => (
<Chip label={option} {...getTagProps({ index })} />
))
}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label="Add Chip"
placeholder="Type and press enter"
/>
)}
/>

How to set default selected items in Autocomplete

I am using material-ui Autocomplete and I want to add some default selected options to it.
https://codesandbox.io/s/broken-fire-htxtd?file=/src/App.js
As you can see in the example I am rendering pre-selected items with startAdornment. The problem is when I try to select another item, it automatically deletes the pre-selected items. Also I cannot delete them properly.
The idea is this default selected to stay selected until I remove them. Also to be able to pick another letter without erasing them.
you can use defaultValue property instead of Adornment.
<Autocomplete
multiple
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
options={["A", "B", "C", "D", "E"]}
disableCloseOnSelect
defaultValue={cities} //here
onChange={(e, v) => setCities(v)}
getOptionLabel={(option) => option}
renderOption={(option, { selected }) => {
if (cities.includes(option)) {
selected = true;
}
return (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option}
</React.Fragment>
);
}}
renderInput={(params) => {
return (
<TextField
{...params}
variant="outlined"
label="Cities"
placeholder="Enter cities"
autoComplete="off"
/>
);
}}
/>

Why required check not working after removing element?

Could you please tell why my required check is not working in autocomplete .I am using material UI with react hook form.
Step to reproduce
Click Submit button it show field is required.
then select any element from list.
remove the selected element Then click again submit button.It should
show “required” field check.but it is not showing anything why ??
Here is my code
https://codesandbox.io/s/mui-autocomplete-with-react-hook-form-0wvpq
<Controller
as={
<Autocomplete
id="country-select-demo"
multiple
style={{ width: 300 }}
options={countries}
classes={{
option: classes.option
}}
autoHighlight
getOptionLabel={option => option.label}
renderOption={(option, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.label} ({option.code}) +{option.phone}
</React.Fragment>
)}
renderInput={params => (
<TextField
{...params}
label="Choose a country"
variant="outlined"
fullWidth
name="country"
inputRef={register({ required: true })}
// required
error={errors["country"] ? true : false}
inputProps={{
...params.inputProps,
autoComplete: "disabled" // disable autocomplete and autofill
}}
/>
)}
/>
}
onChange={([event, data]) => {
return data;
}}
name="country"
control={control}
/>
When the form loads initially, the value of your form is an empty object -
{}
When you select a country (say, 'Andorra') the value of your form becomes:
{"country":[{"code":"AD","label":"Andorra","phone":"376"}]}
And then when you deselect the country, the value of your form becomes:
{"country":[]}
An empty array technically meets the "required" criteria (it's not null, after all) so your required handler doesn't fire.
You can verify this is happening by showing the value of the form in your App class -
const { control, handleSubmit, errors, register, getValues } = useForm({});
return (
<form noValidate onSubmit={handleSubmit(data => console.log(data))}>
<Countries control={control} errors={errors} register={register} />
<Button variant="contained" color="primary" type="submit">
Submit
</Button>
<code>{JSON.stringify(getValues())}</code>
</form>
);
The simple fix is to NOT return an empty array as a value from your control - update your onChange handler as follows -
onChange={([event, data]) => {
return data && data.length ? data : undefined;
}}

Changing format of Server-Side data inside react-virtualized table

I'm making a React app that has two view options:
cards and
lists (tables).
I'm using react-virtualized for the list-view option. The problem is that I need to change the format of the server-side data I get when the data type is number. I've already done that in the card-view option. For example, this is my ItemCard Component:
<div className="container">
<div>{id}</div>
<div>{name}</div>
<div>{parseFloat(inventory).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}</div>
<div>{parseFloat(unitprice).toFixed(2)}</div>
</div>
which I use in the ItemList Component like this:
beautifiedData.map((product, i) => {
return (
<ItemCard
key={i}
id={item.No}
name={item.name}
inventory={item.Inventory}
unitprice={item.UnitPrice}
/>
)
})
How should I do the exact same thing with react-virtualized table which looks like this:
<Table className="items-table"
width={1300}
height={400}
headerHeight={20}
rowHeight={30}
rowCount={list.length}
rowGetter={({ index }) => list[index]}
sortBy={this.state.sortBy}
sortDirection={this.state.sortDirection}
sort={this.sort}
>
<Column
label={content[langProp].ID}
dataKey= 'No'
width={150}
/>
<Column
label={content[langProp].Name}
dataKey= 'Name'
width={150}
/>
<Column
label={content[langProp].Inventory}
dataKey= 'Inventory'
width={150}
/>
<Column
label={content[langProp].UnitPrice}
dataKey= 'UnitPrice'
width={150}
/>
How can I change the format of 'Inventory' and 'UnitPrice' server-side data whose type is string?
I found a solution, I used cellDataGetter like this:
<Column
label={content[langProp].Inventory}
cellDataGetter={({ rowData }) => parseFloat(rowData.Inventory).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
dataKey='Inventory'
width={150}
/>

Categories