Skip to content

Commit cff6541

Browse files
dimodintacheva
andauthored
Update Grid Remote Validation app (#296)
* Update Grid Remote Validation app * Update grid/remote-validation/Client/Pages/Index.razor Co-authored-by: Nadezhda Tacheva <73842592+ntacheva@users.noreply.github.com> * Update grid/remote-validation/Client/Pages/Index.razor Co-authored-by: Nadezhda Tacheva <73842592+ntacheva@users.noreply.github.com> * Update grid/remote-validation/Client/Pages/Index.razor --------- Co-authored-by: Nadezhda Tacheva <73842592+ntacheva@users.noreply.github.com>
1 parent 816bb8c commit cff6541

36 files changed

+805
-588
lines changed
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
<Router AppAssembly="@typeof(Program).Assembly">
1+
<Router AppAssembly="@typeof(App).Assembly">
22
<Found Context="routeData">
33
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
4+
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
45
</Found>
56
<NotFound>
7+
<PageTitle>Not found</PageTitle>
68
<LayoutView Layout="@typeof(MainLayout)">
7-
<p>Sorry, there's nothing at this address.</p>
9+
<p role="alert">Sorry, there's nothing at this address.</p>
810
</LayoutView>
911
</NotFound>
1012
</Router>
13+
14+
Lines changed: 88 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,152 @@
11
@page "/"
22

33
@using RemoteValidationWasm.Shared
4-
@using RemoteValidationWasm.Services
5-
@inject WeatherForecastService ForecastService
4+
@using RemoteValidationWasm.Client.Services
65

7-
Try Inserting a record with a Date that already exists in the grid.
8-
<br />
9-
Try Editing a record and adding the letter "a" in the Summary.
10-
<br />
11-
This sample uses a Notification component to show the error message to supplement any data annotation validation in the Popup edit mode, but it can also work with other edit modes.
6+
@inject WeatherForecastService ForecastService
127

13-
<TelerikGrid Data="@forecasts" Height="550px" Sortable="true" Pageable="true" PageSize="20"
14-
OnUpdate="@UpdateHandler" OnDelete="@DeleteHandler" OnCreate="@CreateHandler" EditMode="@GridEditMode.Popup">
8+
<PageTitle>Index</PageTitle>
9+
10+
<p>To trigger remote validation:</p>
11+
12+
<ul>
13+
<li>Add a row with a Date that already exists.</li>
14+
<li>Update a row that does not contain <em>Q</em> in the Summary.</li>
15+
<li>Delete one of the first five rows.</li>
16+
</ul>
17+
18+
<TelerikGrid Data="@GridData"
19+
EditMode="@GridEditMode.Popup"
20+
OnCreate="@CreateHandler"
21+
OnUpdate="@UpdateHandler"
22+
OnDelete="@DeleteHandler"
23+
Sortable="true"
24+
Pageable="true"
25+
Height="500px">
26+
<GridToolBarTemplate>
27+
<GridCommandButton Command="Add" Icon="@SvgIcon.Plus">Add Item</GridCommandButton>
28+
</GridToolBarTemplate>
1529
<GridColumns>
16-
<GridColumn Field="Id" Title="Id" Width="100px" Editable="false" Groupable="false" />
17-
<GridColumn Field="Date" DisplayFormat="{0:dddd, dd MMM yyyy}" />
18-
<GridColumn Field="TemperatureC" Title="Temp. C" DisplayFormat="{0:N1}" />
19-
<GridColumn Field="TemperatureF" Title="Temp. F" DisplayFormat="{0:N1}" />
20-
<GridColumn Field="Summary" />
21-
<GridCommandColumn Width="200px" Resizable="false">
22-
<GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
23-
<GridCommandButton Command="Edit" Icon="edit" ThemeColor="@ThemeConstants.Button.ThemeColor.Primary">Edit</GridCommandButton>
24-
<GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
25-
<GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
30+
<GridColumn Field="@nameof(WeatherForecast.Id)" Width="100px" Editable="false" Groupable="false" />
31+
<GridColumn Field="@nameof(WeatherForecast.Date)" DisplayFormat="{0:dddd, dd MMM yyyy}" />
32+
<GridColumn Field="@nameof(WeatherForecast.TemperatureC)" Title="Temp. C" DisplayFormat="{0:N1}" />
33+
<GridColumn Field="@nameof(WeatherForecast.TemperatureF)" Title="Temp. F" DisplayFormat="{0:N1}" />
34+
<GridColumn Field="@nameof(WeatherForecast.Summary)" />
35+
<GridCommandColumn Width="200px">
36+
<GridCommandButton Command="Edit" Icon="@SvgIcon.Pencil">Edit</GridCommandButton>
37+
<GridCommandButton Command="Delete" Icon="@SvgIcon.Trash">Delete</GridCommandButton>
38+
<GridCommandButton Command="Save" Icon="@SvgIcon.Save" ShowInEdit="true">Save</GridCommandButton>
39+
<GridCommandButton Command="Cancel" Icon="@SvgIcon.Cancel" ShowInEdit="true">Cancel</GridCommandButton>
2640
</GridCommandColumn>
2741
</GridColumns>
28-
<GridToolBar>
29-
<GridCommandButton Command="Add" Icon="plus" ThemeColor="@ThemeConstants.Button.ThemeColor.Primary">Add Forecast</GridCommandButton>
30-
</GridToolBar>
3142
</TelerikGrid>
3243

33-
<TelerikNotification @ref="@Notification"
44+
<TelerikNotification @ref="@NotificationRef"
3445
HorizontalPosition="@NotificationHorizontalPosition.Center"
3546
VerticalPosition="@NotificationVerticalPosition.Top"
36-
Class="big-notification">
47+
Class="above-modal-overlay">
3748
</TelerikNotification>
3849

50+
<style>
51+
.above-modal-overlay {
52+
z-index: 22222;
53+
}
54+
</style>
3955

4056
@code {
41-
List<WeatherForecast> forecasts { get; set; }
42-
bool errorExists { get; set; }
43-
TelerikNotification Notification { get; set; }
57+
private List<WeatherForecast> GridData { get; set; } = new();
58+
59+
#region UI for Validation Errors
60+
61+
private TelerikNotification? NotificationRef { get; set; }
4462

45-
void ShowErrorNotification(string message)
63+
private void ShowErrorNotification(string message)
4664
{
47-
Notification.Show(new NotificationModel
65+
NotificationRef?.Show(new NotificationModel
4866
{
4967
CloseAfter = 0,
5068
Text = message,
5169
ThemeColor = ThemeConstants.Notification.ThemeColor.Error
5270
});
5371
}
5472

55-
protected override async Task OnInitializedAsync()
56-
{
57-
await GetForecasts();
58-
}
73+
#endregion UI for Validation Errors
5974

60-
async Task GetForecasts()
61-
{
62-
forecasts = await ForecastService.GetForecastListAsync(DateTime.Now);
63-
}
64-
65-
// sample error handling for the CUD operations - in this sample through simplistic error messsages coming from the server
75+
#region Grid Data Operations
6676

67-
public async Task DeleteHandler(GridCommandEventArgs args)
77+
private async Task CreateHandler(GridCommandEventArgs args)
6878
{
69-
WeatherForecast currItem = args.Item as WeatherForecast;
79+
WeatherForecast currItem = (WeatherForecast)args.Item;
7080

7181
try
7282
{
73-
await ForecastService.DeleteForecastAsync(currItem);
74-
// update the view data
75-
forecasts.Remove(currItem);
83+
WeatherForecast insertedForecast = await ForecastService.InsertForecastAsync(currItem);
84+
// Update the view data, otherwise reload the Grid data.
85+
GridData.Insert(0, insertedForecast);
7686
}
7787
catch (Exception ex)
7888
{
79-
// show information to the user
89+
// Keep the Grid in edit mode.
90+
args.IsCancelled = true;
91+
8092
ShowErrorNotification(ex.Message);
8193
}
8294
}
8395

84-
public async Task CreateHandler(GridCommandEventArgs args)
96+
private async Task UpdateHandler(GridCommandEventArgs args)
8597
{
86-
WeatherForecast currItem = args.Item as WeatherForecast;
98+
WeatherForecast currItem = (WeatherForecast)args.Item;
99+
100+
await Task.Delay(1);
87101

88102
try
89103
{
90-
// get the inserted data from the server in case it alters it further (e.g., provides an ID)
91-
WeatherForecast insertedForecast = await ForecastService.InsertForecastAsync(currItem);
92-
// update the view data
93-
forecasts.Insert(0, insertedForecast);
104+
WeatherForecast updatedForecast = await ForecastService.UpdateForecastAsync(currItem);
105+
// Update the view data, otherwise reload the Grid data.
106+
var index = GridData.FindIndex(i => i.Id == updatedForecast.Id);
107+
if (index != -1)
108+
{
109+
GridData[index] = updatedForecast;
110+
}
94111
}
95112
catch (Exception ex)
96113
{
97-
// keep the grid in insert mode
114+
// Keep the Grid in edit mode.
98115
args.IsCancelled = true;
99-
// show information to the user
116+
100117
ShowErrorNotification(ex.Message);
101118
}
102119
}
103120

104-
public async Task UpdateHandler(GridCommandEventArgs args)
121+
private async Task DeleteHandler(GridCommandEventArgs args)
105122
{
106-
WeatherForecast currItem = args.Item as WeatherForecast;
123+
WeatherForecast currItem = (WeatherForecast)args.Item;
107124

108125
try
109126
{
110-
// get the inserted data from the server in case it alters it further
111-
WeatherForecast updatedForecast = await ForecastService.UpdateForecastAsync(currItem);
112-
// update the view data
113-
var index = forecasts.FindIndex(i => i.Id == updatedForecast.Id);
114-
if (index != -1)
115-
{
116-
forecasts[index] = updatedForecast;
117-
}
127+
await ForecastService.DeleteForecastAsync(currItem);
128+
// Update the view data, otherwise reload the Grid data.
129+
GridData.Remove(currItem);
118130
}
119131
catch (Exception ex)
120132
{
121-
// keep the grid in edit mode
122-
args.IsCancelled = true;
123-
// show information to the user
124133
ShowErrorNotification(ex.Message);
125134
}
126135
}
127-
}
128136

129-
<style>
130-
.big-notification .k-notification-container .k-notification-wrap {
131-
width: 350px;
132-
height: 100px;
133-
align-items: center;
134-
font-size: 32px;
135-
}
137+
#endregion Grid Data Operations
136138

137-
.big-notification .k-notification-container .k-notification-wrap .k-icon.k-i-error::before {
138-
font-size: 32px;
139-
}
139+
#region Grid Data Generation
140+
141+
protected override async Task OnInitializedAsync()
142+
{
143+
await GetForecasts();
144+
}
140145

141-
.big-notification {
142-
z-index: 654321;
146+
private async Task GetForecasts()
147+
{
148+
GridData = await ForecastService.GetForecastListAsync(DateTime.Now);
143149
}
144-
</style>
150+
151+
#endregion Grid Data Generation
152+
}
Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
1-
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
2-
using Microsoft.Extensions.DependencyInjection;
3-
using RemoteValidationWasm.Services;
4-
using System.Threading.Tasks;
5-
using System.Net.Http;
6-
using System;
1+
using Microsoft.AspNetCore.Components.Web;
2+
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
3+
using RemoteValidationWasm.Client;
4+
using RemoteValidationWasm.Client.Services;
75

8-
namespace RemoteValidationWasm.Client
9-
{
10-
public class Program
11-
{
12-
public static async Task Main(string[] args)
13-
{
14-
var builder = WebAssemblyHostBuilder.CreateDefault(args);
15-
builder.RootComponents.Add<App>("app");
16-
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
17-
builder.Services.AddScoped<WeatherForecastService>();
18-
builder.Services.AddTelerikBlazor();
6+
var builder = WebAssemblyHostBuilder.CreateDefault(args);
7+
builder.RootComponents.Add<App>("#app");
8+
builder.RootComponents.Add<HeadOutlet>("head::after");
9+
10+
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
11+
12+
builder.Services.AddScoped<WeatherForecastService>();
13+
14+
builder.Services.AddTelerikBlazor();
15+
16+
await builder.Build().RunAsync();
1917

20-
await builder.Build().RunAsync();
21-
}
22-
}
23-
}

grid/remote-validation/Client/Properties/launchSettings.json

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,28 @@
33
"windowsAuthentication": false,
44
"anonymousAuthentication": true,
55
"iisExpress": {
6-
"applicationUrl": "http://localhost:62353/",
7-
"sslPort": 0
6+
"applicationUrl": "http://localhost:62233",
7+
"sslPort": 44398
88
}
99
},
1010
"profiles": {
11-
"IIS Express": {
12-
"commandName": "IISExpress",
11+
"RemoteValidationWasm": {
12+
"commandName": "Project",
1313
"launchBrowser": true,
14+
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
15+
"applicationUrl": "https://localhost:7206;http://localhost:5154",
1416
"environmentVariables": {
1517
"ASPNETCORE_ENVIRONMENT": "Development"
16-
}
18+
},
19+
"dotnetRunMessages": true
1720
},
18-
"RemoteValidationWasm.Client": {
19-
"commandName": "Project",
21+
"IIS Express": {
22+
"commandName": "IISExpress",
2023
"launchBrowser": true,
24+
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
2125
"environmentVariables": {
2226
"ASPNETCORE_ENVIRONMENT": "Development"
23-
},
24-
"applicationUrl": "http://localhost:62355/"
27+
}
2528
}
2629
}
2730
}
Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
2-
3-
<PropertyGroup>
4-
<TargetFramework>netstandard2.1</TargetFramework>
5-
<RazorLangVersion>3.0</RazorLangVersion>
6-
</PropertyGroup>
7-
8-
<ItemGroup>
9-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" />
10-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.1" PrivateAssets="all" />
11-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.1" PrivateAssets="all" />
12-
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
13-
<PackageReference Include="Telerik.UI.for.Blazor" Version="3.4.0" />
14-
</ItemGroup>
15-
<ItemGroup>
16-
<ProjectReference Include="..\Shared\RemoteValidationWasm.Shared.csproj" />
17-
</ItemGroup>
18-
19-
</Project>
1+
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<PropertyGroup Condition=" '$(RunConfiguration)' == 'RemoteValidationWasm' ">
10+
<ExternalConsole>true</ExternalConsole>
11+
</PropertyGroup>
12+
<ItemGroup>
13+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.*" />
14+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.*" PrivateAssets="all" />
15+
<PackageReference Include="Telerik.UI.for.Blazor" Version="*" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\Shared\RemoteValidationWasm.Shared.csproj" />
20+
</ItemGroup>
21+
22+
</Project>

0 commit comments

Comments
 (0)