Build a Blazor todo list app
This tutorial shows you how to build and modify a Blazor app.
Learn how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
At the end of this tutorial, you'll have a working todo list app.
Prerequisites
Create a Blazor app
Create a new Blazor app named TodoList in a command shell:
dotnet new blazorserver -o TodoList
dotnet new blazorwasm -o TodoList
The preceding command creates a folder named TodoList with the -o|--output option to hold the app. The TodoList folder is the root folder of the project. Change directories to the TodoList folder with the following command:
cd TodoList
Build a todo list Blazor app
Add a new
TodoRazor component to the app using the following command:dotnet new razorcomponent -n Todo -o PagesThe
-n|--nameoption in the preceding command specifies the name of the new Razor component. The new component is created in the project'sPagesfolder with the-o|--outputoption.Important
Razor component file names require a capitalized first letter. Open the
Pagesfolder and confirm that theTodocomponent file name starts with a capital letterT. The file name should beTodo.razor.Open the
Todocomponent in any file editor and add an@pageRazor directive to the top of the file with a relative URL of/todo.Pages/Todo.razor:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
@code {
}
Save the Pages/Todo.razor file.
Add the
Todocomponent to the navigation bar.The
NavMenucomponent is used in the app's layout. Layouts are components that allow you to avoid duplication of content in an app. TheNavLinkcomponent provides a cue in the app's UI when the component URL is loaded by the app.In the navigation element content (
<nav class="flex-column">) of theNavMenucomponent, add the following<div>element for theTodocomponent.In
Shared/NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</div>
Save the Shared/NavMenu.razor file.
Build and run the app by executing the
dotnet watch runcommand in the command shell from theTodoListfolder. After the app is running, visit the new Todo page by selecting theTodolink in the app's navigation bar, which loads the page at/todo.Leave the app running the command shell. Each time a file is saved, the app is automatically rebuilt, and the page in the browser is automatically reloaded.
Add a
TodoItem.csfile to the root of the project (theTodoListfolder) to hold a class that represents a todo item. Use the following C# code for theTodoItemclass.TodoItem.cs:
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
Note
If using Visual Studio to create the TodoItem.cs file and TodoItem class, use either of the following approaches:
- Remove the namespace that Visual Studio generates for the class.
- Use the Copy button in the preceding code block and replace the entire contents of the file that Visual Studio generates.
Return to the
Todocomponent and perform the following tasks:- Add a field for the todo items in the
@codeblock. TheTodocomponent uses this field to maintain the state of the todo list. - Add unordered list markup and a
foreachloop to render each todo item as a list item (<li>).
Pages/Todo.razor:- Add a field for the todo items in the
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
- The app requires UI elements for adding todo items to the list. Add a text input (
<input>) and a button (<button>) below the unordered list (<ul>...</ul>):
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
Save the
TodoItem.csfile and the updatedPages/Todo.razorfile. In the command shell, the app is automatically rebuilt when the files are saved. The browser reloads the page.When the
Add todobutton is selected, nothing happens because an event handler isn't attached to the button.Add an
AddTodomethod to theTodocomponent and register the method for the button using the@onclickattribute. TheAddTodoC# method is called when the button is selected:
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
To get the title of the new todo item, add a
newTodostring field at the top of the@codeblock:private string? newTodo;Modify the text
<input>element to bindnewTodowith the@bindattribute:<input placeholder="Something todo" @bind="newTodo" />Update the
AddTodomethod to add theTodoItemwith the specified title to the list. Clear the value of the text input by settingnewTodoto an empty string:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.The title text for each todo item can be made editable, and a checkbox can help the user keep track of completed items. Add a checkbox input for each todo item and bind its value to the
IsDoneproperty. Change@todo.Titleto an<input>element bound totodo.Titlewith@bind:<ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> </li> } </ul>Update the
<h1>header to show a count of the number of todo items that aren't complete (IsDoneisfalse). The Razor expression in the following header evaluates each time Blazor rerenders the component.<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>The completed
Todocomponent (Pages/Todo.razor):
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.Add items, edit items, and mark todo items done to test the component.
When finished, shut down the app in the command shell. Many command shells accept the keyboard command Ctrl+C (Windows) or ⌘+C (macOS) to stop an app.
Publish to Azure
For information on deploying to Azure, see Quickstart: Deploy an ASP.NET web app.
Next steps
In this tutorial, you learned how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
Learn about tooling for ASP.NET Core Blazor:
Learn how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
At the end of this tutorial, you'll have a working todo list app.
Prerequisites
Create a Blazor app
Create a new Blazor app named TodoList in a command shell:
dotnet new blazorserver -o TodoList
dotnet new blazorwasm -o TodoList
The preceding command creates a folder named TodoList with the -o|--output option to hold the app. The TodoList folder is the root folder of the project. Change directories to the TodoList folder with the following command:
cd TodoList
Build a todo list Blazor app
Add a new
TodoRazor component to the app using the following command:dotnet new razorcomponent -n Todo -o PagesThe
-n|--nameoption in the preceding command specifies the name of the new Razor component. The new component is created in the project'sPagesfolder with the-o|--outputoption.Important
Razor component file names require a capitalized first letter. Open the
Pagesfolder and confirm that theTodocomponent file name starts with a capital letterT. The file name should beTodo.razor.Open the
Todocomponent in any file editor and add an@pageRazor directive to the top of the file with a relative URL of/todo.Pages/Todo.razor:
@page "/todo"
<h1>Todo</h1>
@code {
}
Save the Pages/Todo.razor file.
Add the
Todocomponent to the navigation bar.The
NavMenucomponent is used in the app's layout. Layouts are components that allow you to avoid duplication of content in an app. TheNavLinkcomponent provides a cue in the app's UI when the component URL is loaded by the app.In the unordered list (
<ul>...</ul>) of theNavMenucomponent, add the following list item (<li>...</li>) andNavLinkcomponent for theTodocomponent.In
Shared/NavMenu.razor:
<ul class="nav flex-column">
...
<li class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</li>
</ul>
Save the Shared/NavMenu.razor file.
Build and run the app by executing the
dotnet watch runcommand in the command shell from theTodoListfolder. After the app is running, visit the new Todo page by selecting theTodolink in the app's navigation bar, which loads the page at/todo.Leave the app running the command shell. Each time a file is saved, the app is automatically rebuilt, and the page in the browser is automatically reloaded.
Add a
TodoItem.csfile to the root of the project (theTodoListfolder) to hold a class that represents a todo item. Use the following C# code for theTodoItemclass.TodoItem.cs:
public class TodoItem
{
public string Title { get; set; }
public bool IsDone { get; set; }
}
Note
If using Visual Studio to create the TodoItem.cs file and TodoItem class, use either of the following approaches:
- Remove the namespace that Visual Studio generates for the class.
- Use the Copy button in the preceding code block and replace the entire contents of the file that Visual Studio generates.
Return to the
Todocomponent and perform the following tasks:- Add a field for the todo items in the
@codeblock. TheTodocomponent uses this field to maintain the state of the todo list. - Add unordered list markup and a
foreachloop to render each todo item as a list item (<li>).
Pages/Todo.razor:- Add a field for the todo items in the
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
- The app requires UI elements for adding todo items to the list. Add a text input (
<input>) and a button (<button>) below the unordered list (<ul>...</ul>):
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
Save the
TodoItem.csfile and the updatedPages/Todo.razorfile. In the command shell, the app is automatically rebuilt when the files are saved. The browser reloads the page.When the
Add todobutton is selected, nothing happens because an event handler isn't attached to the button.Add an
AddTodomethod to theTodocomponent and register the method for the button using the@onclickattribute. TheAddTodoC# method is called when the button is selected:
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
To get the title of the new todo item, add a
newTodostring field at the top of the@codeblock:private string newTodo;Modify the text
<input>element to bindnewTodowith the@bindattribute:<input placeholder="Something todo" @bind="newTodo" />Update the
AddTodomethod to add theTodoItemwith the specified title to the list. Clear the value of the text input by settingnewTodoto an empty string:
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.The title text for each todo item can be made editable, and a checkbox can help the user keep track of completed items. Add a checkbox input for each todo item and bind its value to the
IsDoneproperty. Change@todo.Titleto an<input>element bound totodo.Titlewith@bind:<ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> </li> } </ul>Update the
<h1>header to show a count of the number of todo items that aren't complete (IsDoneisfalse). The Razor expression in the following header evaluates each time Blazor rerenders the component.<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>The completed
Todocomponent (Pages/Todo.razor):
@page "/todo"
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.Add items, edit items, and mark todo items done to test the component.
When finished, shut down the app in the command shell. Many command shells accept the keyboard command Ctrl+C (Windows) or ⌘+C (macOS) to stop an app.
Publish to Azure
For information on deploying to Azure, see Quickstart: Deploy an ASP.NET web app.
Next steps
In this tutorial, you learned how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
Learn about tooling for ASP.NET Core Blazor:
Learn how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
At the end of this tutorial, you'll have a working todo list app.
Prerequisites
Create a Blazor app
Create a new Blazor app named TodoList in a command shell:
dotnet new blazorserver -o TodoList
dotnet new blazorwasm -o TodoList
The preceding command creates a folder named TodoList with the -o|--output option to hold the app. The TodoList folder is the root folder of the project. Change directories to the TodoList folder with the following command:
cd TodoList
Build a todo list Blazor app
Add a new
TodoRazor component to the app using the following command:dotnet new razorcomponent -n Todo -o PagesThe
-n|--nameoption in the preceding command specifies the name of the new Razor component. The new component is created in the project'sPagesfolder with the-o|--outputoption.Important
Razor component file names require a capitalized first letter. Open the
Pagesfolder and confirm that theTodocomponent file name starts with a capital letterT. The file name should beTodo.razor.Open the
Todocomponent in any file editor and add an@pageRazor directive to the top of the file with a relative URL of/todo.Pages/Todo.razor:
@page "/todo"
<h1>Todo</h1>
@code {
}
Save the Pages/Todo.razor file.
Add the
Todocomponent to the navigation bar.The
NavMenucomponent is used in the app's layout. Layouts are components that allow you to avoid duplication of content in an app. TheNavLinkcomponent provides a cue in the app's UI when the component URL is loaded by the app.In the unordered list (
<ul>...</ul>) of theNavMenucomponent, add the following list item (<li>...</li>) andNavLinkcomponent for theTodocomponent.In
Shared/NavMenu.razor:
<ul class="nav flex-column">
...
<li class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</li>
</ul>
Save the Shared/NavMenu.razor file.
Build and run the app by executing the
dotnet watch runcommand in the command shell from theTodoListfolder. After the app is running, visit the new Todo page by selecting theTodolink in the app's navigation bar, which loads the page at/todo.Leave the app running the command shell. Each time a file is saved, the app is automatically rebuilt, and the page in the browser is automatically reloaded.
Add a
TodoItem.csfile to the root of the project (theTodoListfolder) to hold a class that represents a todo item. Use the following C# code for theTodoItemclass.TodoItem.cs:
public class TodoItem
{
public string Title { get; set; }
public bool IsDone { get; set; }
}
Note
If using Visual Studio to create the TodoItem.cs file and TodoItem class, use either of the following approaches:
- Remove the namespace that Visual Studio generates for the class.
- Use the Copy button in the preceding code block and replace the entire contents of the file that Visual Studio generates.
Return to the
Todocomponent and perform the following tasks:- Add a field for the todo items in the
@codeblock. TheTodocomponent uses this field to maintain the state of the todo list. - Add unordered list markup and a
foreachloop to render each todo item as a list item (<li>).
Pages/Todo.razor:- Add a field for the todo items in the
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
}
- The app requires UI elements for adding todo items to the list. Add a text input (
<input>) and a button (<button>) below the unordered list (<ul>...</ul>):
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
}
Save the
TodoItem.csfile and the updatedPages/Todo.razorfile. In the command shell, the app is automatically rebuilt when the files are saved. The browser reloads the page.When the
Add todobutton is selected, nothing happens because an event handler isn't attached to the button.Add an
AddTodomethod to theTodocomponent and register the method for the button using the@onclickattribute. TheAddTodoC# method is called when the button is selected:
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private void AddTodo()
{
// Todo: Add the todo
}
}
To get the title of the new todo item, add a
newTodostring field at the top of the@codeblock:private string newTodo;Modify the text
<input>element to bindnewTodowith the@bindattribute:<input placeholder="Something todo" @bind="newTodo" />Update the
AddTodomethod to add theTodoItemwith the specified title to the list. Clear the value of the text input by settingnewTodoto an empty string:
@page "/todo"
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.The title text for each todo item can be made editable, and a checkbox can help the user keep track of completed items. Add a checkbox input for each todo item and bind its value to the
IsDoneproperty. Change@todo.Titleto an<input>element bound totodo.Titlewith@bind:<ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> </li> } </ul>Update the
<h1>header to show a count of the number of todo items that aren't complete (IsDoneisfalse). The Razor expression in the following header evaluates each time Blazor rerenders the component.<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>The completed
Todocomponent (Pages/Todo.razor):
@page "/todo"
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.Add items, edit items, and mark todo items done to test the component.
When finished, shut down the app in the command shell. Many command shells accept the keyboard command Ctrl+C (Windows) or ⌘+C (macOS) to stop an app.
Next steps
In this tutorial, you learned how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
Learn about tooling for ASP.NET Core Blazor:
Learn how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
At the end of this tutorial, you'll have a working todo list app.
Prerequisites
Create a Blazor app
Create a new Blazor app named TodoList in a command shell:
dotnet new blazorserver -o TodoList
dotnet new blazorwasm -o TodoList
The preceding command creates a folder named TodoList with the -o|--output option to hold the app. The TodoList folder is the root folder of the project. Change directories to the TodoList folder with the following command:
cd TodoList
Build a todo list Blazor app
Add a new
TodoRazor component to the app using the following command:dotnet new razorcomponent -n Todo -o PagesThe
-n|--nameoption in the preceding command specifies the name of the new Razor component. The new component is created in the project'sPagesfolder with the-o|--outputoption.Important
Razor component file names require a capitalized first letter. Open the
Pagesfolder and confirm that theTodocomponent file name starts with a capital letterT. The file name should beTodo.razor.Open the
Todocomponent in any file editor and add an@pageRazor directive to the top of the file with a relative URL of/todo.Pages/Todo.razor:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
@code {
}
Save the Pages/Todo.razor file.
Add the
Todocomponent to the navigation bar.The
NavMenucomponent is used in the app's layout. Layouts are components that allow you to avoid duplication of content in an app. TheNavLinkcomponent provides a cue in the app's UI when the component URL is loaded by the app.In the navigation element content (
<nav class="flex-column">) of theNavMenucomponent, add the following<div>element for theTodocomponent.In
Shared/NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</div>
Save the Shared/NavMenu.razor file.
Build and run the app by executing the
dotnet watch runcommand in the command shell from theTodoListfolder. After the app is running, visit the new Todo page by selecting theTodolink in the app's navigation bar, which loads the page at/todo.Leave the app running the command shell. Each time a file is saved, the app is automatically rebuilt, and the page in the browser is automatically reloaded.
Add a
TodoItem.csfile to the root of the project (theTodoListfolder) to hold a class that represents a todo item. Use the following C# code for theTodoItemclass.TodoItem.cs:
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
Note
If using Visual Studio to create the TodoItem.cs file and TodoItem class, use either of the following approaches:
- Remove the namespace that Visual Studio generates for the class.
- Use the Copy button in the preceding code block and replace the entire contents of the file that Visual Studio generates.
Return to the
Todocomponent and perform the following tasks:- Add a field for the todo items in the
@codeblock. TheTodocomponent uses this field to maintain the state of the todo list. - Add unordered list markup and a
foreachloop to render each todo item as a list item (<li>).
Pages/Todo.razor:- Add a field for the todo items in the
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
- The app requires UI elements for adding todo items to the list. Add a text input (
<input>) and a button (<button>) below the unordered list (<ul>...</ul>):
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
Save the
TodoItem.csfile and the updatedPages/Todo.razorfile. In the command shell, the app is automatically rebuilt when the files are saved. The browser reloads the page.When the
Add todobutton is selected, nothing happens because an event handler isn't attached to the button.Add an
AddTodomethod to theTodocomponent and register the method for the button using the@onclickattribute. TheAddTodoC# method is called when the button is selected:
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
To get the title of the new todo item, add a
newTodostring field at the top of the@codeblock:private string? newTodo;Modify the text
<input>element to bindnewTodowith the@bindattribute:<input placeholder="Something todo" @bind="newTodo" />Update the
AddTodomethod to add theTodoItemwith the specified title to the list. Clear the value of the text input by settingnewTodoto an empty string:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo</h1>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.The title text for each todo item can be made editable, and a checkbox can help the user keep track of completed items. Add a checkbox input for each todo item and bind its value to the
IsDoneproperty. Change@todo.Titleto an<input>element bound totodo.Titlewith@bind:<ul> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> </li> } </ul>Update the
<h1>header to show a count of the number of todo items that aren't complete (IsDoneisfalse). The Razor expression in the following header evaluates each time Blazor rerenders the component.<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>The completed
Todocomponent (Pages/Todo.razor):
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Save the
Pages/Todo.razorfile. The app is automatically rebuilt in the command shell, and the page reloads in the browser.Add items, edit items, and mark todo items done to test the component.
When finished, shut down the app in the command shell. Many command shells accept the keyboard command Ctrl+C (Windows) or ⌘+C (macOS) to stop an app.
Publish to Azure
For information on deploying to Azure, see Quickstart: Deploy an ASP.NET web app.
Next steps
In this tutorial, you learned how to:
- Create a todo list Blazor app project
- Modify Razor components
- Use event handling and data binding in components
- Use routing in a Blazor app
Learn about tooling for ASP.NET Core Blazor:
Feedback
Submit and view feedback for