Reputation: 45
I am trying to create a simple lunch scheme webapp, where you can sign up for any business day of the week. I want the user to be able to select each day individually or select a whole week.
What I thought would be a simple method call/check is proving to be seemingly impossible in a Blazor razorpage. I want a checkbox for the whole week, which checks or unchecks all the checkboxes for each individual day. This is pretty straightforward and works as expected. But if I uncheck any of the days, I want the week checkbox to get unchecked as well.
This is what the relevant part of my page looks like:
@foreach (var item in weeks)
{
<tr>
<td><input type="checkbox" @onchange="eventArgs => SetAllWeekDays(item.Key, eventArgs.Value)" /> @item.Value.WeekNumber</td>
<td>
<input type="checkbox" @bind="item.Value.WeekDays[0].IsSignedUp" />
</td>
<td>
<input type="checkbox" @bind="item.Value.WeekDays[1].IsSignedUp" />
</td>
<td>
<input type="checkbox" @bind="item.Value.WeekDays[2].IsSignedUp" />
</td>
<td>
<input type="checkbox" @bind="item.Value.WeekDays[3].IsSignedUp" />
</td>
<td>
<input type="checkbox" @bind="item.Value.WeekDays[4].IsSignedUp" />
</td>
</tr>
}
And this is the SetAllWeekDays method:
private void SetAllWeekDays(int weekNumber, object checkedValue)
{
if ((bool)checkedValue)
{
for (int i = 0; i < weeks[weekNumber].WeekDays.Count; i++)
{
weeks[weekNumber].WeekDays[i].IsSignedUp = true;
}
}
else
{
for (int i = 0; i < weeks[weekNumber].WeekDays.Count; i++)
{
weeks[weekNumber].WeekDays[i].IsSignedUp = false;
}
}
}
When I check or uncheck the week, it checks or unchecks all the days, but if I check or uncheck any of the days individually, the checkbox for the week stays unchanged
I feel like I'm missing some obvious way of databinding a method call to the value of the whole week, as you can't both bind a value and set an @onchange event.
Upvotes: 2
Views: 2630
Reputation: 45626
Here's a working code sample how to do that... copy and test:
Note that @bind
is equivalent to the checked
attribute and the @onchange
directive, and how I make use of both
@page "/LunchScheme"
@using System;
<table class="table">
<thead>
<tr>
<td>Week</td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
</tr>
</thead>
<tbody>
@foreach(var week in weeks)
{
<tr>
<td>
<input type="checkbox" checked="@week.Selected" @onchange="@((args) => { week.Selected = (bool)
args.Value; Check(week); } )" />
</td>
@foreach(var day in week.DayOfTheWeeks)
{
<td>
<input type="checkbox" checked="@day.Selected" @onchange="@((args) => { day.Selected = (bool)
args.Value; CheckWeek(week); } )" />
</td>
}
</tr>
}
</tbody>
</table>
@code {
private List<Week> weeks = new List<Week>() { new Week { ID = 1 },
new Week { ID = 2 },
new Week { ID = 3 },
new Week { ID = 4 }};
public class Week
{
public int ID { get; set; }
public bool Selected { get; set; }
public List<DayOfTheWeek> DayOfTheWeeks { get; set; } = new List<DayOfTheWeek>()
{ new DayOfTheWeek{ DayOfWeek = DayOfWeek.Monday },
new DayOfTheWeek{ DayOfWeek = DayOfWeek.Tuesday },
new DayOfTheWeek{ DayOfWeek = DayOfWeek.Wednesday },
new DayOfTheWeek{ DayOfWeek = DayOfWeek.Thursday },
new DayOfTheWeek{ DayOfWeek = DayOfWeek.Friday }};
}
public class DayOfTheWeek
{
public DayOfWeek DayOfWeek {get; set;}
public bool Selected {get;set;}
}
protected void Check(Week week)
{
var toCheck = week.DayOfTheWeeks;
foreach (var day in toCheck)
{
day.Selected = week.Selected;
}
}
protected void CheckWeek(Week week)
{
var allSelected = week.DayOfTheWeeks.All(day => day.Selected == true);
if(allSelected)
{
week.Selected = true;
}
else
{
week.Selected = false;
}
}
}
Upvotes: 3