Complex web forms don’t have just text input fields; they are built with different types of components, including Sliders.
What is a Slider in UI?
A slider allows users to adjust values quickly by sliding rather than typing. It provides instant visual feedback, showing users the selected range.
One of the biggest advantages of using a slider is that there is a 0% chance that the user will select invalid values because we are redefining the values between specific ranges, and users can’t go outside that range.
You can create functionality based on the Slider, which means that when a user selects a specific range, you will dynamically update the UI.
For example, if you are browsing an e-commerce application, you must have seen the price range slider. When you select a range from the Slider, it will show the products belonging to that price range.
Implementing Range Slider Component in React
With the help of Vite, Material-UI (for styling), Formik (for form state management), and Yup (for defining validation schema), we can implement a Range slider, capture its values, and display them in the front using the alert box.
Here is what we will build and what the final output looks like:
Here is the step-by-step guide to implement it:
Step 1: Setup a new React project with Vite
Type the following command to create a new React with Vite using the below command:
npm create vite@latest formik-range-slider -- --template react cd formik-range-slider npm install
Step 2: Install the MUI, Formik, and Yup
Install all the necessary modules using the command below:
npm install @mui/material @emotion/react @emotion/styled formik yup @mui/icons-material
Step 3: Create a reusable RangeSlider component
We will create a reusable range slider, a RangeSlider component with Formik for form management and Material-UI for styling. If validation fails, it displays a label, a styled slider, and an error message.
Inside the src folder, create a new folder called “components”, and inside the “components” folder, create a new file called “RangeSlider.jsx”. Add the code below.
// src/components/RangeSlider.jsx import { Slider, Typography, Box } from "@mui/material"; import { useField } from "formik"; // eslint-disable-next-line react/prop-types const RangeSlider = ({ label, ...props }) => { const [field, meta, helpers] = useField(props); const handleChange = (_, value) => { helpers.setValue(value); }; return ( <Box sx={{ width: 300, mt: 2 }}> <Typography gutterBottom>{label}</Typography> <Slider {...field} {...props} onChange={handleChange} valueLabelDisplay="auto" sx={{ color: "primary.main", "& .MuiSlider-thumb": { "&:hover, &.Mui-focusVisible": { boxShadow: "0px 0px 0px 8px rgba(25, 118, 210, 0.16)", }, }, }} /> {meta.touched && meta.error ? ( <Typography color="error" variant="caption"> {meta.error} </Typography> ) : null} </Box> ); }; export default RangeSlider;
In the above code, the Slider is the main MUI component we imported to implement the Slider.
We use the useField hook to connect the component to Formik’s form state. It provides an array containing field, meta, and helpers related to the form field.
The handleChange() function updates the field’s value using Formik’s setValue helper function. The value is the Slider’s new value. The onChange event triggers the handleChange() function, which sets the latest value of the range slider.
Step 4: Create utilities
We will create separate files for constants, validation schemas, and utility functions. This approach will make the code more maintainable and easier to scale.
Inside the src folder, create a new folder called utils, and inside that folder, create the following two new files:
- formConstants.js
- formUtils.js
Add the code below inside the formConstants.js file:
// src/utils/formConstants.js export const INITIAL_VALUES = { price: [20, 80], rating: [2, 4], }; export const SLIDER_CONFIG = { price: { label: "Price Range ($)", min: 0, max: 100, step: 1, }, rating: { label: "Rating Range", min: 0, max: 5, step: 0.5, }, };
Add the code below inside the formUtils.js file:
// src/utils/formUtils.js export const handleSubmit = (values, { setSubmitting }) => { alert(JSON.stringify(values, null, 2)) setSubmitting(false); };
Step 5: Define a validation schema
Inside the src folder, create a new folder called validation, and inside that folder, create a new file called validationSchema.js and add the code below:
// src/validation/validationSchema.js import * as Yup from 'yup'; export const createRangeValidation = (fieldName) => Yup.array() .of(Yup.number()) .length(2) .test(`${fieldName}-range`, `Invalid ${fieldName} range`, (value) => value[0] < value[1]); export const validationSchema = Yup.object({ price: createRangeValidation('price'), rating: createRangeValidation('rating'), });
Step 6: Create a RangeSliderForm
We will create a final form file called RangeSliderForm.jsx inside the src directory. This component is responsible for rendering a form containing range sliders and a submit button.
Add the code below in RangeSliderForm.jsx:
// src/components/RangeSliderForm.jsx import { Formik, Form } from "formik"; import { Button, Box } from "@mui/material"; import RangeSlider from "./RangeSlider"; import { INITIAL_VALUES, SLIDER_CONFIG } from "../utils/formConstants"; import { validationSchema } from "../validation/validationSchema"; import { handleSubmit } from "../utils/formUtils"; const RangeSliderForm = () => { return ( <Box sx={{ maxWidth: 400, mx: "auto", mt: 4, p: 2, boxShadow: 3, borderRadius: 2, }} > <Formik initialValues={INITIAL_VALUES} validationSchema={validationSchema} onSubmit={handleSubmit} > {({ isSubmitting }) => ( <Form> {Object.entries(SLIDER_CONFIG).map(([name, config]) => ( <RangeSlider key={name} name={name} {...config} /> ))} <Button type="submit" variant="contained" color="primary" disabled={isSubmitting} sx={{ mt: 2 }} > Submit </Button> </Form> )} </Formik> </Box> ); }; export default RangeSliderForm;
In this code, we initialize the form with values from INITIAL_VALUES, validate the form using validationSchema, and handle the form submission with handleSubmit.
If we select the range and submit the form, it will display the range in the alert box.
Step 7: Update the App.jsx to use the new component
Update the src/App.jsx file like this:
// src/App.jsx import RangeSliderForm from "./components/RangeSliderForm"; import Container from "@mui/material/Container"; import { CssBaseline, Typography } from "@mui/material"; const App = () => { return ( <Container> <CssBaseline /> <Typography variant="h4" align="center" gutterBottom> Range Slider Form Example </Typography> <RangeSliderForm /> </Container> ); }; export default App;
And the src/main.jsx file looks like this:
// src/main.jsx import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App.jsx"; ReactDOM.createRoot(document.getElementById("root")).render( <React.StrictMode> <App /> </React.StrictMode> );
Step 8: Run the project
npm run dev
This RangeSliderForm.jsx component demonstrates how to use multiple range sliders in a form.
Let’s change the range of price range and rating range and submit the form.
If you analyze the output, you can see that we have two ranges of two different sliders.
That’s all!