Reputation: 1842
I'm trying to force the date selected in a date input to the Sunday of the week of the date actually selected by the user. So if they pick Wednesday, it will actually change to the Sunday of the same week.
I've managed to do this but when I reselect a date in the same week again it doesn't work. As an example, when the user selects Wednesday, it successfully selects Sunday. But then when they go and select Tuesday instead, it keeps the displayed value as Tuesday instead of changing it to Sunday (which is what I'd want it to do)
Here's some example code
<input type="date" value="@overrideStart.ToString("yyyy-MM-dd")" @onchange="@SelectStartOfWeek" />
@code {
private DateTime overrideStart = DateTime.Today;
protected override async Task OnInitializedAsync()
{
overrideStart = GetStartOfWeek(overrideStart)
}
public async Task SelectStartOfWeek(ChangeEventArgs args)
{
var value = args.Value.ToString();
overrideStart = value == string.Empty ? DateTime.Today : DateTime.Parse(value);
overrideStart = await GetStartOfWeek(overrideStart);
}
private async Task<DateTime> GetStartOfWeek(DateTime date)
{
return date.AddDays(-(int)date.DayOfWeek);
}
}
Obviously the issue is because it recognizes that overrideStart
ends up with the same value after SelectStartOfWeek
finishes. I've tried StateHasChanged()
but it doesn't seem to have any effect.
Upvotes: 4
Views: 7161
Reputation: 30036
Another approach using the setter on a property. This works standalone and the EditForm
context.
@page "/MyDate"
<h3>MyDate Editor</h3>
<EditForm EditContext="editContext">
<InputDate @bind-Value="model.MyDate"></InputDate>
</EditForm>
<input type="date" @bind-value="this.MyDate" />
@code {
private dataModel model { get; set; } = new dataModel();
private EditContext editContext;
protected override Task OnInitializedAsync()
{
this.editContext = new EditContext(model);
return base.OnInitializedAsync();
}
public class dataModel
{
public DateTime? MyDate
{
get => _myDate;
set
{
if (value != null)
{
var date = (DateTime)value;
_myDate = date.AddDays(-(int)date.DayOfWeek);
}
}
}
private DateTime? _myDate;
}
public DateTime? MyDate
{
get => _myDate;
set
{
if (value != null)
{
var date = (DateTime)value;
_myDate = date.AddDays(-(int)date.DayOfWeek);
}
}
}
private DateTime? _myDate;
}
Upvotes: 4
Reputation: 8964
You have correctly identified the issue, but I think there are only hacky ways of avoiding this optimisation.
One such way is to change something else on the element, like a @key
which will force Blazor to replace the entire element.
<input
@key="@toggle"
type="date"
value="@overrideStart.ToString("yyyy-MM-dd")"
@onchange="@SelectStartOfWeek" />
@code {
bool toggle;
private DateTime overrideStart = DateTime.Today;
protected override async Task OnInitializedAsync()
{
overrideStart = await GetStartOfWeek(overrideStart);
}
public async Task SelectStartOfWeek(ChangeEventArgs args)
{
var value = args.Value.ToString();
overrideStart = value == string.Empty ? DateTime.Today : DateTime.Parse(value);
overrideStart = await GetStartOfWeek(overrideStart);
toggle = !toggle;
}
private ValueTask<DateTime> GetStartOfWeek(DateTime date)
{
return ValueTask.FromResult(date.AddDays(-(int)date.DayOfWeek));
}
}
Upvotes: 2