Last active
December 28, 2021 04:37
-
-
Save robertmarriott/13087d02d79e676fedf7c43e78346b47 to your computer and use it in GitHub Desktop.
Formik MUI Filtered Select Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Box, Button, MenuItem } from '@mui/material'; | |
import { Field, Form, Formik } from 'formik'; | |
import React, { useState } from 'react'; | |
import { TextField } from 'formik-mui'; | |
export default function SelectDemo({ regions, countries, cities, cityId }) { | |
const { countryId = 0 } = cities.find((city) => city.id === cityId); | |
const { regionId = 0 } = countries.find( | |
(country) => country.id === countryId | |
); | |
const [regionItems, setRegionItems] = useState(regions); | |
const [countryItems, setCountryItems] = useState( | |
countries.filter((country) => country.regionId === regionId) | |
); | |
const [cityItems, setCityItems] = useState( | |
cities.filter((city) => city.countryId === countryId) | |
); | |
const initialValues = { | |
regionId, | |
countryId, | |
cityId, | |
}; | |
function handleSubmit(values, { setSubmitting }) { | |
const { regionId, countryId, cityId } = values; | |
alert( | |
`Region ID: ${regionId}, Country ID: ${countryId}, City ID: ${cityId}` | |
); | |
setSubmitting(false); | |
} | |
return ( | |
<> | |
<Formik initialValues={initialValues} onSubmit={handleSubmit}> | |
{({ setFieldValue }) => { | |
function resetCountries(regionId) { | |
setFieldValue('countryId', 0); | |
setCountryItems( | |
countries.filter((country) => country.regionId === regionId) | |
); | |
} | |
function resetCities(countryId) { | |
setFieldValue('cityId', 0); | |
setCityItems(cities.filter((city) => city.countryId === countryId)); | |
} | |
function handleRegionIdChange(e) { | |
const regionId = e.target.value; | |
setFieldValue('regionId', regionId); | |
resetCountries(regionId); | |
resetCities(0); | |
} | |
function handleCountryIdChange(e) { | |
const countryId = e.target.value; | |
setFieldValue('countryId', countryId); | |
resetCities(countryId); | |
} | |
return ( | |
<Form> | |
<Box sx={{ p: 1 }}> | |
<Field | |
component={TextField} | |
select | |
fullWidth | |
name="regionId" | |
label="Region" | |
onChange={handleRegionIdChange} | |
> | |
<MenuItem value="0">Select Region...</MenuItem> | |
{regionItems.map(({ id, name }) => ( | |
<MenuItem key={id} value={id}> | |
{name} | |
</MenuItem> | |
))} | |
</Field> | |
</Box> | |
<Box sx={{ p: 1 }}> | |
<Field | |
component={TextField} | |
select | |
fullWidth | |
name="countryId" | |
label="Country" | |
onChange={handleCountryIdChange} | |
> | |
<MenuItem value="0">Select Country...</MenuItem> | |
{countryItems.map(({ id, name }) => ( | |
<MenuItem key={id} value={id}> | |
{name} | |
</MenuItem> | |
))} | |
</Field> | |
</Box> | |
<Box sx={{ p: 1 }}> | |
<Field | |
component={TextField} | |
select | |
fullWidth | |
name="cityId" | |
label="City" | |
> | |
<MenuItem value="0">Select City...</MenuItem> | |
{cityItems.map(({ id, name }) => ( | |
<MenuItem key={id} value={id}> | |
{name} | |
</MenuItem> | |
))} | |
</Field> | |
</Box> | |
<Box> | |
<Button type="submit">Submit</Button> | |
</Box> | |
</Form> | |
); | |
}} | |
</Formik> | |
</> | |
); | |
} | |
const regions = [ | |
{ id: 1, name: 'Asia' }, | |
{ id: 2, name: 'Europe' }, | |
{ id: 3, name: 'North America' }, | |
]; | |
const countries = [ | |
{ id: 1, regionId: 1, name: 'China' }, | |
{ id: 2, regionId: 1, name: 'Japan' }, | |
{ id: 3, regionId: 2, name: 'England' }, | |
{ id: 4, regionId: 2, name: 'France' }, | |
{ id: 5, regionId: 3, name: 'Canada' }, | |
{ id: 6, regionId: 3, name: 'United States' }, | |
]; | |
const cities = [ | |
{ id: 1, countryId: 1, name: 'Beijing' }, | |
{ id: 2, countryId: 1, name: 'Shanghai' }, | |
{ id: 3, countryId: 2, name: 'Osaka' }, | |
{ id: 4, countryId: 2, name: 'Tokyo' }, | |
{ id: 5, countryId: 3, name: 'London' }, | |
{ id: 6, countryId: 3, name: 'Manchester' }, | |
{ id: 7, countryId: 4, name: 'Marseille' }, | |
{ id: 8, countryId: 4, name: 'Paris' }, | |
{ id: 9, countryId: 5, name: 'Toronto' }, | |
{ id: 10, countryId: 5, name: 'Vancouver' }, | |
{ id: 11, countryId: 6, name: 'Los Angeles' }, | |
{ id: 12, countryId: 6, name: 'New York' }, | |
]; | |
const cityId = cities.find((city) => city.name === 'Vancouver').id; | |
export function getServerSideProps() { | |
return { | |
props: { | |
regions, | |
countries, | |
cities, | |
cityId, | |
}, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment