Razor Page
TreeList CRUD Operations in Razor Pages
This article showcases how to perform CRUD operations with the TreeList component in a Razor Pages scenario.
To set up the TreeList component bindings:
- Configure the
Create
,Read
,Update
,Delete
methods of theDataSource
instance. The URLs in these methods must refer to the method names in the PageModel. - Set the
Id
field in theModel
of theDataSource
. It is mandatory for theCreate
,Update
,Delete
operations.
See the implementation details in the example below. For the complete project with Razor Pages examples, visit our GitHub repository.
@page
@model Telerik.Examples.RazorPages.Pages.TreeList.TreeListCrudOperationsModel
@{
ViewData["Title"] = "TreeListCrudOperations";
}
@using Telerik.Examples.RazorPages.Models
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@Html.AntiForgeryToken()
@(Html.Kendo().TreeList<EmployeeDirectoryModel>()
.Name("treelist")
.Toolbar(toolbar => toolbar.Create())
.Columns(columns =>
{
columns.Add().Field(e => e.FirstName).Title("First Name").Width(220);
columns.Add().Field(e => e.LastName).Title("Last Name").Width(200);
columns.Add().Field(e => e.Position);
columns.Add().Field(e => e.HireDate).Format("{0:MMMM d, yyyy}");
columns.Add().Width(350).Command(c =>
{
c.CreateChild().Text("Add child");
c.Edit();
c.Destroy();
})
.HtmlAttributes(new
{
style = "text-align: center;"
});
})
.Editable()
.DataSource(dataSource => dataSource
.Read(r => r.Url("/TreeList/TreeListCrudOperations?handler=Read").Data("forgeryToken")) // Specify the url to the OnPostRead method.
.Update(u => u.Url("/TreeList/TreeListCrudOperations?handler=Update").Data("forgeryToken"))
.Create(c => c.Url("/TreeList/TreeListCrudOperations?handler=Create").Data("forgeryToken"))
.Destroy(d => d.Url("/TreeList/TreeListCrudOperations?handler=Destroy").Data("forgeryToken"))
.Model(m =>
{
m.Id(f => f.EmployeeId); // Provide the Id property of the model.
m.ParentId(f => f.ReportsTo); // Provide the Child Id property of the model.
m.Expanded(true); // Set to true if you want the TreeList to be expanded by default.
m.Field(f => f.FirstName);
m.Field(f => f.LastName);
m.Field(f => f.ReportsTo);
m.Field(f => f.HireDate);
m.Field(f => f.Position);
})
)
.Height(540)
)
<script>
function forgeryToken() {
return kendo.antiForgeryTokens();
}
</script>
<style>
.k-treelist .k-command-cell .k-button {
min-width: 0px;
padding: 10px 10px 10px 10px;
}
</style>
<kendo-treelist name="treelist" height="540">
<toolbar>
<treelist-toolbar-button name="create" />
</toolbar>
<columns>
<treelist-column field="FirstName" width="220px" title="First Name"></treelist-column>
<treelist-column field="LastName" title="Last Name" width="200px"></treelist-column>
<treelist-column field="Position"></treelist-column>
<treelist-column field="HireDate" format="{0:MMMM d, yyyy}"></treelist-column>
<treelist-column width="350px">
<commands>
<treelist-column-command name="createChild" text="Add child" />
<treelist-column-command name="edit" />
<treelist-column-command name="destroy" />
</commands>
</treelist-column>
</columns>
<editable enabled="true"/>
<treelist-datasource>
<transport>
<read url="/TreeList/TreeListCrudOperations?handler=Read" data="forgeryToken"/>
<update url="/TreeList/TreeListCrudOperations?handler=Update" data="forgeryToken"/>
<create url="/TreeList/TreeListCrudOperations?handler=Create" data="forgeryToken"/>
<destroy url="/TreeList/TreeListCrudOperations?handler=Destroy" data="forgeryToken"/>
</transport>
<schema data="Data" total="Total" errors="Errors">
<treelist-model id="EmployeeId" parent-id="ReportsTo" expanded="true">
<fields>
<field name="EmployeeId" type="number"></field>
<field name="ReportsTo" nullable="true"></field>
<field name="FirstName" type="string"></field>
<field name="LastName" type="string"></field>
<field name="Position" type="string"></field>
<field name="HireDate" type="date"></field>
</fields>
</treelist-model>
</schema>
</treelist-datasource>
</kendo-treelist>
<script>
function forgeryToken() {
return kendo.antiForgeryTokens();
}
</script>
<style>
.k-treelist .k-command-cell .k-button {
min-width: 0px;
padding: 10px 10px 10px 10px;
}
</style>
using System;
using System.Collections.Generic;
using System.Linq;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Telerik.Examples.RazorPages.Models;
namespace Telerik.Examples.RazorPages.Pages.TreeList
{
public class TreeListCrudOperationsModel : PageModel
{
private static IList<EmployeeDirectoryModel> employees;
public void OnGet()
{
GetDirectory(); // Retrieve the sample data.
}
public JsonResult OnPostRead([DataSourceRequest] DataSourceRequest request)
{
// Apply any DataSource operations such as Paging/Filtering/Sorting to the List.
var result = employees.ToTreeDataSourceResult(request,
e => e.EmployeeId,
e => e.ReportsTo,
e => e
);
return new JsonResult(result);
}
public JsonResult OnPostCreate([DataSourceRequest] DataSourceRequest request, EmployeeDirectoryModel employee)
{
// Assign an Id to the newly created employee and add them to the list.
employee.EmployeeId = employees.Count + 2;
employees.Add(employee);
return new JsonResult(new[] { employee }.ToTreeDataSourceResult(request, ModelState));
}
public JsonResult OnPostUpdate([DataSourceRequest] DataSourceRequest request, EmployeeDirectoryModel employee)
{
var target = employees.FirstOrDefault(x => x.EmployeeId == employee.EmployeeId);
// Update the data for the employee that was edited.
if(target != null)
{
target.FirstName = employee.FirstName;
target.LastName = employee.LastName;
target.HireDate = employee.HireDate;
target.Position = employee.Position;
target.ReportsTo = employee.ReportsTo;
}
return new JsonResult(new[] { employee }.ToTreeDataSourceResult(request, ModelState));
}
public JsonResult OnPostDestroy([DataSourceRequest] DataSourceRequest request, EmployeeDirectoryModel employee)
{
employees.Remove(employees.FirstOrDefault(x => x.EmployeeId == employee.EmployeeId));
return new JsonResult(new[] { employee }.ToTreeDataSourceResult(request, ModelState));
}
// Add some sample data to the list.
private IList<EmployeeDirectoryModel> GetDirectory()
{
if (employees == null)
{
employees = new List<EmployeeDirectoryModel>();
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 1,
FirstName = "Daryl",
LastName = "Sweeney",
ReportsTo = null,
HireDate = DateTime.Now.AddDays(1),
Position = "CEO",
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 2,
FirstName = "Guy",
LastName = "Wooten",
ReportsTo = 1,
HireDate = DateTime.Now.AddDays(2),
Position = "Chief Technical Officer"
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 3,
FirstName = "Buffy",
LastName = "Weber",
ReportsTo = 2,
HireDate = DateTime.Now.AddDays(3),
Position = "VP, Engineering"
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 4,
FirstName = "Hyacinth",
LastName = "Hood",
ReportsTo = 3,
HireDate = DateTime.Now.AddDays(4),
Position = "Team Lead"
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 5,
FirstName = "Akeem",
LastName = "Carr",
ReportsTo = 4,
HireDate = DateTime.Now.AddDays(5),
Position = "Junior Software Developer"
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 6,
FirstName = "Rinah",
LastName = "Simon",
ReportsTo = 4,
HireDate = DateTime.Now.AddDays(6),
Position = "Software Developer"
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 7,
FirstName = "Gage",
LastName = "Daniels",
ReportsTo = 3,
HireDate = DateTime.Now.AddDays(7),
Position = "Software Architect",
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 8,
FirstName = "Constance",
LastName = "Vazquez",
ReportsTo = 3,
HireDate = DateTime.Now.AddDays(8),
Position = "Director, Engineering",
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 9,
FirstName = "Darrel",
LastName = "Solis",
ReportsTo = 8,
HireDate = DateTime.Now.AddDays(9),
Position = "Team Lead",
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 10,
FirstName = "Brian",
LastName = "Yang",
ReportsTo = 9,
HireDate = DateTime.Now.AddDays(10),
Position = "Senior Software Developer",
});
employees.Add(new EmployeeDirectoryModel
{
EmployeeId = 11,
FirstName = "Lillian",
LastName = "Bradshaw",
ReportsTo = 9,
HireDate = DateTime.Now.AddDays(11),
Position = "Software Developer",
});
}
return employees;
}
}
}
using System;
using System.ComponentModel.DataAnnotations;
namespace Telerik.Examples.RazorPages.Models
{
public class EmployeeDirectoryModel
{
[ScaffoldColumn(false)]
public int EmployeeId { get; set; }
[Required]
[Display(Name = "First name")]
public string FirstName { get; set; }
[Display(Name = "Last name")]
public string LastName { get; set; }
[ScaffoldColumn(false)]
public int? ReportsTo { get; set; }
public string Position { get; set; }
[ScaffoldColumn(false)]
public bool hasChildren { get; set; }
private DateTime? hireDate;
[DataType(DataType.Date)]
[Display(Name = "Hire Date")]
public DateTime? HireDate
{
get
{
return hireDate;
}
set
{
if (value.HasValue)
{
hireDate = value.Value;
}
else
{
hireDate = null;
}
}
}
}
}