Building A Todo List Using Blazor

Introduction

 
I've been spending a lot of time lately dabbling with Microsoft's Blazor web framework and would love to share my learnings with the community. In this article, we'll learn to build a dead-simple Todo List application using Blazor.
 
Prerequisites
 
To start building the Blazor apps first thing you'll need is the .NET SDK (Software Development Kit). You could simply download and install the .NET SDK from the link mentioned below,
Once installed, open the command prompt and run the following command:
  1. dotnet  
If the installation was successful, you'll see the following output on the screen. 
 
 

Creating the Todo app

 
In the command prompt, run the following command to create a new Blazor app:
  1. dotnet new blazorwasm -o TodoApp  
The above command will create a new folder named TodoApp which will be the root folder of our application. 
 
Move to the TodoApp directory using the following command:
  1. cd TodoApp   

Creating the Todo Component 

  1. dotnet new razorcomponent -n Todo -o Pages  
Use the above command to create a new component named Todo which will be located in the Pages directory of the project. The -n flag is used to specify the name of the component and -o is used to specify the location. The name of the file where the component code resides will be Todo.razor.
 
The Todo.razor fille will be pretty much empty at this moment.
  1. <h3>Todo</h3>    
  2. @code {    
  3. }     

Adding the Route

 
Next, we'll use the @page directive to define a route for this component,
  1. @page "/todo"    
  2. <h3>Todo</h3>    
  3. @code {    
  4. }     
Add @page "/todo" at the top of the Todo.razor file and save your changes. 
 
The next thing we need to do is to add the route to the navigation menu. To do this open the NavMenu.razor file located inside the shared directory. And add the following code to the unordered list and hit the save button.
  1. <ul class="nav flex-column">    
  2.     .    
  3.     .    
  4.     .     
  5.     <li class="nav-item px-3">    
  6.         <NavLink class="nav-link" href="todo">    
  7.             <span class="oi oi-list-rich" aria-hidden="true"></span> TodoApp    
  8.         </NavLink>    
  9.     </li>    
  10. </ul>      

Starting the application

 
Use the following command to start the application:
  1. dotnet watch run  
The above command will build and run your application and will launch it inside a web browser. This will open the application in watch mode and every time you make some changes in any of the files, the app will be automatically rebuilt. Once the app is up and running, visit the new Todo component by selecting the Todo link in the navigation bar on the left-hand side of your application.
 

Creating the TodoItem Class

 
Next, we'll be adding a TodoItem.cs file to the root of the project to create a class that represents a todo item.
  1. public class TodoItem  
  2. {  
  3.     public string Title { getset; }  
  4.     public bool IsComplete { getset; } = false;  

  5.     public TodoItem(string title)  
  6.     {  
  7.         Title = title;  
  8.     }  
  9. }  

Adding UI elements to the Component

 
We'll start by adding an input box and a button to theTodo.razor file. This will enable the use to enter 
  1. <input type="Enter a Todo">    
  2. <button>Save</button>     
Next, we'll wire up a binding and a click event with the input box and the button using the @bind and @onclick attributes.
  1. <input @bind="newTodoItem" type="Enter a Todo">    
  2. <button @onclick="Save">Save</button>    
We need to create the newTodoItem property and Save method which are registered with the @bind and @onclick attributes.
  1. @code {  
  2.   private string newTodoItem { getset; }  
  3.   
  4.   private void Save()  
  5.   {  
  6.   
  7.   }  
  8. }  
Now, whenever someone clicks the Save button in the UI the @onclick attribute will trigger the Save method from the code block.
 

Saving the Todo Items

 
We'll create a new List to save the todo items entered by the user.
  1. private List<TodoItem> todoList = new List<TodoItem>();  
And every time a user clicks the save button we'll add a new TodoItem instance to this list. 
  1. private void Save()  
  2. {  
  3.     todoList.Add(new TodoItem(newTodoItem));  
  4. }  
The newTodoItem passed to the TodoItem's constructor is the property binding registered with the input box. It'll contain the text user has entered in the input box.
 
To make sure the user has entered a valid string in the input box we'll use the IsNullOrWhiteSpace method. And once the string is added to the list we'll clear the input box by assigning an empty string to it.
  1. if(!string.IsNullOrWhiteSpace(newTodoItem))  
  2. {  
  3.     todoList.Add(new TodoItem(newTodoItem));  
  4.     newTodoItem = string.Empty;  
  5. }  
We'll use a foreach loop to loop over the todoList and display the items using an unordered list.
  1. @if (todoList.Count > 0)  
  2. {  
  3.   <ul>  
  4.     @foreach (TodoItem todo in todoList)  
  5.     {  
  6.       <li>@todo.Title</li>  
  7.     }  
  8.   </ul>  
  9. }  
Now, once you start entering the todo items in the input box it'll start appearing in the unordered list.
 
One more thing we could do is add a checkbox before the todo text to indicate if the todo task is complete or not and bind the check box value with the IsComplete property
  1. <li>  
  2.     <input type="checkbox" @bind="todo.IsComplete" />  
  3.     <span style="@(todo.IsComplete ? "text-decoration: line-through" : "")">@todo.Title</span>    
  4. </li>  
We've also added a style binding to the span element wrapping around the todo text which will strike the text if checkbox before the span element is checked.
 
In the end, our Todo.razor file will look like this,
  1. @page "/todo"  
  2.   
  3. <h3>Todo</h3>  
  4. <input @bind="newTodoItem" type="Enter a Todo">  
  5. <button type="button" @onclick="Save">Save</button>  
  6.   
  7. @if (todoList.Count > 0)  
  8. {  
  9.   <ul>  
  10.     @foreach (TodoItem todo in todoList)  
  11.     {  
  12.       <li>  
  13.         <input type="checkbox" @bind="todo.IsComplete" />  
  14.         <span style="@(todo.IsComplete ? "text-decoration: line-through" : "")">@todo.Title</span>    
  15.       </li>  
  16.     }  
  17.   </ul>  
  18. }  
  19.   
  20. @code {  
  21.   private List<TodoItem> todoList = new List<TodoItem>();  
  22.   private string newTodoItem { getset; }  
  23.   
  24.   private void Save()  
  25.   {  
  26.     if (!string.IsNullOrWhiteSpace(newTodoItem))  
  27.     {  
  28.       todoList.Add(new TodoItem(newTodoItem));  
  29.       newTodoItem = string.Empty;  
  30.     }  
  31.   }  
  32. }  
And that's it. In case, you've any queries or feedback, do let me know in the comment section.