Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions treeview/rename-node/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Rename TreeView Node

Tree TreeView component is a data visualization component, and it does not provide editing capabilities out-of-the-box. If your users need to perform CRUD operations a lot, you may want to consider using <a href="https://demos.telerik.com/blazor-ui/treelist/editing-inline" target="_blank">the TreeList component that offers built-in editing</a> (in fact, it offers three different edit modes and UX).

If you want to add editing capabilities to your treeview, the most straight forward way to implement them is to:

1. Create a component that will provide the desired item rendering and editing UX.
* In this sample, it is the `~/Shared/EditableTreeNode.razor` component.
1. Put that component in the <a href="https://docs.telerik.com/blazor-ui/components/treeview/templates" target="_blank">`ItemTemplate`</a> of your treeview.
1. Pass to that component the current item that it will render and edit.
* We pass it as a parameter to the child component.
1. Raise an event after an item was edited so the parent treeview can re-render.
* In this sample we fetch the data from the mock database every time to ensure the TreeView is up-to-date and shows other people's edits. In your case you can choose when and how to make updates.
25 changes: 25 additions & 0 deletions treeview/rename-node/rename-node.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31313.79
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rename_node", "rename-node\rename_node.csproj", "{5BA11479-F113-4C80-804A-C1FC7AFFF5B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5BA11479-F113-4C80-804A-C1FC7AFFF5B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BA11479-F113-4C80-804A-C1FC7AFFF5B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BA11479-F113-4C80-804A-C1FC7AFFF5B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BA11479-F113-4C80-804A-C1FC7AFFF5B9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F4DB2B5B-F48B-4C6F-AF60-2BF3F0663C20}
EndGlobalSection
EndGlobal
9 changes: 9 additions & 0 deletions treeview/rename-node/rename-node/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
</Found>
<NotFound>
<h1>Page not found</h1>
<p>Sorry, but there's nothing here!</p>
</NotFound>
</Router>
20 changes: 20 additions & 0 deletions treeview/rename-node/rename-node/Models/TreeItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace rename_node.Models
{
/// <summary>
/// Sample tree item model, uses the default field names.
/// </summary>
public class TreeItem
{
public int Id { get; set; }
public string Text { get; set; }
public int? ParentId { get; set; }
public bool HasChildren { get; set; }
public string Icon { get; set; }
public bool Expanded { get; set; }
}
}
36 changes: 36 additions & 0 deletions treeview/rename-node/rename-node/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@page "/"

@using rename_node.Models
@using rename_node.Services
@using rename_node.Shared
@inject TreeDataService DataService

<TelerikTreeView Data="@FlatData">
<TreeViewBindings>
<TreeViewBinding>
<ItemTemplate>
@* A component in the Shared folder where we define the desired rendering and UX for editing *@
<EditableTreeNode Item="@(context as TreeItem)" ItemTextChanged="@UpdateData"></EditableTreeNode>
</ItemTemplate>
</TreeViewBinding>
</TreeViewBindings>
</TelerikTreeView>

@code {
List<TreeItem> FlatData { get; set; }

protected override async Task OnInitializedAsync()
{
await FetchData();
}

async Task UpdateData()
{
await FetchData();
}

async Task FetchData()
{
FlatData = await DataService.GetData();
}
}
33 changes: 33 additions & 0 deletions treeview/rename-node/rename-node/Pages/_Host.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@page "/"
@namespace rename_node.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>rename_node</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" />
<script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js" defer></script>
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />

<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

<script src="_framework/blazor.server.js"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions treeview/rename-node/rename-node/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace rename_node
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStaticWebAssets();
webBuilder.UseStartup<Startup>();
});
}
}
27 changes: 27 additions & 0 deletions treeview/rename-node/rename-node/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:55276/",
"sslPort": 44398
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"rename_node": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}
107 changes: 107 additions & 0 deletions treeview/rename-node/rename-node/Services/TreeDataService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using rename_node.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace rename_node.Services
{
/// <summary>
/// Simulates real data source (database) operations in memory. Replace with actual storage and logic.
/// </summary>
public class TreeDataService
{
List<TreeItem> items = new List<TreeItem>();

public async Task<List<TreeItem>> GetData()
{
EnsureData();
return await Task.FromResult(new List<TreeItem>(items));
}

public async Task UpdateNode(TreeItem itemToUpdate)
{
int itmIndex = items.FindIndex(itm => itm.Id == itemToUpdate.Id);
if(itmIndex > -1)
{
items[itmIndex] = itemToUpdate;
}
}

private void EnsureData()
{
if (items == null || !items.Any())
{
GenerateData();
}
}

private void GenerateData()
{
items = new List<TreeItem>();

items.Add(new TreeItem()
{
Id = 1,
Text = "Project",
ParentId = null,
HasChildren = true,
Icon = "folder",
Expanded = true
});

items.Add(new TreeItem()
{
Id = 2,
Text = "Design",
ParentId = 1,
HasChildren = true,
Icon = "brush",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 3,
Text = "Implementation",
ParentId = 1,
HasChildren = true,
Icon = "folder",
Expanded = true
});

items.Add(new TreeItem()
{
Id = 4,
Text = "site.psd",
ParentId = 2,
HasChildren = false,
Icon = "psd",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 5,
Text = "index.js",
ParentId = 3,
HasChildren = false,
Icon = "js"
});
items.Add(new TreeItem()
{
Id = 6,
Text = "index.html",
ParentId = 3,
HasChildren = false,
Icon = "html"
});
items.Add(new TreeItem()
{
Id = 7,
Text = "styles.css",
ParentId = 3,
HasChildren = false,
Icon = "css"
});
}
}
}
52 changes: 52 additions & 0 deletions treeview/rename-node/rename-node/Shared/EditableTreeNode.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@using rename_node.Models
@using rename_node.Services
@inject TreeDataService DataService

@if (!string.IsNullOrEmpty(Item.Icon))
{
<TelerikIcon Icon="@Item.Icon"></TelerikIcon>
}
@if (!IsEditing)
{
<span style="margin-right: 1em;">@Item.Text</span>
<TelerikButton Icon="pencil" OnClick="@Edit" Class="k-flat"></TelerikButton>
}
else
{
<span @onclick:stopPropagation="true">@* Stop the treenode from taking focus when you click in the textbox *@
<TelerikTextBox @bind-Value="@Item.Text" @ref="@tbRef"></TelerikTextBox>
</span>
<TelerikButton Icon="save" OnClick="@Save"></TelerikButton>
}


@code {
[Parameter]
public TreeItem Item { get; set; }
[Parameter]
public EventCallback ItemTextChanged { get; set; }

TelerikTextBox tbRef { get; set; }
bool IsEditing { get; set; }

async Task Edit()
{
IsEditing = true;

//give rendering time to put the markup in and populate the reference
await InvokeAsync(StateHasChanged);
await Task.Delay(20);

if (tbRef != null)
{
await tbRef.FocusAsync();
}
}

async Task Save()
{
IsEditing = false;
await DataService.UpdateNode(Item);
await ItemTextChanged.InvokeAsync();
}
}
19 changes: 19 additions & 0 deletions treeview/rename-node/rename-node/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@layout TelerikLayout

@inherits LayoutComponentBase

<div class="page">
<div class="sidebar">
<NavMenu />
</div>

<div class="main">
<div class="top-row px-4">
<a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
</div>

<div class="content px-4">
@Body
</div>
</div>
</div>
Loading