onChange (single mode)
The difference between onChange in this package and others is that type of its argument is sent as DateObject instead of Date.
You can easily convert it to Date with the toDate() method.
import { useState } from "react"
import DatePicker from "react-multi-date-picker"
export default function Example() {
const [value, setValue] = useState()
return (
<>
<DatePicker
value={value}
onChange={setValue}
/>
{value?.toDate?.().toString()}
</>
)
}
onChange (Converting Selected Date To All Calendars)
//gregorian calendar & locale
import gregorian from "react-date-object/calendars/gregorian";
import gregorian_en from "react-date-object/locales/gregorian_en";
//persian calendar & locale
import persian from "react-date-object/calendars/persian";
import persian_en from "react-date-object/locales/persian_en";
//arabic calendar & locale
import arabic from "react-date-object/calendars/arabic";
import arabic_en from "react-date-object/locales/arabic_en";
//indian calendar & locale
import indian from "react-date-object/calendars/indian";
import indian_en from "react-date-object/locales/indian_en";
.
.
.
const [state, setState] = useState({ format: "MM/DD/YYYY" })
const convert = (date, format = state.format) => {
let object = { date, format }
setState({
gregorian: new DateObject(object).format(),
persian: new DateObject(object).convert(persian, persian_en).format(),
arabic: new DateObject(object).convert(arabic, arabic_en).format(),
indian: new DateObject(object).convert(indian, indian_en).format(),
jsDate: date.toDate(),
...object
})
}
const Span = ({ children }) => <span style={{ fontWeight: "bold" }}>{children}</span>
return(
<div>
<div>
<div>
<Span>click to select: </Span>
<DatePicker
value={state.date}
onChange={convert}
/>
</div>
<div>
<Span>format: </Span>
<select
value={state.format}
onChange={e => convert(state.date, e.target.value)}
className="select"
>
<option>MM/DD/YYYY</option>
<option>DD-MM-YYYY</option>
<option>YYYY,MM,DD</option>
<option>dddd DD MMMM YYYY</option>
<option>ddd MMM DD YYYY HH:mm:ss</option>
<option>MMM/DD/YYYY hh:mm:ss a</option>
<option>MMM/DD/YYYY HH:mm:ss</option>
</select>
</div>
<div>
<Span>gregorian: </Span>
<span>{state.gregorian}</span>
</div>
<div>
<Span>solar hijri: </Span>
<span>{state.persian}</span>
</div>
<div>
<Span>islamic hijri: </Span>
<span>{state.arabic}</span>
</div>
<div>
<Span>indian: </Span>
<span>{state.indian}</span>
</div>
<div>
<Span>javascript date: </Span>
<span>{state.jsDate?.toString?.()}</span>
</div>
</div>
</div>
)
onChange (multiple mode)
<DatePicker
multiple
onChange={array => { //Array of Dateobjecs
alert("selected dates :\n" + array.join(",\n"))
}}
/>
OnOpen
If you have a specific condition for opening or closing the calendar, you can use onOpen and onClose events.
If you return false in onOpen, the calendar will not open. Also, if you return false in onClose, the calendar will not close.
const [shouldOpenCalendar, setShouldOpenCalendar] = useState(false)
.
.
.
<div>
<DatePicker
onOpen={() => shouldOpenCalendar}
/>
<label>
<input
type="checkbox"
checked={shouldOpenCalendar}
onChange={() => setShouldOpenCalendar(!shouldOpenCalendar)}
/>
Should open calendar
</label>
</div>
OnClose
const [shouldCloseCalendar, setShouldCloseCalendar] = useState(false)
.
.
.
<div>
<DatePicker
onClose={() => shouldCloseCalendar}
/>
<label>
<input
type="checkbox"
checked={shouldCloseCalendar}
onChange={() => setShouldCloseCalendar(!shouldCloseCalendar)}
/>
Should close calendar
</label>
</div>
onPositionChange
Each time the popper(calendar) position is recalculated, the onChange function is executed in the element-popper.
Because onChange does something else in datepicker, I changed its name to onPositionChange here.
The function you enter in onPositionChange is executed when scrolling, resizing, opening the calendar, or when you call refreshPosition from datepicker ref.
In the onPositionChange function, an object is sent as an argument containing the calculated popper(calendar) and arrow positions, as well as scrollable date picker parent elements.
In this example, the mentioned object is logged in the console and you can view it by opening your browser console (Ctrl + Shift + i, in Chrome browser).
<DatePicker
onPositionChange={data => console.log(data)}
/>
onPropsChange
This feature is suitable for plugins.
Because for some of them, setting the DatePicker props (parent component) from the plugins (child component) is inevitable.
const [props, setProps] = useState({
value: new Date(),
format: "MM-DD-YYYY",
onChange: (date) => console.log(date.format()),
});
.
.
.
<DatePicker
{...props}
onPropsChange={setProps}
/>
onMonthChange
In this example, setting the currentDate property is optional.
The currentDate property is set to open the calendar in the same selected month.
import React, { useState } from "react";
import DatePicker, { DateObject } from "react-multi-date-picker";
export default function Example() {
const [dateObject, setDateObject] = useState(
new DateObject()
);
return (
<>
<DatePicker
onMonthChange={(date) => setDateObject(new DateObject(date))}
onChange={(date) => setDateObject(new DateObject(date))}
currentDate={dateObject}
/>
<p>Selected Month: {dateObject.month.name}</p>
</>
)
}
Selected Month: June
onYearChange
like the onMonthChange, a date with the type of DateObject is sent as an argument in onYearChange function.
For example you can use the onYearChange and onMonthChange Props, if you want to implement a DatePicker in which the month and year of the user-selected date changes by changing the month and year of the calendar.
import React, { useState } from "react";
import DatePicker, { DateObject } from "react-multi-date-picker";
export default function Example() {
const [value, setValue] = useState();
return (
<DatePicker
value={value}
onChange={setValue}
onYearChange={updateValue}
onMonthChange={updateValue}
/>
)
function updateValue({ year, month }) {
setValue(
new DateObject(value).set({
day: value.day > month.length ? month.length : value.day,
month,
year,
})
);
}
}
onFocusedDateChange
The onFocusedDateChange property receives a function and calls it with two arguments (the first argument is dateFocused, and the second argument is dateClicked), which can be called by the Calendar itself or any of the plugins.
The difference between when onFocusedDateChange is called by the Calendar itself and when it is called by one of the plugins is that in the first case the second argument (ie dateClicked) is always present, and in the second case the second argument is always undefined.
The onFocusedDateChange property actually specifies two things.
Which date is currently focused.
Which date is currently clicked.
The nature of the two is different from each other and is sent as two arguments to the listener you have specified.
There are a few things to keep in mind about this property.
Both of these arguments may have the same type (either DateObject or undefined)
One of them may be DateObject and the other may be undefined.
Here I will describe the different conditions:
Single & Range Modes:
Both arguments have the same type (DateObject).
This means that the date focused is the same as the date clicked.
Multiple Mode:
As long as the user is selecting new dates, both arguments have the same type (DateObject).
This means that the date focused is the same as the date clicked.
But as soon as the user clicks on the date that already selected, The selected date is deleted and one of the following cases may occur:
the date that is deleted is the same as the focused date, in which case the first argument (ie dateFocused) is undefined and the second argument (ie dateClicked) is the clicked date.
the deleted date is not the same as the focused date, in which case the first argument is the previous focused date, and the second argument is the current deleted date.
DatePanel:
As a plugin, the second argument is always undefined.
Clicking on any dates displayed on the DatePanel, will focus that date, so if you click on any date of DatePanel, the first argument (ie dateFocused) will be the same as the clicked date.
If the user deletes an unfocused date through the dates panel, the first argument is the same as the previous focused date.
If the user deletes a focused date through the dates panel, the first argument is also undefined.
import React, { useState } from "react";
import DatePicker from "react-multi-date-picker";
import DatePanel from "react-multi-date-picker/plugins/date_panel";
.
.
.
const [state, setState] = useState({});
.
.
.
<>
<DatePicker
multiple
onFocusedDateChange={(dateFocused, dateClicked) => {
setState({ dateFocused, dateClicked });
}}
onClose={() => setState({})}
plugins={[<DatePanel markFocused />]}
/>
<div>
<p>
<b>Date focused:</b> {state.dateFocused?.format?.()}
</p>
<p>
<b>Date clicked:</b> {state.dateClicked?.format?.()}
</p>
</div>
</>
Date focused:
Date clicked: