Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pickers][DatePicker] DatePicker with different locale also changes the input value #14580

Open
brunomgurgel opened this issue Sep 11, 2024 · 12 comments
Labels
component: pickers This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it

Comments

@brunomgurgel
Copy link

brunomgurgel commented Sep 11, 2024

Steps to reproduce

Link to live example: https://codesandbox.io/s/mgtfx8?file=/src/Demo.tsx

Steps:

  1. Add a locale with a different date format than en-US

Current behavior

Currently the input value changes to the provided date format.

Expected behavior

I understand the current behavior and I see advantages on it sometimes. But I wish there was a possibility to just change the UI and the value always remains on the same format. Which makes it easier to parse the date on an API that knows nothing about the language and is always expecting on the en-US format.

Context

I want the UI to show the date in the format of the provided locale but I want the value to be always in one format (in my case en-US). Specially using server actions in Next.js we don't have controlled inputs, which means that what is sent to the server is the input value itself.

image

Your environment

No response

Search keywords: Date Picker, Localization

Search keywords:

@brunomgurgel brunomgurgel added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Sep 11, 2024
@zannager zannager transferred this issue from mui/material-ui Sep 11, 2024
@zannager zannager added the component: pickers This is the name of the generic UI component, not the React module! label Sep 11, 2024
@michelengelen
Copy link
Member

Hey @brunomgurgel
I don't get what you are trying to achieve. Is it a standardized format in which you send and receive the value without affecting the UI?

You can do that very simply by using the value

import * as React from "react";
import dayjs from "dayjs";
import "dayjs/locale/de";
import "dayjs/locale/en-gb";
import "dayjs/locale/zh-cn";
import Stack from "@mui/material/Stack";
import ToggleButton from "@mui/material/ToggleButton";
import ToggleButtonGroup from "@mui/material/ToggleButtonGroup";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import { DateField } from "@mui/x-date-pickers/DateField";
import { TimeField } from "@mui/x-date-pickers/TimeField";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";

const locales = ["en", "en-gb", "zh-cn", "de"];

type LocaleKey = (typeof locales)[number];

export default function LocalizationDayjs() {
  const [locale, setLocale] = React.useState<LocaleKey>("en");
  const [date, setDate] = React.useState(dayjs("2022-04-17"));

  console.log("date", date.toISOString());

  return (
    <LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale={locale}>
      <Stack spacing={3} sx={{ width: 300 }}>
        <ToggleButtonGroup
          value={locale}
          exclusive
          fullWidth
          onChange={(event, newLocale) => {
            if (newLocale != null) {
              setLocale(newLocale);
            }
          }}
        >
          {locales.map((localeItem) => (
            <ToggleButton key={localeItem} value={localeItem}>
              {localeItem}
            </ToggleButton>
          ))}
        </ToggleButtonGroup>
        <DateField label="Date" value={date} />
        <TimeField label="Time" value={date} />
      </Stack>
    </LocalizationProvider>
  );
}

In CSB: DEMO

toISOString() will convert the current value to a machine-readable standardized string that can be used to store to and receive from a backend.

@michelengelen michelengelen changed the title [DatePicker] DatePicker with different locale also changes the input value [pickers][DatePicker] DatePicker with different locale also changes the input value Sep 11, 2024
@michelengelen michelengelen added status: waiting for author Issue with insufficient information status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Sep 11, 2024
@brunomgurgel
Copy link
Author

Hey @michelengelen , thank you for the fast response!

I'm trying to achieve something similar to what you're saying, but there are some differences.

I'm using Server Actions, which means that I don't send the form with an onSubmit on the form component. Instead it uses the native HTML form submission, just getting the value from the date picker.

Which means that if my language is de for example, it will send a date as 11/09/2024, but when the API (that knows nothing about locale) parses this date, it interprets as 9 of november, instead of 11 of september.

What I want to know is if I can change the value to be on an ISO format or on a standardized format (in my case the en-US format).

Below is how my input value gets rendered when using de as the locale adapter

image

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Sep 11, 2024
@michelengelen
Copy link
Member

This is a bit tricky. Could you provide us with a minimal reproduction repository we can execute and play around with?

I would honestly love to test it and possibly add a section about this in the docs if possible!

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Sep 11, 2024
@brunomgurgel
Copy link
Author

I created a minimal repro in my personal github

When you submit the form you will see on the server logs and on the screen the resulting value, and if you change the language you will see the value changes.

I added the workaround I'm currently doing, but I don't feel is the best option.

Thank you again for the support!

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Sep 11, 2024
@flaviendelangle
Copy link
Member

flaviendelangle commented Sep 12, 2024

@brunomgurgel I'm interested to discuss a bit with you about server actions and how they are used in the Date and Time Pickers.

We currently have 2 DOM structure, the old one with a <input /> and the new one that uses several contentEditable spans (for accessibility reason).
In the next major, the new structure will become the default one and we will deprecate the old one.
To be compatible with server actions, we kept a hidden <input /> DOM element that for now contains the formatted date (just like the old structure have it). Would your problem be solved if the value stored in the hidden <input /> was a fixed format (probably the ISO one) instead of the formatted value?

You would then have:

  • the UI displays whatever format the user wants in his locale (using the contentEditable spans)
  • the hidden <input /> for form submission with a reliable value that is easy to parse even if the displayed value is more exotic

You can find the doc about the new structure here and play with it by adding enableAccessibleFieldDOMStructure to any picker of field component.

@brunomgurgel
Copy link
Author

That would work great! And those are exciting news. Thank you a lot! I will play around with this new structure

@michelengelen
Copy link
Member

side note: useFormState got deprecated and replaced with a new hook useActionState

@michelengelen
Copy link
Member

Another side note: even in the official useActionState documentation they use hidden inputs as helpers for the formState, so IMHO something like this:

<DatePicker
  label="Start Date"
  value={formState.startDate}
  onChange={(date) => setFormState({ ...formState, startDate: date })}
  name="startDate"
  slotProps={{
    textField: {
      required: true,
    },
  }}
/>

<input
  type="hidden"
  name="startDate"
  value={formState.startDate?.toISOString()}
/>

is a perfectly viable workaround for now.

@flaviendelangle Should we keep this open as a feature request to apply the ISO value to the hidden field?

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Sep 12, 2024
@brunomgurgel
Copy link
Author

Yep, I agree! For now we will doing this workaround and I will keep an eye on this update

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Sep 12, 2024
@michelengelen michelengelen added enhancement This is not a bug, nor a new feature and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Sep 12, 2024
@michelengelen
Copy link
Member

Yep, I agree! For now we will doing this workaround and I will keep an eye on this update

Great to see that we have a solution, even if it is just a workaround for now. I did add this to the board so that the team can discuss this in the grooming session.

Thanks for your patience and cooperation on this @brunomgurgel 🙇🏼

@brunomgurgel
Copy link
Author

Thank you guys for all the help and fast response! I love your product and you're doing an awesome job!

@flaviendelangle
Copy link
Member

@flaviendelangle Should we keep this open as a feature request to apply the ISO value to the hidden field?

I would create a dedicated issue clearly focused around server actions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: pickers This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it
Projects
None yet
Development

No branches or pull requests

4 participants