Posts How to create a modal dialog
Post
Cancel

How to create a modal dialog

Modal dialog

ConfigurePizzaDialog

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
@inject HttpClient HttpClient

<div class="dialog-container">
    <div class="dialog">
        <div class="dialog-title">
            <h2>@Pizza.Special.Name</h2>
            @Pizza.Special.Description
        </div>
        <form class="dialog-body">
            <div>
                <label>Size:</label>
                <input type="range" min="@Pizza.MinimumSize" max="@Pizza.MaximumSize" step="1" @bind="Pizza.Size" @bind:event="oninput" />
                <span class="size-label">
                    @(Pizza.Size)" (£@(Pizza.GetFormattedTotalPrice()))
                </span>
            </div>
            <div>
                <label>Extra Toppings:</label>
                @if (toppings == null)
                {
                    <select class="custom-select" disabled>
                        <option>(loading...)</option>
                    </select>
                }
                else if (Pizza.Toppings.Count >= 6)
                {
                    <div>(maximum reached)</div>
                }
                else
                {
                    <select class="custom-select" @onchange="ToppingSelected">
                        <option value="-1" disabled selected>(select)</option>
                        @for (var i = 0; i < toppings.Count; i++)
                        {
                            <option value="@i">@toppings[i].Name - (£@(toppings[i].GetFormattedPrice()))</option>
                        }
                    </select>
                }
            </div>

            <div class="toppings">
                @foreach (var topping in Pizza.Toppings)
                {
                    <div class="topping">
                        @topping.Topping.Name
                        <span class="topping-price">@topping.Topping.GetFormattedPrice()</span>
                        <button type="button" class="delete-topping" @onclick="@(() => RemoveTopping(topping.Topping))">x</button>
                    </div>
                }
            </div>
        </form>

        <div class="dialog-buttons">
            <button class="btn btn-secondary mr-auto" @onclick="OnCancel">Cancel</button>
            <span class="mr-center">
                Price: <span class="price">@(Pizza.GetFormattedTotalPrice())</span>
            </span>
            <button class="btn btn-success ml-auto" @onclick="@OnConfirm">Order ></button>
        </div>
    </div>
</div>

@code {
    List<Topping> toppings;

    [Parameter] public Pizza Pizza { get; set; }
    [Parameter] public EventCallback OnCancel { get; set; }
    [Parameter] public EventCallback OnConfirm { get; set; }

    protected async override Task OnInitializedAsync()
    {
        toppings = await HttpClient.GetJsonAsync<List<Topping>>("toppings");
    }

    void ToppingSelected(ChangeEventArgs e)
    {
        if (int.TryParse((string)e.Value, out var index) && index >= 0)
        {
            AddTopping(toppings[index]);
        }
    }

    void AddTopping(Topping topping)
    {
        if (Pizza.Toppings.Find(pt => pt.Topping == topping) == null)
        {
            Pizza.Toppings.Add(new PizzaTopping() { Topping = topping });
        }
    }

    void RemoveTopping(Topping topping)
    {
        Pizza.Toppings.RemoveAll(pt => pt.Topping == topping);
    }
}

Index.razor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@page "/"
@inject HttpClient HttpClient
@inject OrderState OrderState
@inject NavigationManager NavigationManager

<div class="main">
    <ul class="pizza-cards">
        @if (specials != null)
        {
            @foreach (var special in specials)
            {
                <li @onclick="@(() => OrderState.ShowConfigurePizzaDialog(special))" style="background-image: url('@special.ImageUrl')">
                    <div class="pizza-info">
                        <span class="title">@special.Name</span>
                        @special.Description
                        <span class="price">@special.GetFormattedBasePrice()</span>
                    </div>
                </li>
            }
        }
    </ul>
</div>

<div class="sidebar">
    @if (Order.Pizzas.Any())
    {
        <div class="order-contents">
            <h2>Your order</h2>

            @foreach (var configuredPizza in Order.Pizzas)
            {
                <ConfiguredPizzaItem Pizza="configuredPizza" OnRemoved="@(() => OrderState.RemoveConfiguredPizza(configuredPizza))" />
            }
        </div>
    }
    else
    {
        <div class="empty-cart">Choose a pizza<br>to get started</div>
    }

    <div class="order-total @(Order.Pizzas.Any() ? "" : "hidden")">
        Total:
        <span class="total-price">@Order.GetFormattedTotalPrice()</span>
        <a href="checkout" class="btn btn-warning" disabled="@(Order.Pizzas.Count == 0)">
            Order >
        </a>
    </div>
</div>

@if (OrderState.ShowingConfigureDialog)
{
    <ConfigurePizzaDialog
        Pizza="@OrderState.ConfiguringPizza"
        OnConfirm="@OrderState.ConfirmConfigurePizzaDialog" 
        OnCancel="@OrderState.CancelConfigurePizzaDialog" />
}

@code {
    List<PizzaSpecial> specials;
    Order Order => OrderState.Order;

    protected async override Task OnInitializedAsync()
    {
        specials = await HttpClient.GetJsonAsync<List<PizzaSpecial>>("specials");
    }
}

OrderState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System.Collections.Generic;

namespace BlazingPizza.Client
{
    public class OrderState
    {
        public bool ShowingConfigureDialog { get; private set; }

        public Pizza ConfiguringPizza { get; private set; }

        public Order Order { get; private set; } = new Order();

        public void ShowConfigurePizzaDialog(PizzaSpecial special)
        {
            ConfiguringPizza = new Pizza()
            {
                Special = special,
                SpecialId = special.Id,
                Size = Pizza.DefaultSize,
                Toppings = new List<PizzaTopping>(),
            };

            ShowingConfigureDialog = true;
        }

        public void CancelConfigurePizzaDialog()
        {
            ConfiguringPizza = null;

            ShowingConfigureDialog = false;
        }

        public void ConfirmConfigurePizzaDialog()
        {
            Order.Pizzas.Add(ConfiguringPizza);
            ConfiguringPizza = null;

            ShowingConfigureDialog = false;
        }

        public void RemoveConfiguredPizza(Pizza pizza)
        {
            Order.Pizzas.Remove(pizza);
        }

        public void ResetOrder()
        {
            Order = new Order();
        }
    }
}
This post is licensed under CC BY 4.0 by the author.