Blazor Weather Demo Application Edit modal

I wanted to add modal support to my Blazor applications.  As with many of the things I have found with Blazor this is a lot easier than I had thought it would have been.

Now there are several CSS frameworks for Blazor that have modals built in, such as Blazorise, MatBlazor, Telerik and SyncFusion.  These are nice, but I was looking for just the model and with having to use Java script.  I was lucky to find one here from Chris Sainty .  Chris has a lot of good Blazor stuff.


I will be covering my implementation of the Blazored Modal by adding additional functionality to my Weather Demo Application we started with the Form Validation post.  This modal is very clean and simple.  Once you add the project and add your references, it is easy to execute.  One key part of the modal is that you must pass in a razor component, this allows for a flexible implementation.

Configuration



    1.       StartUp.CS add the service

    services.AddBlazoredModal();

    2.       _Imports.razor add using’s

@using Blazored
@using Blazored.Modal
@using Blazored.Modal.Services

    3.       Add the component in MainLayout.razor

   <BlazoredModal />

    4.       Add the CSS link to _Host.cshtml

    <link href="_content/Blazored.Modal/blazored-modal.css" rel="stylesheet" />

    5.       Inject the Modal service in our CityWeather page

    @inject Services.CityWeatherService service


Now we are ready to use the modal component

Calling the Modal


We want to add an edit function to our City weather application.  We will do this by adding a On Click event to the name of the City in the list.  Yes, there are better user experiences we could do, but I want to focus on the Modal implementation not the UI. 

To set the On Click method, we will need to pass in the “City” we are click on and pass that to the Modal to display and allow editing.

Here is the On Click call to trigger the edit:

    <td @onclick="@(e => ShowModal(city))">@city.City</td>


Since we are doing this in the foreach loop when we build the table, it is easy to set the City as the parameter to the method.

We now need to build the ShowModal method.  We will need to build the parameters property to pass into the modal.  The “Parameters” is basically a dictionary collection of what you want to pass to the modal.   This becomes very power full.  You can pass anything you need and let your razor page handle processing the parameters.  Here we are just passing in the selected city from the click event and setting the key with “City”.

Once we set the parameters, we need to set the callback method for what happens when the modal closes.  Once we have that, we just show the modal.  You should note that we are passing in the razor page that we want to display in the modal, “typeof(Addcity)”.  To me this is the power of using this modal.


    void ShowModal(CityWeatherInfo inCity)
    {
        var parameters = new ModalParameters();

        if (inCity != null)
        {
            parameters.Add("City", inCity);

            Modal.OnClose += ModalClosed;
            Modal.Show("", typeof(AddCity), parameters);
        }
    }



In our Modal close we will check to see if the user saved an edit and if they did, we will need to refresh the list and update the DOM.  If the user did not save the edit, we just log that the modal closed.  To refresh the data, we are call the service to get all the cities and then tell Blazor that the state has changed.  We could have returned the updated city, replace it in the collection and then updated the DOM.  Since we are running on the Blazor server, it is just as easy to do it this way.  If we were working with a Server API, we would need to determine the most efficient way to handle the edits.

    void ModalClosed(ModalResult modalResult)
    {
        if (modalResult.Cancelled)
        {
        Console.WriteLine("Modal has closed");
        }
        else
        {
            cityInfo = service.GetAll();
            StateHasChanged();
        }

        Modal.OnClose -= ModalClosed;
    }


Showing the Modal 


In our AddCity razor page we need to inject the Modal Service.  This will give us the access to the features we need to make the modal work. 
We will add an On Initialized method to the page so we can do a couple of things.
1.       If the parameters object is null
a.       We are in “add” mode
b.       We set the title for the Modal
2.       If the parameters are not null
a.       We pull out the “City” object and set it as the model
b.       We set the title to “Editing”

    protected override void OnInitialized()
    {
        if (Parameters == null)
        {
            title = "Add City Weather";
        }
        else
        {
            city = Parameters.Get<CityWeatherInfo>("City");
            title = "Edit City Weather";
        }
    }

Cancel Event Handler


We do add a button to allow the user to cancel out of the edit discard any change.  The button is a normal HTML button with a On Click event handler:

    <button class="btn btn-primary" @onclick="CancelAction">Cancel</button>

In the event handler we will check to see if we are in Adding mode or editing mode.  If we are in Adding mode, we just use the navigation service to go back to the list page.  If we are in edit mode, we are going to set the “return value” of the modal to “Cancel”.  This will allow the calling page to inform the user that the edit was not saved.

Submit Event Handler

On the successful submit of the form, remember from the previous post that we are using Data Annotations for form validation, the “HandleValidSubmit” event handler will be called. 

 In the event handler we must check to see what mode we are in, editing vs. adding.  If we are adding, we execute the code as we did before adding the city to the collection and return via the navigation service.

If we are editing, we call the service to Update the city we edited.  If that is successful, we will return to the list page by calling the Model Service’s close method passing the edited city object, in case the list wants to use it.

    private async Task HandleValidSubmit()
    {
        if (Parameters == null)
        {
            error = await service.AddAsync(city);
            if (string.IsNullOrEmpty(error))
            {
                //go back to the list page
                NavigationManager.NavigateTo("CityWeather");
            }
        }
        else
        {
            error = await service.UpdateAsync(city);
            if (string.IsNullOrEmpty(error))
            {
                ModalService.Close(ModalResult.Ok<CityWeatherInfo>(city));
            }
        }
    }

In our weather demo application, we can now add or edit cities and their Weather.  We are doing this by full page and a modal.  Again, I am amazed how easy this is in Blazor.  It would have taken days for me to do the same functionality in JavaScript.  Not because JavaScript is more complicated, but because I am so much more comfortable with C# and ASP.Net core.

I am looking forward to the next feature we will be adding, using Toast messages.

Remember there is a component for that 😊

piggybacking on https://chrissainty.com/blazored-modal-released/


Comments

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor new and improved Search Box

Blazor Wizard Step Component