Home > Mobile >  Blazor @Onchanged / @bind for List item
Blazor @Onchanged / @bind for List item

Time:09-06

I want to do a DbUpdate for a List item every time a checkbox is ticked. My List is the property but it does not fire the SET when a @bind in the foreach is changed. I also cannot use @Bind on the foreach and use an @Onchanged at the same time. How could i achieve my goal and what is the best blazor practice?

Foreach: First checkbox handles the method but the passed object is not changed by the "Checked" The second checkbox changes the bool of the object but i can't use @Onchange in combination with @Bind

@foreach (var configuration in dashboardConfigurations)
            {
                <tr>
                    <td>@configuration.Customer.Name</td>
                    <td>@configuration.Customer.Vat</td>
                    <td><input type="checkbox" @onchange="@(async () => await SaveConfiguration(configuration))" checked="@configuration.UploadPurchaseInvoices"/></td> 
                    <td><input type="checkbox" @bind="configuration.UploadSalesInvoices" /></td>
                    <td><button @onclick="@(()=> TestMethod(1))">Disable Customer</button></td>
                </tr>
            }

For: Hoped that a change of the textbox would call the SET of my parameter List but is does nothing...

@for(int i = 0; i < DashboardConfigurations.Count; i  ){
                <tr>
                    <td>@DashboardConfigurations[i].Customer.Name</td>
                    <td>@DashboardConfigurations[i].Customer.Vat</td>
                    <td><input type="checkbox" @bind="DashboardConfigurations[i].UploadPurchaseInvoices"/></td>
                    <td><input type="checkbox" @bind="DashboardConfigurations[i].UploadSalesInvoices" /></td>
                    <td><button @onclick="@(()=> TestMethod(1))">Disable Customer</button></td>
                </tr>
            }

Code:

@code { 

    private List<CustomerDashboardConfiguration> dashboardConfigurations;
    [Parameter]
    public List<CustomerDashboardConfiguration> DashboardConfigurations
    {
        get { return dashboardConfigurations; }
        set { dashboardConfigurations = value; }
    }

    internal async Task SaveConfiguration(CustomerDashboardConfiguration customerDashboardConfiguration)
    {
        Console.WriteLine("Saving object");
    }
}

Edit: This works and is exactly what i am trying to achieve but it is pretty ugly in my foreach:

<td><input type="checkbox" @onchange="@(async e =>{configuration.UploadPurchaseInvoices = (bool)e.Value;  await SaveConfiguration(configuration);})" checked="@configuration.UploadPurchaseInvoices"/></td>

CodePudding user response:

Brian has answered the first part of your question.

This works and is exactly what i am trying to achieve but it is pretty ugly in my foreach.

<td><input type="checkbox" @onchange="@(async e =>{configuration.UploadPurchaseInvoices = (bool)e.Value;  await SaveConfiguration(configuration);})" checked="@configuration.UploadPurchaseInvoices"/></td>

Sure is! Move the anonymous method into the code section and just call the method.

<td>
   <input 
      type="checkbox" 
      @onchange="(e) => CheckboxChanged(configuration, e)" 
      checked="@configuration.UploadPurchaseInvoices"
   />
</td>

@code {
//....
async Task CheckboxChanged(DashboardConfiguration configuration, ChangeEventArgs e) 
   {
      configuration.UploadPurchaseInvoices = (bool)e.Value;
      await SaveConfiguration(configuration);
   }
}

Wish there was a way to use the bound object so the (bool)e.Value isn't needed anymore but this works to!

There is. See the code below. But there is a problem on event timing that the code illustrates.

@page "/counter"

<div>
    <input type="checkbox" @bind-value=Checked @oninput=Changed /> CheckBox
</div>

<div >
    Checked : @Checked
</div>

<div >
    Message : @message
</div>

@code {
    private bool Checked { get; set; }
    private string message = string.Empty;

    private void Changed( ChangeEventArgs e )
    {
        message = $"Clicked at {DateTime.Now.ToLongTimeString()}. Sumitted Value is {e.Value?.ToString()}  Checked Property was {Checked}.";
    }
}

enter image description here

CodePudding user response:

Use a ForEach not a For there are known issues with the index reference.

@foreach (var dashboardConfiguration in DashboardConfigurations)
{
    <tr>
        <td>@dashboardConfiguration.Customer.Name</td>
        <td>@dashboardConfiguration.Customer.Vat</td>
        <td><input type="checkbox" @bind="dashboardConfiguration.UploadPurchaseInvoices" /></td>
        <td><input type="checkbox" @bind="dashboardConfiguration.UploadSalesInvoices" /></td>
        <td><button @onclick="@(()=> TestMethod(dashboardConfiguration))">Disable Customer</button></td>
    </tr>
}
  • Related