7
votes

Since Blazor doesn't support stopping event propagation I need one-way binding for an input element with type="date" and with an onchange event handler.

Something like this:

<input type="date" value="@_endDate" format-value="yyyy-MM-dd" onchange="@EndDate_change"/>

But this doesn't work. The page contains datePicker but without any value.

"_endDate" is of type DateTime.

If I use Two-way binding then everything working fine.

<input type="date" bind="@_endDate" format-value="yyyy-MM-dd"/>

Any idea why the first "input" doesn't work? Is there any mistake or is this a bug in blazor? For plain text one-way binding with onchange event works without problems.

Edit1: _endDate contains the current date and is set as DateTime.Now

protected void EndDate_change(UIChangeEventArgs endDateEvent)
{
    _endDate = Convert.ToDateTime(endDateEvent.Value);
    StateHasChanged();
}
4
How do you set _endDate and what does EndDate_change do? If you check the docs binding is equivalent to setting the new value in the change event. You still have to set _endDate to something if you want it to be displayed - Panagiotis Kanavos
Please look at Edit1. I added it to question. - lukesss
I can't repro this. The date shows (Chrome, Firefox, edge) but the event is not triggered from a date input. Latest Blazor, clientside. - Henk Holterman
Are you trying to change date value from javascript (datePicker) ? Then, maybe, you should to need interop - dani herrera

4 Answers

3
votes

To keep both @onchange= and a one way value= use this

value="@someDate.ToString("yyyy-MM-dd")"

The trick is to format as a string yyyy-MM-dd to get one way binding from the value. Formatting differently or simply using the DateTime object fails to show the date inside the date selector.

Example:

<input type="date" value="@knowledge.ActualShortTermDate.ToString("yyyy-MM-dd")" @onchange="@(async (e) => await updateDate(DateTime.Parse(e.Value.ToString())))" />

2
votes

Since in blazor @bind-Value and @onchange cannot co exists as at now here is the best work around

<InputDate type="date" @bind-Value="@_endDate"/>
@code {
 private DateTime endDate;
public DateTime _endDate
{
    get { return endDate; }
    set
    {
        endDate = value;
        //Do Other tasks ......
        // Eg updateSomething();
    }
}
}
0
votes

both Prevent default actions for events and Stop event propagation are supported in Blazor apps since .NET Core 3.1 Preview 2 check thisd link here

0
votes

Try using @bind-Value instead of just @bind, it works for me

        <div class="col-4 border border-primary border-0 text-left">
            <InputDate id="expenseedate" class="form-control form-control-sm col-4" format-value="yyyy-MM-dd" @bind-Value="@_endDate" @oninput="@ResetError" placeholder="Enter Expense end Date"></InputDate>
        </div>