I've a select control in blazor which shows 2 option to sort a column and it is rendering fine but at first time when I choose 1st option then associated @onchange event doesn't trigger and when I choose the 2nd one and then choose the 1st one back then it works, I'm unable to figure out what's wrong here
<select @onchange="@(() => SortTable(Name))" style="width: 1rem;">
<option>Sort By Ascending</option>
<option>Sort By Descending</option>
</select>
and event callback method-
private async Task SortTable(string columnName)
{
if (columnName != activeSortColumn)
{
isSortedAscending = true;
activeSortColumn = columnName;
}
else
{
if (isSortedAscending)
{
}
else
{
}
isSortedAscending = !isSortedAscending;
}
await SortEvent.InvokeAsync((columnName, isSortedAscending));
}
CodePudding user response:
You'll want to use ChangeEventArgs to receive the event
<select @onchange="HandleSelectChange" value="@selectedItem" >
<option> First </option>
<option> Second </option>
</select>
<div> @selectedItem </div>
string selectedItem = "First";
private async Task HandleSelectChange(ChangeEventArgs e)
{
selectedItem = e.Value!.ToString()!;
}
Update
CodePudding user response:
In response to your requests for some suggestions this is a standalone page with two options.
The first sticks with the select but separates out the column selection from the sort direction. Not very satisfactory as it potentially calls SortEvent.InvokeAsync((columnName, isSortedAscending));
twice. Someone may come up with a better solution. I've only included it to demonstrate the UI challenges using a Select.
The second uses a dropdown implementation - in this case Bootstrap. It's much more elegant and you get a single event when you select the column and the direction.
@page "/"
<h3>Column Sorting</h3>
<div >
<div >
<span @onclick="@(() => ResetSort("Country"))">Country</span>
<select @onclick="@(() => ResetSort("Country"))" @onchange=@SortTable style="width: 1rem;">
<option value=false selected="@(!sortDescending)">Sort By Ascending</option>
<option value=true selected="@(sortDescending)">Sort By Descending</option>
</select>
</div>
<div >
<span @onclick="@(() => ResetSort("Continent"))">Continent</span>
<select @onclick="@(() => ResetSort("Continent"))" @onchange=@SortTable style="width: 1rem;">
<option value=false selected="@(!sortDescending)">Sort By Ascending</option>
<option value=true selected="@(sortDescending)">Sort By Descending</option>
</select>
</div>
</div>
<div >
<div >
@(SortingColumn) : @(sortDescending ? "Sort Descending" : "Sort Ascending")
</div>
</div>
<div >
<div @onmouseover="@(() => ShowSorting("Country"))" @onmouseout="@(() => ShowSorting(string.Empty))">
<div >
Country
<span ></span>
</div>
@DropDown("Country")
</div>
<div >
<div @onmouseover="@(() => ShowSorting("Continent"))" @onmouseout="@(() => ShowSorting(string.Empty))">
<div >
Continent
<span ></span>
</div>
@DropDown("Continent")
</div>
</div>
</div>
<div >
<div >
@(SortingColumn) : @(sortDescending ? "Sort Descending" : "Sort Ascending")
</div>
</div>
@code {
bool sortDescending;
// Set to default sort column
string SortingColumn = "Country";
// Top row code
private void ResetSort(string name)
{
if (!name.Equals(SortingColumn))
{
sortDescending = false;
SortingColumn = name;
}
}
private void SortTable(ChangeEventArgs e)
{
if (bool.TryParse(e.Value?.ToString(), out bool value))
sortDescending = value;
}
private string GetActive(string column, bool dir)
{
if (SortingColumn.Equals(column))
return dir == sortDescending ? "active" : string.Empty;
return string.Empty;
}
string SelectedColumn = string.Empty;
private void SetSorting(string column, bool descending)
{
SortingColumn = column;
sortDescending = descending;
}
private void ShowSorting(string column)
{
SelectedColumn = column;
}
private RenderFragment DropDown(string column) => (__builder) =>
{
@if (this.SelectedColumn.Equals(column))
{
<ul >
<li @onclick="() => this.SetSorting(column, false)">Ascending</li>
<li @onclick="() => this.SetSorting(column, true)">Descending</li>
</ul>
}
};
}