7

I am working on Blazor project based on latest Core 3.1.

The UI Culture show correctly dates and numbers as seen the in the image.

But the moment I used the EditForm the number and date is not formatted as it should be.

So this code part of EditForm

<InputDate id="date" class="form-control" @bind-Value="@TaskObject.Date" />

So in EditForm it looks like this, which is not correct culture format:

enter image description here

But in the UI looks like this, which is OK:

enter image description here

As I new in Blazor, I have tried to read different stuff online to get some knowledge regarding this issue.

So I have tired following:

without luck.

Then I tried to read this and found this which is not working with Core 3.1.

My question, what should exactly be done to make EditForm show date and number like the of UI, and Why this happen for EditForm?

Maytham Fahmi
  • 31,138
  • 14
  • 118
  • 137
  • 1. The built-in `InputDate`/`InputNumber` is designed as a **`Culture-Invariant`** component. See [source code](https://github.com/aspnet/AspNetCore/blob/8c02467b4a218df3b1b0a69bceb50f5b64f482b1/src/Components/Web/src/Forms/InputDate.cs#L99). 2. And according to [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date#Value): *The displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd.*. 3. See also [this thread](https://stackoverflow.com/questions/7372038/is-there-any-way-to-change-input-type-date-format) – itminus Dec 30 '19 at 07:32
  • @itminus that is helpful, thx, so to summarize, I guess there is no standard way or solution to customize/manipulate date object? – Maytham Fahmi Dec 30 '19 at 08:56
  • Yes. I believe there's no standard way to do that. Even we could create a custom `InputDate` implementation, we still need some js/css to display the format according to current CultureInfo. – itminus Dec 30 '19 at 09:00
  • ok, so I need to develop a customize model in javascript/css and invoke it in blazor to make it work i guess, ok if you formulate all this comments in an answer I will accept it for now. – Maytham Fahmi Dec 30 '19 at 09:06

3 Answers3

5

Why this happen for EditForm

The built-in InputDate/InputNumber is designed as Culture-Invariant components. See source code of InputDate and InputNumber.

What should exactly be done to make EditForm show date and number like the of UI,

I thought we can create a custom InputDate<TValue> implementation. However, I was wrong. According to MDN:

The displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd..

Even we get a custom InputDate<TValue>implementation that honors the current CultureInfo, we still need some js/css to display the correct format. IMO, there's no standard way to implement this. See also this thread on SO.

itminus
  • 23,772
  • 2
  • 53
  • 88
2

This is not a Blazor issue but rather the behaviour of the HTML <input> element of type="date".

The required format for type="date" is "yyyy-MM-dd" which the Blazor component uses. Any other format is not valid.

If we do a little test, we can verify it is not a Blazor issue.

@page "/dates"
@using System.Globalization
<h3>Date</h3>
<p>@_dateString</p>
<input type="date" value="@_dateString" />
@code {
    private string _dateString;

    protected override void OnInitialized()
    {
        // using en-US culture
        // this is what InputDate component does
        _dateString = DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
    }
}

_dateString outputs 2019-12-30 but the date shown in the <input> is 30/12/2019

Detailed information on type=date can be found here. In the Value section there is a note which says the following:

The displayed date format will differ from the actual value — the displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd.

So the formatting is fixed to the locale of the users browser.

Colin Bacon
  • 15,436
  • 7
  • 52
  • 72
0

I suggest using this component https://blazorrepl.com/repl/wbambCPv20P0pX1h21

EDIT: Here is the code if the link does not work:

<style>
    #myInput[type="date"] {
        margin-top: 3px;
        border: 0;
        position: absolute;
        width: 24px;
        height: 24px;
    }

        #myInput[type="date"]::-webkit-inner-spin-button {
            display: none;
        }

        #myInput[type="date"]::-webkit-calendar-picker-indicator {
            margin: 0;
            position: absolute;
        }

    #myInput[type=date]::-webkit-datetime-edit,
    #myInput[type=date]::-webkit-datetime-edit-fields-wrapper {
        -webkit-appearance: none;
        display: none;
        margin: 0;
        padding: 0;
    }
</style>
<input value="@this.Value.ToString(this.Format)" @onchange="this.DateChangedAsync" class="@Class" style="display:inline-block;margin-right: -38px;" />
<input id="myInput" type="date" value="@Value" @onchange="this.DateChangedAsync" style="display:inline-block; " />

@code {
    [Parameter]
        public string Format { get; set; }

        [Parameter]
        public DateTime Value { get; set; }

        [Parameter]
        public EventCallback<DateTime> ValueChanged { get; set; }

        [Parameter]
        public string Class { get; set; }

        protected override void OnParametersSet()
        {
            if (string.IsNullOrWhiteSpace(Format))
            {
                this.Format = "dd/MM/yyyy";
            }
        }

        private async Task DateChangedAsync(ChangeEventArgs args)
        {
            string text = args.Value.ToString();

            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            this.Value = DateTime.Parse(text);
            await this.ValueChanged.InvokeAsync(this.Value);
        }
}
  • 1
    Welcome to Stack Overflow! While your answer may solve the question, [including an explanation](https://meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. You can edit your answer to add explanations and give an indication of what limitations and assumptions apply. - [From Review](https://stackoverflow.com/review/late-answers/28329211) – Adam Marshall Feb 15 '21 at 16:31