bind

How to get value from select option and at the same time use @onchange to do a function. (blazor)


<select @bind="Project.Supplier" @onchange="LoadProjectTypes">
   <option value="0">Select Supplier</option>

   @foreach (var supplier in ProjectSuppliers)
    {
        <option>@supplier.SupplierName</option>
    }
</select>

@code{
private ProjectModel Project;
private List<ProjectSuppliersModel> ProjectSuppliers;

public void CreateProject()
{
    //a function to insert the current project in the database
}

protected override void OnInitialized()
{
    ProjectSuppliers = _db.GetProjectSuppliers();
}

I want to get the selected Project.Supplier from select-option and then sent it to the data base. at the same time I want to use LoadProjectTypes function. but there is an error in the select element like this: "The attribute 'onchange' is used two or more times for this element". How can I solve it. Am I missing something? to be more clear: the function LoadProjectTypes affect another select element to show project types which is related just to the selected project supplier as its options


Solution

  • EDIT Inputs in Blazor now have @bind:after event, which gives an easy way for you to do something with your input value whenever it changes. There are also @bind:get and @bind:set, so the answer I gave below is now pretty dodgy.


    Under the hood, @bind uses @onchange to set your variable, so you can't use both.

    I think you don't need 2-way binding for dropdowns usually, so I recommend the "Unbound" example in the following. But if you REALLY want to do 2-way binding, then you can catch the value change in a custom get; set; for the variable instead of trying to catch the actual event.

    @page "/onchange"
    
    <select @onchange="HandleOnChangeUnbound">
        <option disabled selected>Select an option</option>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
    <br />
    @if (UnboundSelected is not null)
    {
        <div>@UnboundSelected</div>
    }
    <select @bind="BoundSelected">
        <option disabled selected>Select an option</option>
        <option>Option A</option>
        <option>Option B</option>
        <option>Option C</option>
    </select>
    @if (DisplayBound is not null)
    {
        <div>@DisplayBound</div>
    }
    
    
    
    @code {
        string UnboundSelected { get; set; }
        string DisplayBound { get; set; }
        private string _boundSelected;
        public string BoundSelected
        {
            get
            {
                return _boundSelected;
            }
            set
            {
                _boundSelected = value;
                HandleOnChangeBound(value);
            }
        }
        void HandleOnChangeUnbound(ChangeEventArgs args)
        {
            UnboundSelected = args.Value.ToString();
            // Do DB stuff.
        }
        void HandleOnChangeBound(string value)
        {
            DisplayBound = value;
            // Do DB stuff
        }
    }