Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor Reset Model to Initial State when Click on Cancel (Reset Button) in Editform

I have a crud operation using Blazor Server Side and Editform. Everything works great except for when I try to reset the form after editing an existing record.

When I change something in a form control and then click the reset button, it closes the form. The data that I change is updated to the HTML table, but it's not updated in the database.

Is there anyway I can prevent this?

Here is my model:

public class Address  
{
    public string province { get; set; }
    public string address { get; set; }
    public string contact_name { get; set; }
    public string phone_number { get; set; }
}

This is my EditForm:

<EditForm Model="@model" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div class="form-group">
        <InputText @bind-Value="@model.province" />
    </div> 
    <div class="form-group">
        <InputText @bind-Value="@model.contact_name" />
    </div>
    <div class="form-group">
        <InputText @bind-Value="@model.phone_number" />
    </div>
    <div class="form-group">
        <InputText @bind-Value="@model.address" />
    </div>
    <button type="submit" class="btn btn-primary">Save</button>
    <button type="reset" class="btn btn-warning">Cancel</button>
</EditForm>

Here is my HTML Table:

@if (address_list== null)
{
    <p>Loading</p>
}
else
{
    <table class="table table-striped text-center">
        <thead>
            <tr>
                <th scope="col" class="text-center">Province</th>
                <th scope="col" class="text-center">Contact Name</th>
                <th scope="col" class="text-center">Phone</th>
                <th scope="col" class="text-center">Address</th>
                <th scope="col" class="text-center">Edit</th>
                <th scope="col" class="text-center">Delete</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var d in  address_list)
            {
                <tr>
                    <td>@d.province</td>
                    <td>@d.contact_person</td>
                    <td>@d.phone_number</td>
                    <td>@d.address</td>
                    <td><button type="button" class="btn btn-link" @onclick="@(() => Edit(d))">Edit</button></td>
                    <td><button type="button" class="btn btn-link" @onclick="@(() => Delete(d))">Delete</button></td>  
                </tr>
            }
        </tbody>
    </table>
}
like image 235
Pheakdey Tes Avatar asked Dec 21 '19 06:12

Pheakdey Tes


1 Answers

You don't show your server-side code related to the edit form, but I assume it looks something like this:

@code {
    public Address model { get; set; }
}

You can actually implement the getter and setter. In doing so, create a typical backing field, but then also create a clone field to capture your initial data. Also create a reset function that captures the values from the clone field and puts it back in to the current model state.

@code { 

    public Address model {
        get { return _model; }
        set {
            _model = value;
            _clone = new Address {
                province = value.province,
                address = value.address,
                contact_name = value.contact_name,
                phone_number = value.phone_number            
            }
        }
    Address _model;
    Address _clone;

    public void reset () {
        _model.province = _clone.province;
        _model.address = _clone.address;
        _model.contact_name = _clone.contact_name;
        _model.phone_number = _clone.phone_number;
    }

}

Then, in your edit form, instead of a 'reset' type button, do:

<button class="btn btn-warning" @onclick="reset" @onclick:preventDefault>Cancel</button>

This will last you until the guys at Microsoft implement something like:

<InputText @firstNonBlankAsInitial="true" @bind-Value="@model.province" />
like image 79
pwilcox Avatar answered Oct 13 '22 21:10

pwilcox