How To Create A Multiform In MUI And Next Js?
Embarking on the journey of creating a Multiform with Material-UI and Next.js opens the door to a world of possibilities for dynamic and engaging user experiences. In this comprehensive guide, we’ll explore the intricacies of building a Multiform and dive into the provided code snippets step by step.
Unveiling the Multiform Architecture
Multiform Component – MultiForms.js
Now, let’s delve into the MultiForms
component, where Material-UI’s Stepper
guides users through different steps. The showSteps
function dynamically renders the appropriate form step based on the current step.
// MultiForms.js
import React, { useContext } from "react";
import StepOne from "./StepOne";
import StepTwo from "./StepTwo";
import { Stepper, StepLabel, Step } from "@mui/material";
import { MultiStepContext } from "./StepContext";
const MultiForms = () => {
const { currentstep } = useContext(MultiStepContext);
function showSteps(step) {
switch (step) {
case 1:
return <StepOne />;
case 2:
return <StepTwo />;
default:
// Handle additional steps as needed
}
}
return (
<>
<div className="App">
<center>
<h1> MultiForms</h1>
<Stepper
style={{ width: "400px" }}
activeStep={currentstep - 1}
orientation="horizontal"
>
<Step>
<StepLabel></StepLabel>
</Step>
<Step>
<StepLabel></StepLabel>
</Step>
</Stepper>
{showSteps(currentstep)}
</center>
</div>
</>
);
};
export default MultiForms;
Step Context – StepContext.js
The StepContext
component plays a pivotal role in managing the state of the Multiform. It handles form data, form errors, the current step, and provides functions like SubmitData
to process the collected information.
// StepContext.js
import React, { useState } from "react";
import MultiForms from "./MultiForms";
export const MultiStepContext = React.createContext();
const StepContext = () => {
const [currentstep, setCurrentStep] = useState(1);
const [UserData, setUserData] = useState({
firstname: "",
lastname: "",
email: "",
number: "",
address: "",
city: "",
});
const [File, setFile] = useState("");
const [formErrors, setFormError] = useState({});
function SubmitData() {
console.log("click");
let Data = { UserData, File };
console.log(Data);
// Further processing logic can be added here
}
return (
<>
<div>
<MultiStepContext.Provider
value={{
formErrors,
setFormError,
File,
setFile,
currentstep,
setCurrentStep,
UserData,
setUserData,
SubmitData,
}}
>
<MultiForms />
</MultiStepContext.Provider>
</div>
</>
);
};
export default StepContext;
app.js – The Gateway to Multiforms
Let’s start by understanding the root _app.js
file. This file initializes the application and wraps it with a StepContext
component, a crucial part of our Multiform architecture. The StepContext
will manage the flow between different form steps.
// _app.js
import StepContext from "@/components/MultiForm/StepContext";
import "@/styles/globals.css";
export default function App({ Component, pageProps }) {
return (
<>
<StepContext>
<Component {...pageProps} />;
</StepContext>
</>
);
}
StepOne – Collecting Basic Information
StepOne.js
handles the collection of basic user information, ensuring that all required fields are filled. Validation logic is implemented to display errors if necessary.
// StepOne.js
import React, { useContext } from "react";
import { Button, TextField } from "@mui/material";
import { MultiStepContext } from "./StepContext";
const StepOne = () => {
const { setCurrentStep, UserData, setUserData, formErrors, setFormError } =
useContext(MultiStepContext);
const handleInput = (e) => {
setUserData({ ...UserData, [e.target.name]: e.target.value });
};
const validate = () => {
let inputValid = UserData;
let formErrors = {};
let isValid = true;
const reg = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
if (!inputValid.firstname) {
isValid = false;
formErrors.firstname = "Firstname field is required!";
}
if (!inputValid.lastname) {
isValid = false;
formErrors.lastname = "Lastname field is required!";
}
if (!inputValid.email) {
isValid = false;
formErrors.email = "Email field is required ";
} else if (!reg.test(inputValid.email)) {
isValid = false;
formErrors.email = "This is not a valid email";
}
setFormError(formErrors);
return isValid;
};
const stepButtonTwo = (e) => {
e.preventDefault();
if (validate()) {
setCurrentStep(2);
}
};
return (
<>
<div className="container">
<div>
<TextField
className="wd"
type="text"
value={UserData.firstname}
name="firstname"
onChange={handleInput}
label="FirstName"
margin="normal"
variant="outlined"
color="primary"
/>
</div>
<span style={{ color: "red" }}>{formErrors.firstname}</span>
<div>
<TextField
className="wd"
type="text"
value={UserData.lastname}
name="lastname"
onChange={handleInput}
label="LastName"
margin="normal"
variant="outlined"
color="primary"
/>
</div>
<span style={{ color: "red" }}>{formErrors.lastname}</span>
<div>
<TextField
className="wd"
type="email"
value={UserData.email}
name="email"
onChange={handleInput}
label="Email"
margin="normal"
variant="outlined"
color="primary"
/>
</div>
<span style={{ color: "red" }}>{formErrors.email}</span>
<div>
<Button
style={{ margin: "10px" }}
variant="contained"
onClick={stepButtonTwo}
color="primary"
>
Next
</Button>
</div>
</div>
</>
);
};
export default StepOne;
StepTwo – Advanced Information and File Upload
StepTwo.js
focuses on collecting advanced user information and allows users to upload a file. Similar to StepOne
, it includes validation logic for error handling.
// StepTwo.js
import React, { useContext } from "react";
import {
Button,
TextField,
Select,
FormControl,
MenuItem,
InputLabel,
} from "@mui/material";
import { MultiStepContext } from "./StepContext";
import FileUploadIcon from "@mui/icons-material/FileUpload";
const StepTwo = () => {
const {
setCurrentStep,
UserData,
setUserData,
SubmitData,
File,
setFile,
formErrors,
setFormError,
} = useContext(MultiStepContext);
const validate = () => {
let inputValid = UserData;
let formErrors = {};
let isValid = true;
if (!inputValid.address) {
isValid = false;
formErrors.address = "Address field is required!";
}
if (!inputValid.city) {
isValid = false;
formErrors.city = "City field is required!";
}
if (!inputValid.number) {
isValid = false;
formErrors.number = "Number field is required!";
} else if (inputValid.number.length !== 10) {
isValid = false;
formErrors.number = "Number must be 10 characters";
}
if (!File) {
isValid = false;
formErrors.File = "File field is required!";
}
setFormError(formErrors);
return isValid;
};
const stepButtonFinal = (e) => {
e.preventDefault();
if (validate()) {
SubmitData();
}
};
const handleInput = (e) => {
setUserData({ ...UserData, [e.target.name]: e.target.value });
};
const handleFile = (e) => {
const file = e.target.files[0];
setFile(file);
console.log(file);
};
return (
<div className="container">
<div>
<TextField
className="wd"
type="number"
value={UserData.number}
onChange={handleInput}
name="number"
label="Number"
margin="normal"
variant="outlined"
color="primary"
/>
</div>
<span style={{ color: "red" }}>{formErrors.number}</span>
<div>
<TextField
className="wd"
type="text"
value={UserData.address}
name="address"
onChange={handleInput}
label="Address"
margin="normal"
variant="outlined"
color="primary"
/>
</div>
<span style={{ color: "red" }}>{formErrors.address}</span>
<div>
<FormControl sx={{ my: 2, minWidth: 220 }}>
<InputLabel id="demo-simple-select-label">Enter City</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={UserData.city}
name="city"
label="Enter City"
onChange={handleInput}
>
<MenuItem value="london">London</MenuItem>
<MenuItem value="newyork">New york</MenuItem>
<MenuItem value="dubai">Dubai</MenuItem>
</Select>
</FormControl>
</div>
<span style={{ color: "red" }}>{formErrors.city}</span>
<div className="f-file">
<input
onChange={handleFile}
name="file"
type="file"
accept=""
style={{ display: "none" }}
id="contained-button-file"
multiple
/>
<label htmlFor="contained-button-file">
<Button variant="contained" color="primary" component="span">
<FileUploadIcon />
Upload
</Button>
</label>
<div>{File.name}</div>
</div>
<span style={{ color: "red" }}>{formErrors.File}</span>
<div>
<Button
variant="contained"
onClick={() => setCurrentStep(1)}
color="secondary"
>
Back
</Button>
<span> </span>
<Button
style={{ margin: "10px" }}
variant="contained"
onClick={stepButtonFinal}
color="primary"
>
Submit
</Button>
</div>
</div>
);
};
export default StepTwo;
Conclusion: Crafting a Seamless Multiform Experience
In conclusion, mastering the art of Multiforms with Material-UI and Next.js empowers you to create interactive, step-by-step user journeys. By understanding the provided code snippets, you have the foundation to customize and expand this Multiform for your specific project needs.
Enhance your development skills with more insights and tutorials at Your Learning Hub.
All Related Posts
- MUI Table Integration, Pagination, & Excel Export
- Cloudinary Setup In Next.Js: A Step-By-Step Guide
- How To Secure APIs In Next JS
- How to use Nodemailer in Next JS
- How To Use MUI Grid For Responsive Web Layouts
- Material-UI Typography: React Text Styling Guide
- Next.Js And Material UI: Building A Login Page
- How To Create Contact Form With MUI In React
- How To Use Material UI Forms
- MUI AppBar For Top-Level Navigation In React
- MUI Card Components: Elevate Your React UI Design
- How To Use Material-UI Cards