How to customize the Material UI Date Range Picker - datepicker

I am using MobileDateRangePicker from "#material-ui/lab/MobileDateRangePicker". I am trying to customize it according to my needs. What I am looking for is
When the MobileDateRangePicker opens I need text input view to show first and after that when I click on calendar icon calendar view needs to come. But right now complete opposite is happening. How can I get my requirement.
This is the complete code. Any assistance would be really helpful to me. Thank you.
import * as React from "react";
import TextField from "#material-ui/core/TextField";
import AdapterDateFns from "#material-ui/lab/AdapterDateFns";
import LocalizationProvider from "#material-ui/lab/LocalizationProvider";
import Box from "#material-ui/core/Box";
import Stack from "#material-ui/core/Stack";
import MobileDateRangePicker from "#material-ui/lab/MobileDateRangePicker";
import { Button } from "#material-ui/core";
export default function ResponsiveDateRangePicker() {
const [value, setValue] = React.useState([null, null]);
const [openPicker, setOPenPicker] = React.useState(false);
const handleClick = () => {
setOPenPicker(!openPicker);
};
return (
<div>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Stack spacing={3}>
<MobileDateRangePicker
startText="Start date"
endText="End date"
disableMaskedInput={true}
// open={openPicker}
// disableOpenPicker={true}
showDaysOutsideCurrentMonth={true}
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
toolbarTitle="custom date range"
renderInput={(startProps, endProps) => (
<React.Fragment>
<TextField {...startProps} />
<Box sx={{ mx: 2 }}> to </Box>
<TextField {...endProps} />
</React.Fragment>
)}
/>
</Stack>
</LocalizationProvider>
</div>
);
}
sandbox link: https://codesandbox.io/s/responsivedaterangepicker-material-demo-forked-8qws4?file=/demo.js

Related

material-ui: why is the code running twice?

can someone explain to me why the following code is executed twice? (See image)
import * as React from 'react';
import Container from '#mui/material/Container';
import Typography from '#mui/material/Typography';
import Box from '#mui/material/Box';
import raw from "./testfile.csv";
function ReadFile(file) {
fetch(raw)
.then(r => r.text())
.then(text => {
console.log('text decoded:', text);
});
}
export default function App() {
return (
<Container maxWidth="sm">
<Box sx={{ my: 4 }}>
<Typography variant="h4" component="h1" gutterBottom>
Create React App example
</Typography>
<ReadFile />
</Box>
</Container>
);
}
executed twice
I don't understand why the code is executed 2x by the browser
Do you have <React.StrictMode> in index.js? It already happened to me that my code executed twice because of that.

Material Ui DatePicker always get invalid date when type with keyboard

I was trying to use mui-x/datepicker with a buddhist year using dayjs as the adapter, when I use the calendar popup as the input it works fine , but when I type the date using keyboard and change the year to less than or greather than '2565' in the textfeild I always get 'Invalid date'.
Here my code
import { useState } from "react";
import { LocalizationProvider } from "#mui/x-date-pickers";
import { AdapterDayjs } from "#mui/x-date-pickers/AdapterDayjs";
import { DatePicker } from "#mui/x-date-pickers/DatePicker";
import { TextField } from "#mui/material";
import dayjs from "dayjs";
import buddhistEra from "dayjs/plugin/buddhistEra";
import "dayjs/locale/th";
dayjs.locale("th");
dayjs.extend(buddhistEra);
const dateformats = const dateformats = {
year: "BBBB",
monthAndYear: "MMMM BBBB",
keyboardDate: "DD/MM/BBBB"
};
export default function App() {
const [protectionPrdFrom, setProtectionPrdFrom] = useState(dayjs());
return (
<div className="App">
<h3>{protectionPrdFrom ? protectionPrdFrom.toString() : ""}</h3>
<LocalizationProvider
dateFormats={dateformats}
dateAdapter={AdapterDayjs}
adapterLocale="th"
>
<DatePicker
showToolbar
maxDate={dayjs(new Date(3000, 12, 31))}
minDate={dayjs(new Date(1990, 1, 1))}
inputFormat="DD/MM/BBBB"
views={["year", "month", "day"]}
value={protectionPrdFrom}
onChange={(date, keyboardDate) => {
setProtectionPrdFrom(date);
}}
renderInput={(params) => (
<TextField {...params} size="small" fullWidth />
)}
/>
</LocalizationProvider>
</div>
);
}
Here the link for my demo My Mui Datepicker
i think Adapter from mui is not support for input from keyboard input, i guess.
So you can try this external lib for buddhist year .
https://github.com/tarzui/date-fns-be
^ ^

material text field label not copyable?

I am using MUI's Text Field component and found there's literally no way to copy the label contents. Is there a way to copy the label somehow?
See the demo here: https://codesandbox.io/s/4ou0l7?file=/demo.tsx
Thanks
It is because material UI is disabling the label selection using CSS.
You can enable it back in a few ways. You can enable it for a certain field or across all of them using the material UI theme override ability.
In order to enable label selection only to one field, you have pass an additional prop to your TextField: InputLabelProps={{ sx: { userSelect: "text" } }}
And here I have provided you with the second way to do that for all the text fields:
import * as React from "react";
import Box from "#mui/material/Box";
import TextField from "#mui/material/TextField";
import { createTheme, ThemeProvider } from "#mui/material/styles";
const theme = createTheme({
components: {
MuiInputLabel: {
styleOverrides: {
root: {
userSelect: "text"
}
}
}
}
});
const StateTextFields = () => {
const [name, setName] = React.useState("Cat in the Hat");
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setName(event.target.value);
};
return (
<Box
component="form"
sx={{
"& > :not(style)": { m: 1, width: "25ch" }
}}
noValidate
autoComplete="off"
>
<TextField
id="outlined-name"
label="Name"
value={name}
onChange={handleChange}
/>
<TextField
id="outlined-uncontrolled"
label="Uncontrolled"
defaultValue="foo"
/>
</Box>
);
};
export default () => (
<ThemeProvider theme={theme}>
<StateTextFields />
</ThemeProvider>
);
Of course, you can extract this ThemeProvider into a separate file and wrap with it the whole project, not only this file. It is combined just for the example.
I found a way that this can be done using the helperText and my solution is more of a hack. I am using the helperText and positioning it where the label was used to be, giving it a background and bringing it to front using z-index.
Also you can either choose to use the label or replace it with the placeholder depending if you are happy with the animation.
Here is a codesandbox based on your code in case you need it.
<TextField
id="outlined-name"
label="Name"
// placeholder="Name"
value={name}
onChange={handleChange}
helperText="Name"
sx={{
"& .MuiFormHelperText-root": {
top: "-11px",
position: "absolute",
zIndex: "1",
background: "white",
padding: "0 4px",
}
}}
/>

I have React Hook Form With Controller With Yup as validataro The Material UI Select stays red after selecting something and won't go away

I got TextField to work, now the Material UI Select will turn red if no selection is made but stays red after selection is made and won't let form submit. I'm using Yup as validation library.Maybe I keep using wrong Yup type I try String and array but I can't get it to work.
import {
makeStyles,
Box,
Select,
FormControl,
InputLabel,
MenuItem,
Typography,
} from "#material-ui/core";
import * as yup from 'yup';
import { yupResolver } from '#hookform/resolvers'
import { useForm, Controller } from "react-hook-form";
const FormFields = ({ typeOfInquiry, typeOfProviderSupplier, feedbackform }) => {
const schema = yup.object().shape({
typeofInquiry: yup.array().nullable().required(),
});
const { handleSubmit, control, reset, errors } = useForm();
return (
<Controller
style={{ minWidth: 220 }}
name="typeofInquiry"
render ={({ field: { ...field }, fieldState })=>{
console.log(props)
return ( <Select {...field} >
{typeOfInquiry.map((person) => (
<MenuItem key={person.value} value={person.value} >
{person.label}
</MenuItem>
))}
</Select>
)
}}
control={control}
defaultValue=" "
/>
<Typography className={classes.red}>{errors.typeofInquiry?.message}</Typography>
</FormControl>
</form>
);
}
You've to pass the ref to the TextField component.
Here is a working example
👉🏻 https://codesandbox.io/s/exciting-pateu-3n0i9
You should do something similar with Select.
Some examples with MUI: https://codesandbox.io/s/react-hook-form-v7-controller-5h1q5?file=/src/Mui.js

Material UI filled input for KeyboardDatePicker

I know that with an InputField one is able to pass down the variant="filled" prop to get input box filled. However, is it also possible to pass down a prop with the similar effect using a Material UI date picker (not using the native datepicker from the browser)?
Example of filled input:
I think you are looking for inputVariant={"filled"} prop
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
inputVariant={"filled"}
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"
}}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}
Working sandbox project link
The #material-ui/pickers has been moved to the #mui/lab.
Checkout the migration guide Here !
Below is a sample code to implement the same
import React from "react";
import TextField from "#mui/material/TextField";
import AdapterDateFns from "#mui/lab/AdapterDateFns";
import LocalizationProvider from "#mui/lab/LocalizationProvider";
import DatePicker from "#mui/lab/DatePicker";
export default function filledDatePicker() {
const [selectedDate, setSelectedDate] = React.useState(new Date());
const handleDateChange = date => {
setSelectedDate(date);
};
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
value={selectedDate}
onChange={handleDateChange}
renderInput={(props) => (
<TextField {...props} variant="filled" label="Select Date" />
)}
/>
</LocalizationProvider>
);
}