How can I set null as default value in Slider from Material UI - reactjs

I'm checking the documentation and looks like Slider requires the values to be an integer and also fallback to the first or the last item in case I pass a number that is not in the list of values for the Slider.
I'm creating a component that asks the user to select one of these:
Never | Rarely | Sometimes | Frequently | Almost always | Always
But it doesn't make sense to me to have an initial one selected. The options should show up initially as none of them selected. Is this something that Slider was not created to do? Looks so simple not having a value as default. Am I missing something?
Material UI Slider docs: https://material-ui.com/api/slider/

Currently, it is not possible to have MuiSlider without value. It will pick value from defaultValue or value.
For your use case, in case you need to use Slider component, you need to introduce one more extra value (only for UI sake)
import { Typography, Slider } from "#material-ui/core";
const marks = [
{ label: "None", value: 0 },
{
label: "Never",
value: 1
},
{
label: "Rarely Sometimes",
value: 2
},
{
label: " Frequently",
value: 3
},
{
label: "Almost always",
value: 4
},
{
label: "Always",
value: 5
}
];
export default function DiscreteSlider() {
const [sliderValue, setSliderValue] = useState(marks[0].value);
const onSliderValueChange = (e, val) => {
setSliderValue(val);
};
return (
<div>
<Typography id="discrete-slider" gutterBottom>
Slider
</Typography>
<Slider
aria-labelledby="discrete-slider"
valueLabelDisplay="off"
value={sliderValue}
onChangeCommitted={onSliderValueChange}
marks={marks}
min={0}
max={5}
/>
</div>
);
}
Else you can also check for Rating component available in lab version and map its rating with your selection values.
import Rating from "#material-ui/lab/Rating";
import Typography from "#material-ui/core/Typography";
export default function SimpleRating() {
const [value, setValue] = React.useState(0);
return (
<div>
<Rating
name="simple-controlled"
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
/>
</div>
);
}

Related

How to make MUI's Autocomplete display the label from the matching value in props.options?

I have a multilingual website where there are certain Autocompletes whose options array need to have its items labels translated, which is done very easily.
However, it would be harder to update the current chosen value, stored elsewhere. Since Autocomplete uses the label from the value prop instead of using the item of same ID within options, it ends up like this:
const vehicles = [
{ id: 1, label: "Car" },
{ id: 2, label: "Bus" }
];
const currentVehicleValue = {
id: 2,
label: "Ônibus"
};
export default function ComboBox() {
return (
<Autocomplete
disablePortal
id="combo-box-demo"
options={vehicles}
value={currentVehicleValue}
renderInput={(params) => <TextField {...params} label="Vehicle" />}
/>
);
}
Is there a way to just tell Autocomplete to use the label inside the options prop instead of the one within the value
demo
EDIT: I mean to have the label within options being shown while I don't type anything. As in, the language changed, the options were translated, but the currentValue was not, so it would be nice to have the Autocomplete use the label from the matching item within options as long as I don't type anything.
Edit after clarification
You can change how the <TextField/> is rendered by tweaking the props it receives.
In the example below, I find the currentVehicle by its id and change the inputProps.value to be the vehicle label.
Also, to ensure MUI finds the currentValue correctly within the options, you will need to use the isOptionEqualToValue to compare the options ids instead of strict equality
const vehicles = [
{ id: 1, label: "Car" },
{ id: 2, label: "Bus" }
];
const currentVehicleValue = {
id: 2,
label: "Ônibus"
};
function compareValueToOption(option, value) {
return option.id === value.id;
}
function ComboBox() {
return (
<Autocomplete
disablePortal
id="combo-box-demo"
options={vehicles}
value={currentVehicleValue}
renderInput={ComboBoxInput}
isOptionEqualToValue={compareValueToOption}
/>
);
}
function ComboBoxInput(props) {
const currentVehicle = vehicles.find(
(vehicle) => vehicle.id === currentVehicleValue.id
);
props.inputProps.value = currentVehicle.label;
return <TextField {...props} label="Vehicle" />;
}
Here's a working demo

react typescript set default value multiselect

I am using this module
import { MultiSelect } from "react-multi-select-component"
and creating form by this
const [selected_to2, setSelected_to2] = useState([]);
<MultiSelect
options={options2}
value={selected_to}
onChange={setSelected_to}
labelledBy="Select2"
/>
then I creating multiselect component with default value using this
selected_to2.push({
value: item?.Code,
label: item?.Name
})
but returning value with 4 time called in the multiselect form, any proper way to set default value of multiselect then also add and remove in multiselect item?
React state must updated by set function. Edit the value directly will not work.
So you need do
setSelected_to2(s => [...s, {
value: item?.Code,
label: item?.Name
}])
First of all you are updating state is a wrong way
Wrong way
selected_to2.push({
value: item?.Code,
label: item?.Name
})
Right way:
setSelected_to2([{
value: item?.Code,
label: item?.Name
}
])
Here's a quick example that I did might help you, remember your default value must be an array of selected values since it's a multiselect component.
JSX
import { useState } from "react";
import { MultiSelect } from "react-multi-select-component";
import "./App.css";
const options = [
{ label: "The Godfather", value: 1 },
{ label: "Pulp Fiction", value: 2 },
];
const App = ({ editMode = true }) => {
const [value, setValue] = useState(editMode ? [options[1]] : []);
return (
<div className="App">
<MultiSelect
options={options}
value={value}
onChange={(selectedValues) => setValue(selectedValues)}
labelledBy="Select2"
/>
</div>
);
};
export default App;

Access selected value from react's Select Component

Hello dear community,
I want to create a very basic website for my school assignment.
I have a dropdown menu with a Select Component as its implementation. I need to access the selected value, which is a currency in my case, in order to update the information displayed on the page once a currency has been selected.
I am kind of frustrated since I wasn't able to find a helpfull solution to my relatively basic problem (I think it's basic :D)
My component class here:
import { Component } from "react";
import Select from 'react-select';
interface DropdownMenuProps {
values: [{}]
defaultValue: string
}
interface DropdownMenuState { }
/**
* Represents a Dropdown Menu
*/
export default class DropdownMenu extends Component<DropdownMenuProps, DropdownMenuState> {
render() {
return (
<div style={{ width: '120px' }}>
<Select id="dropdown-menu"
placeholder={this.props.defaultValue}
options={this.props.values}
// getOptionValue={(option) => option.value}
// getOptionLabel={(option) => option.label}
/>
</div>
)
}
}
This is how I create a dropdown menu compent:
<DropdownMenu defaultValue="Currency" values={[{ label: "EUR", value: "EUR" }, { label: "GBP", value: "GBP" }, { label: "USD", value: "USD" }]} ></DropdownMenu>
I'm glad for any tips :)
You have to use the onChange prop of react-select:
<select
id="dropdown-menu"
onChange={handleSelectChange}
>
and in this function you could handle the changes:
const handleSelectChange = (selectedVal) => console.log(selectedVal)
I recommend you using directly onChange and save it into a state:
1st:
Create state with the name you want:
const [selectValue, setSelectValue] = useState({});
2nd: Create options:
const options = [
{ label: "Tomate", value: 1 },
{ label: "Queso", value: 2 }
];
3rd: add method onChange in select and pass options:
const onChange = (ev) => {
setSelectValue(ev);
//console.log(ev);
console.log(selectValue);
};
<Select
id="dropdown-menu"
placeholder={"e"}
options={options}
onChange={onChange}
/>
I have created demo here:
https://codesandbox.io/s/ancient-pond-96h53?file=/src/App.js

Manipulate React Render Properties

I have a react component that is rendering data via the react-multi-select-component. I need to change the way the data renders. The library has a property - ItemRenderer but I'm not sure how to manipulate the properties. For example:
Current data render:
123 Item Red
124 Item Blue
204 Item Green
Desired data render:
Item Red (125)
Item Blue (124)
Item Green (204)
The actual UI code is like:
return (
<div>
<MultiSelect
options={dataListOptions}
value = {selectedListOptions}
onChange = {setSelectedOptions}
</div>
);
You can manipulate the label of each item by using ItemRenderer. See below:
export default function App() {
const options = [
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango" },
{ label: "Strawberry 🍓", value: "strawberry", disabled: true }
];
const [selected, setSelected] = useState([]);
return (
<div>
<h1>Select Fruits</h1>
<pre>{JSON.stringify(selected)}</pre>
<MultiSelect
options={options}
value={selected}
onChange={setSelected}
labelledBy={"Select"}
ItemRenderer={data => data.option.label + " CHANGED"}
/>
</div>
);
}
It will render the option like this:
Grapes 🍇 CHANGED
Mango 🥭 CHANGED
Strawberry 🍓 CHANGED
In your case, since ItemRenderer props accepts a function, you just have to modify it whatever you like.

How to format value of the React Select

I use "react final forms" and "react select".
I've organized an interface and functionality works, but I have one thing which I don't like.
React select requires options in next format:
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
and the value also should be set as { value: 'chocolate', label: 'Chocolate' }.
But for me is strange to have in my model of data (and send to the server also) the value like this - { value: 'chocolate', label: 'Chocolate' }, because I need only 'chocolate'.
Easy way is format the object into a single value after the form will be saved and format back from single value to the object before the rendering of the element. I know how to do it outside of form, but in this case I should solve this problem again and again for each select element separately.
What I would like to do:
Find a way how to set value of the react select as single value, like 'chocolate' instead of object.
OR
Create a wrapper for react select component and format value there when it sets (it's easy) and when the form get the value from this field (this I don't know how to do).
I will appreciate any help.
Method 1
With strings:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";
const data = ["1", "2"];
function SingleStringReactSelect() {
const [option, setOption] = useState();
return (
<section>
<Select
onChange={option => setOption(option)}
value={[option]}
getOptionLabel={label => label}
getOptionValue={value => value}
closeMenuOSelect={false}
options={data}
/>
</section>
);
}
Method 2:
Created example:
https://codesandbox.io/s/react-codesandboxer-example-z57ke
You can use map in options and with Wrapper like SingleValueReactSelect
import React, { Fragment, useState } from "react";
import Select from "react-select";
const data = ["chocolate", "strawberry", "vanilla"];
export function SingleValueReactSelect(props) {
const [selectedItem, setSelectedItem] = useState();
return (
<Select
{...props}
value={selectedItem}
onChange={item => {
setSelectedItem(item);
props.onChange(item.value);
}}
options={props.options.map(item => ({ label: item, value: item }))}
/>
);
}
export default function AppDemo() {
return (
<Fragment>
<p>SingleValueReactSelect Demo</p>
<SingleValueReactSelect
isClearable
isSearchable
options={data}
onChange={item => {
alert(item);
}}
/>
</Fragment>
);
}
You can transform/filter the object data once you are sending the form data to server or another component.
Setting the value of the react-select as a single value will not show it as selected in the React-Select.

Resources