Month and Year picker in MUI React - reactjs

Is there any way to implement a month Picker and year picker using MUI.
In month view the output should be like only month and the year only Eg:- 2020-09

V5
MUI v5 added the DatePicker to #mui/lab so you don't need to install the third-party package anymore. To restrict to month and year only, you can set the view prop like this:
<DatePicker
views={['year', 'month']}
label="Year and Month"
minDate={new Date('2012-03-01')}
maxDate={new Date('2023-06-01')}
value={value}
onChange={setValue}
renderInput={(params) => <TextField {...params} helperText={null} />}
/>
output should be like only month and the year only Eg:- 2020-09
To change how the TextField display the current date, use inputFormat prop. If you're using date-fns, see this table here for reference.
<DatePicker inputFormat="yyyy-MM"
V4
You can use different views as demonstrated in this section here.
<DatePicker
variant="inline"
openTo="year"
views={["year", "month"]}
label="Year and Month"
helperText="Start from year selection"
value={selectedDate}
onChange={handleDateChange}
/>
Live Demo

In your component, pass an array called views with month and year.
views={["year", "month"]}
Take a look at views prop for more info: https://material-ui-pickers.dev/api/KeyboardDatePicker
Also change the format to MM/yyyy
format="MM/yyyy"
Here is a sandbox for your reference:

import "date-fns";
import React from "react";
import Grid from "#material-ui/core/Grid";
import DateFnsUtils from "#date-io/date-fns";
import { MuiPickersUtilsProvider, DatePicker } from "#material-ui/pickers";
export default function MaterialUIPickers() {
// The first commit of Material-UI
const [selectedDate, setSelectedDate] = React.useState<Date | null>(
new Date("2014-08-18T21:11:54")
);
const handleDateChange = (date: Date | null) => {
setSelectedDate(date);
};
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<DatePicker
variant="inline"
openTo="year"
views={["year", "month"]}
label="Year and Month"
helperText="Start from year selection"
value={selectedDate}
onChange={handleDateChange}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}
Second Solution
import "date-fns";
import React from "react";
import Grid from "#material-ui/core/Grid";
import DateFnsUtils from "#date-io/date-fns";
import {
MuiPickersUtilsProvider,
KeyboardDatePicker
} from "#material-ui/pickers";
export default function MaterialUIPickers() {
const [selectedDate, setSelectedDate] = React.useState(
new Date("2014-08-18T21:11:54")
);
const handleDateChange = (date) => {
setSelectedDate(date);
};
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/yyyy"
views={["year", "month"]}
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
"aria-label": "change date"
}}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}

Related

How to "auto format" date in mui DatePicker with mm/yyyy format?

I've been working with mui DatePciker with mm/yyyy format. The thing is that I want the slash to appear automatically if the user writes by itself, like it happens with dd/mm/yyyy format.
I've checked the documentation and changing the examples that are given but I can't make it work.
Here is the example I am workig on: https://codesandbox.io/s/loving-parm-70mcsq?file=/demo.tsx
Example image:
As you can see in the image the first DatePicker has the format mm/yyyy, I wrote it by myself and this is what I get 032021 instead of 03/2021 whereas in the second DatePicker the slashes are added automatically while writing the date 12/12/
How can I replicate automatically adding the slashes behaviour? Thank you!
CODE:
import * as React from "react";
import dayjs, { Dayjs } from "dayjs";
import TextField from "#mui/material/TextField";
import Stack from "#mui/material/Stack";
import { LocalizationProvider } from "#mui/x-date-pickers/LocalizationProvider";
import { AdapterDayjs } from "#mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "#mui/x-date-pickers/DatePicker";
export default function ViewsDatePicker() {
const [value, setValue] = React.useState<Dayjs | null>(dayjs("2022-04-07"));
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Stack spacing={3}>
<DatePicker
views={["year", "month"]}
inputFormat="MM/YYYY" //Added prop
label="Year and Month"
minDate={dayjs("2012-03-01")}
maxDate={dayjs("2023-06-01")}
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} helperText={null} />}
/>
<DatePicker
openTo="year"
views={["year", "month", "day"]}
label="Year, month and date"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} helperText={null} />}
/>
</Stack>
</LocalizationProvider>
);
}
Finally I've found an answer that works. It can be fixed with this two props:
mask="__/____"
disableMaskedInput={false}
This two must be added, only with mask doesn't work.
Answer and more explanation found here: https://github.com/mui/mui-x/issues/4664

reactjs KeyboardDatePicker + react hook form: How to get the date in YYYY-MM-DD format

I am using material ui + react hook form for my form
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Controller
name="date_of_birth"
control={control}
defaultValue={new Date()}
render={({ field: { ref, ...rest } }) => (
<KeyboardDatePicker
inputRef={ref}
margin="dense"
fullWidth
id="date-picker-dialog"
label="Date of Birth"
format="yyyy-MM-dd"
KeyboardButtonProps={{
"aria-label": "change date",
}}
error={errors.date_of_birth ? true : false}
{...rest}
/>
)}
/>
</MuiPickersUtilsProvider>
With the in the react hook form i get date_of_birth in the format 2021-08-29T00:46:27.103Z but i want it to be 2021-08-29
HOw can i do this
Tried
import DateFnsUtils from "#date-io/date-fns";
const dateFns = new DateFnsUtils();
... in the onSubmit function
... example
date = dateFns.parseISO('2021-08-29T01:23:43.495Z')
... here i get error parseISO is not a function of dateFns
formated = dateFns.format(date,"yyyy-MM-dd")
How to use dateFns to format it to yyyy-MM-dd
As you can see in their document. Just use the format function.
https://date-fns.org/docs/Getting-Started
Updating my answer:
For date formatting purposes you may use date-fns or moment.js. #date-io is an abstraction of various date libraries like moment, date-fns, luxon, etc. In your case, you can directly use date-fns library and use their features.

How to show custom text (placeholder) in KeyboardDatePicker

I want to show "-select date-" placeHolder in datepicker if no date defined. Is that possible?
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
disablePast
/>
</MuiPickersUtilsProvider>
You can provide a placeholder in the form of the placeholder prop.
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
placeholder='-select date-'
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
disablePast
/>
</MuiPickersUtilsProvider>
Check out the example on the official documentation page for more info.
OK. the solution is to add labelFunc prop
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
labelFunc={() => selectedDate || '- Select date -'}
disablePast
/>
</MuiPickersUtilsProvider>
or even better (assuming default date value == null):
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
emptyLabel="- Select Date -"
disablePast
/>
</MuiPickersUtilsProvider>
Yes, you can. don't get overwhelmed with null value and stuffs, this is one of many appropriate option you can do.
Try this out:
//You need all of these imports (a must)
import DateFnsUtils from '#date-io/date-fns';
import Moment from 'moment';
import { MuiPickersUtilsProvider, KeyboardDatePicker } from "#material-ui/pickers";
//you need this too (a must)
const [selectDate, handleChangeSelectDate] = useState(null);
//Finally this is final thing you need
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
id="date-picker-inline"
autoOk
placeholder='-select date-'
inputStyle={{ textAlign: 'center' }}
variant="inline"
inputVariant="outlined"
format="MMM/dd/yyyy" //Can use MM if you want to show only number of month
value={selectDate? moment(selectDate) : null}
InputAdornmentProps={{ position: "start" }} //just use to put calendar icon on start or left position - remove it if you want it on end of the box or right hand side
onChange={date => handleChangeSelectDate(date)}
/>
</MuiPickersUtilsProvider>

Material Ui Datepicker is giving error: expected a string

I am trying to implement a Datepicker in my React Project using the Material UI's DatePicker. I initially tried to do what this site said. After that didn't work, I tried a simpler approach and tried what this site said. Both those approaches give this error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `AddScreen`.
My CodeSandbox link: https://codesandbox.io/s/testing-karmapact-app-bghgp?file=/App.js (Datepicker is implemented in /Screens/AddScreen.js)
There are two issues in your code:
Package is mismatch :
"#date-io/date-fns": "2.10.6",
"#material-ui/core": "latest",
"#material-ui/icons": "latest",
"#material-ui/pickers": "4.0.0-alpha.12"
Instead you need to use these:
"#date-io/date-fns": "v1",
"#material-ui/core": "latest",
"#material-ui/icons": "latest",
"#material-ui/pickers": "latest",
For using KeyboardTimePicker you also need to provide MuiPickersUtilsProvider which is not present .
Here is code for AddScreen
import "date-fns";
import React from "react";
import Grid from "#material-ui/core/Grid";
import DateFnsUtils from "#date-io/date-fns";
import {
MuiPickersUtilsProvider,
KeyboardTimePicker,
KeyboardDatePicker
} from "#material-ui/pickers";
export default function MaterialUIPickers() {
// The first commit of Material-UI
const [selectedDate, setSelectedDate] = React.useState(
new Date("2014-08-18T21:11:54")
);
const handleDateChange = (date) => {
setSelectedDate(date);
};
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<KeyboardDatePicker
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
"aria-label": "change date"
}}
/>
<KeyboardDatePicker
margin="normal"
id="date-picker-dialog"
label="Date picker dialog"
format="MM/dd/yyyy"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
"aria-label": "change date"
}}
/>
<KeyboardTimePicker
margin="normal"
id="time-picker"
label="Time picker"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
"aria-label": "change time"
}}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}
Here is working demo: https://codesandbox.io/s/mui-demo-forked-4gvbl?file=/Screens/AddScreen.js:0-946

How to solve this error Can not find utils in context

I am working on Materialui, here I am trying to display date and time but it is showing one error that is
Can not find utils in context. You either a) forgot to wrap your component tree in MuiPickersUtilsProvider; or b) mixed named and direct file imports. Recommendation: use named imports from the module index.
Please tell me how to solve this error
This is App.js
import React, { Fragment, useState } from "react";
import { DateTimePicker } from "#material-ui/pickers";
function BasicDateTimePicker() {
const [selectedDate, handleDateChange] = useState(new Date());
return (
<Fragment>
<DateTimePicker
label="DateTimePicker"
inputVariant="outlined"
value={selectedDate}
onChange={handleDateChange}
/>
<DateTimePicker
autoOk
ampm={false}
disableFuture
value={selectedDate}
onChange={handleDateChange}
label="24h clock"
/>
<DateTimePicker
value={selectedDate}
disablePast
onChange={handleDateChange}
label="With Today Button"
showTodayButton
/>
</Fragment>
);
}
export default BasicDateTimePicker;
Try wrapping it (like in the example: https://material-ui.com/components/pickers/):
import React, { Fragment, useState } from "react";
import DateFnsUtils from '#date-io/date-fns';
import { DateTimePicker, MuiPickersUtilsProvider } from "#material-ui/pickers";
function BasicDateTimePicker() {
const [selectedDate, handleDateChange] = useState(new Date());
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DateTimePicker
label="DateTimePicker"
inputVariant="outlined"
value={selectedDate}
onChange={handleDateChange}
/>
<DateTimePicker
autoOk
ampm={false}
disableFuture
value={selectedDate}
onChange={handleDateChange}
label="24h clock"
/>
<DateTimePicker
value={selectedDate}
disablePast
onChange={handleDateChange}
label="With Today Button"
showTodayButton
/>
</MuiPickersUtilsProvider>
);
}
export default BasicDateTimePicker;
If you are using IntelliJ IDEA 2020.2.3, then the following could help.
In my case, it was one of those stupid mistakes you can spend an hour or two to hunt down. So I copied and pasted the example from the official docs. I copied the component <MuiThemeProvider/> and then used the autocorrection feature of IntelliJ i.e Alt+Ener. So far, so good, see the screen:
I chose the first line as it seems that IDE correctly suggested the autocorrection. It inserts the following import at the header of the file:
import MuiPickersUtilsProvider from "#material-ui/pickers/MuiPickersUtilsProvider";
And it turns out that it's an incorrect version of using import for MuiThemeProvider. The correct version is:
import {MuiPickersUtilsProvider} from "#material-ui/pickers";
Be careful about using the autocomplete feature. Most of the time, it's working as you expect but not always, unfortunately. In this particular case, it's just better to ensure that all imports from the official example are the same as in your code.
I tried to solve the problem quite long. I forgot to wrap the DatePicker component with <LocalizationProvider dateAdapter={AdapterDateFns}>.
import AdapterDateFns from '#mui/lab/AdapterDateFns';
import LocalizationProvider from '#mui/lab/LocalizationProvider';
import DatePicker from '#mui/lab/DatePicker';
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
disableFuture
label="Responsive"
openTo="year"
views={['year', 'month', 'day']}
value={dateValue}
onChange={(newValue) => {
setDateValue(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
The above solution worked for me
I encountered the same error in a Lerna monorepo scenario. I made sure to use the correct imports, as the above answers suggested, but the error was still occurring.
The error occurred because:
I was using yarn workspaces
import { MuiPickersUtilsProvider } from "#material-ui/pickers"; was in a package
import { DateTimePicker} from "#material-ui/pickers"; was in a 3rd party library
hoisting happened to put the library package in root/node_modules and the "#material-ui/pickers" in root/packages/app/node_modules
=> The context that I set via MuiPickersUtilsProvider and the one looked up by the library was not really the same, hence the error.
Luckily, the fix is simple, just mark "#material-ui/pickers" and the red party packages as 'nohoist' in root/package.json:
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": [
"**/#material-ui/pickers**",
"**/the-3rd-part-library**"
]
},
Hopefully, this saves somebody the 10 hours I spent trying to fix this 😅
I was also using yarn workspaces where one of my packages in the workspace functioned as my component library to be used in my react app package. I simply had to make sure both these packages had the same date util version. In my case I am using #date-io/moment. Once I specified "#date-io/moment": "^1.3.13" in both packages this error was resolved.
Starting from 1900 when openTo is "year".
Version : #material-ui/pickers": "^3.3.10"
<DatePicker
disableFuture
openTo="year"
format="dd/MM/yyyy"
label="Date of birth"
views={["year", "month", "date"]}
value={selectedDate}
onChange={handleDateChange}
/>

Resources