DEV Community

Cover image for Simple Todo App with Blazor Server and Material Blazor
Zoltan Halasz
Zoltan Halasz

Posted on

5 1

Simple Todo App with Blazor Server and Material Blazor

In order to make my journey in C# more interesting, I insert small projects where I can learn new things. The new target is now Blazor Server, a cool new Web Technology from Microsoft.

I am trying to find small things to learn and add them to a bigger project later this year, perhaps.
My main tutors on the net were Tim Corey, and maybe Nick Chapsas for this topic. You can search them on youtube, they have great content.

The new application I have created is a regular todo app which uses:

Prerequisites:

  • asp.net core 3.1 installed on your machine
  • intermediate C# and html

Code is under:
https://github.com/zoltanhalasz/TodoList_BlazorServer.git

The application is live: https://todolist-blazorserver.zoltanhalasz.net/todos

You can add material design to a blazor server project:

  • Install-Package MatBlazor
  • Add @using MatBlazor in main _Imports.razor
  • add to _Host.cshtml (head section)

The toaster is added to the todo page: see instructions at: https://www.matblazor.com/Toast

A. The main model class for the todos:

public class TodoModel
{
public int Id { get; set; }

public string Todo { get; set; }

public DateTime Deadline { get; set; }

public bool IsCompleted { get; set; }

}
Enter fullscreen mode Exit fullscreen mode

B. The layout:
Please read the below examples
https://www.matblazor.com/TextField
https://www.matblazor.com/Checkbox
https://www.matblazor.com/DatePicker
https://www.matblazor.com/Button
See list of icons available:
https://www.matblazor.com/Icon
Toast, see tutorial example:
https://www.matblazor.com/Toast

C. The code-behind:

@page "/todos"
@inject IMatToaster Toaster
@using TodoList_BlazorServer.Data


<h1>Todo Manager App</h1>

<div class="row">
    <div class="col-md-4">
        <MatTextField @bind-Value="@myTodoText" Label="Add todo task here"></MatTextField>
    </div>
    <div class="col-md-4">
        <MatDatePicker @bind-Value="@myDeadline"></MatDatePicker>
    </div>
    <div class="col-md-4">
        <MatButton Raised="true" Icon="playlist_add" OnClick="@Click">Add Todo</MatButton>
    </div>
</div>

@if (TodoList != null && TodoList.Count>0)
{
    <table class="table">
        <thead>
            <tr>
                <th>Ready?</th>
                <th>Description</th>
                <th>Deadline</th>
                <th>Complete</th>
                <th>Delete</th>
                <th>Edit</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var td in TodoList)
            {
            <tr>
                <td>
                    <MatCheckbox @bind-Value="@td.IsCompleted" Disabled="true"></MatCheckbox>
                </td>
                <td>@td.Todo</td>
                <td>@td.Deadline.ToShortDateString()</td>
                <td><MatButton Icon="done" Outlined="true" @onclick="@(e=> completeItem(td.Id))">Complete</MatButton></td>
                <td><MatButton Icon="delete" Outlined="true" @onclick="@(e=> deleteItem(td.Id))">Delete</MatButton></td>
                <td><MatButton Icon="edit" Outlined="true" @onclick="@(e=> editItem(td.Id))">Edit</MatButton></td>
            </tr>
            }
        </tbody>
    </table>
}

@code {
    private List<TodoModel> TodoList = new List<TodoModel>();
    string myTodoText = null;
    DateTime? myDeadline;
    int editedID = 0;


    private void Click(MouseEventArgs e)
    {
        if (myTodoText == null)
        {
            Toaster.Add("Cannot add empty values", MatToastType.Warning, "Todo List", null);
            return;
        }

        if (editedID == 0)
        {              
            var myTodoItem = new TodoModel()
            {
                Id = TodoList.Count() + 1,
                Deadline = myDeadline == null ? DateTime.Now.AddDays(1) : ((DateTime)myDeadline),
                Todo = myTodoText,
                IsCompleted = false
            };
            TodoList.Add(myTodoItem);
            myTodoText = null;
            myDeadline = null;
            Toaster.Add("New todo added.", MatToastType.Info, "Todo List", null);
        }
        else
        {
            var myTodo = TodoList.FirstOrDefault(x => x.Id == editedID);
            myTodo.Todo = myTodoText;
            myTodo.Deadline = myDeadline == null ? DateTime.Now.AddDays(1) : ((DateTime)myDeadline);

            myTodoText = null;
            myDeadline = null;
            Toaster.Add("Todo edit finished.", MatToastType.Info, "Todo List", null);
            editedID = 0;
        }

    }

    void deleteItem(int id)
    {
        var myTodo = TodoList.FirstOrDefault(x => x.Id == id);
        TodoList.Remove(myTodo);
        Toaster.Add("Todo removed.", MatToastType.Info, "Todo List", null);
    }

    void completeItem(int id)
    {
        var myTodo = TodoList.FirstOrDefault(x => x.Id == id);
        myTodo.IsCompleted = !myTodo.IsCompleted;
        Toaster.Add("Todo status changed.", MatToastType.Info, "Todo List", null);
    }

    void editItem(int id)
    {
        var myTodo = TodoList.FirstOrDefault(x => x.Id == id);
        myTodoText = myTodo.Todo;
        myDeadline = myTodo.Deadline;
        editedID = id;
    }
}
Enter fullscreen mode Exit fullscreen mode

D. Final result:

todolist

Billboard image

Deploy and scale your apps on AWS and GCP with a world class developer experience

Coherence makes it easy to set up and maintain cloud infrastructure. Harness the extensibility, compliance and cost efficiency of the cloud.

Learn more

Top comments (2)

Collapse
 
hermetheus profile image
Allan

Zoltan, Thanks for this! It's a nice blazor start!

Collapse
 
zoltanhalasz profile image
Zoltan Halasz

I'm also learning, and try to share my experience. Happy to help.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay