Home > Software engineering >  @onchange event not triggering for first option in blazor
@onchange event not triggering for first option in blazor

Time:07-26

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

working blazor fiddle

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>
        }
    };
}
  • Related