ADD: continue the tutorial since DI IOC

master
Lucie Bedouret 3 years ago
parent 8c2bac92e9
commit b102254321

@ -1,13 +1,10 @@
<Router AppAssembly="@typeof(App).Assembly"> <Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData"> <Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found> </Found>
<NotFound> <NotFound>
<PageTitle>Not found</PageTitle> <PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)"> <p>Sorry, there's nothing at this address.</p>
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound> </NotFound>
</Router> </Router>

@ -0,0 +1,40 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace myBlazorApp.Models
{
public class ItemModel
{
public int Id { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The display name must not exceed 50 characters.")]
public string DisplayName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The name must not exceed 50 characters.")]
[RegularExpression(@"^[a-z''-'\s]{1,40}$", ErrorMessage = "Only lowercase characters are accepted.")]
public string Name { get; set; }
[Required]
[Range(1, 64)]
public int StackSize { get; set; }
[Required]
[Range(1, 125)]
public int MaxDurability { get; set; }
public List<string> EnchantCategories { get; set; }
public List<string> RepairWith { get; set; }
[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "You must agree to the terms.")]
public bool AcceptCondition { get; set; }
[Required(ErrorMessage = "The image of the item is mandatory!")]
public byte[] ImageContent { get; set; }
}
}

@ -0,0 +1,69 @@
@page "/add"
<h3>Add</h3>
<EditForm Model="@itemModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
<label for="display-name">
Display name:
<InputText id="display-name" @bind-Value="itemModel.DisplayName" />
</label>
</p>
<p>
<label for="name">
Name:
<InputText id="name" @bind-Value="itemModel.Name" />
</label>
</p>
<p>
<label for="stack-size">
Stack size:
<InputNumber id="stack-size" @bind-Value="itemModel.StackSize" />
</label>
</p>
<p>
<label for="max-durability">
Max durability:
<InputNumber id="max-durability" @bind-Value="itemModel.MaxDurability" />
</label>
</p>
<p>
Enchant categories:
<div>
@foreach (var item in enchantCategories)
{
<label>
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" />@item
</label>
}
</div>
</p>
<p>
Repair with:
<div>
@foreach (var item in repairWith)
{
<label>
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" />@item
</label>
}
</div>
</p>
<p>
<label>
Item image:
<InputFile OnChange="@LoadImage" accept=".png" />
</label>
</p>
<p>
<label>
Accept Condition:
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
</label>
</p>
<button type="submit">Submit</button>
</EditForm>

@ -0,0 +1,128 @@
using System;
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using myBlazorApp.Models;
namespace myBlazorApp.Pages
{
public partial class Add
{
[Inject]
public ILocalStorageService LocalStorage { get; set; }
[Inject]
public IWebHostEnvironment WebHostEnvironment { get; set; }
[Inject]
public NavigationManager NavigationManager { get; set; }
/// <summary>
/// The default enchant categories.
/// </summary>
private List<string> enchantCategories = new List<string>() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
/// <summary>
/// The default repair with.
/// </summary>
private List<string> repairWith = new List<string>() { "oak_planks", "spruce_planks", "birch_planks", "jungle_planks", "acacia_planks", "dark_oak_planks", "crimson_planks", "warped_planks" };
/// <summary>
/// The current item model
/// </summary>
private ItemModel itemModel = new()
{
EnchantCategories = new List<string>(),
RepairWith = new List<string>()
};
private async void HandleValidSubmit()
{
// Get the current data
var currentData = await LocalStorage.GetItemAsync<List<Item>>("data");
// Simulate the Id
itemModel.Id = currentData.Max(s => s.Id) + 1;
// Add the item to the current data
currentData.Add(new Item
{
Id = itemModel.Id,
DisplayName = itemModel.DisplayName,
Name = itemModel.Name,
RepairWith = itemModel.RepairWith,
EnchantCategories = itemModel.EnchantCategories,
MaxDurability = itemModel.MaxDurability,
StackSize = itemModel.StackSize,
CreatedDate = DateTime.Now
});
// Save the image
var imagePathInfo = new DirectoryInfo($"{WebHostEnvironment.WebRootPath}/images");
// Check if the folder "images" exist
if (!imagePathInfo.Exists)
{
imagePathInfo.Create();
}
// Determine the image name
var fileName = new FileInfo($"{imagePathInfo}/{itemModel.Name}.png");
// Write the file content
await File.WriteAllBytesAsync(fileName.FullName, itemModel.ImageContent);
// Save the data
await LocalStorage.SetItemAsync("data", currentData);
NavigationManager.NavigateTo("list");
}
private async Task LoadImage(InputFileChangeEventArgs e)
{
// Set the content of the image to the model
using (var memoryStream = new MemoryStream())
{
await e.File.OpenReadStream().CopyToAsync(memoryStream);
itemModel.ImageContent = memoryStream.ToArray();
}
}
private void OnEnchantCategoriesChange(string item, object checkedValue)
{
if ((bool)checkedValue)
{
if (!itemModel.EnchantCategories.Contains(item))
{
itemModel.EnchantCategories.Add(item);
}
return;
}
if (itemModel.EnchantCategories.Contains(item))
{
itemModel.EnchantCategories.Remove(item);
}
}
private void OnRepairWithChange(string item, object checkedValue)
{
if ((bool)checkedValue)
{
if (!itemModel.RepairWith.Contains(item))
{
itemModel.RepairWith.Add(item);
}
return;
}
if (itemModel.RepairWith.Contains(item))
{
itemModel.RepairWith.Remove(item);
}
}
}
}

@ -0,0 +1,4 @@
@page "/BlazorRoute"
@page "/DifferentBlazorRoute"
<h1>Blazor routing</h1>

@ -4,11 +4,32 @@
<h3>List</h3> <h3>List</h3>
<div>
<NavLink class="btn btn-primary" href="Add" Match="NavLinkMatch.All">
<i class="fa fa-plus"/> Ajouter :)
</NavLink>
</div>
<DataGrid TItem="Item" <DataGrid TItem="Item"
Data="@items" Data="@items"
PageSize="int.MaxValue" ReadData="@OnReadData"
TotalItems="@totalItem"
PageSize="10"
ShowPager
Responsive> Responsive>
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="#" /> <DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="#" />
<DataGridColumn TItem="Item" Field="@nameof(Item.Id)" Caption="Image">
<DisplayTemplate>
@if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{context.Name}.png"))
{
<img src="images/@(context.Name).png" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="max-width: 150px" />
}
else
{
<img src="images/default.png" class="img-thumbnail" title="@context.DisplayName" alt="@context.DisplayName" style="max-width: 150px" />
}
</DisplayTemplate>
</DataGridColumn>
<DataGridColumn TItem="Item" Field="@nameof(Item.DisplayName)" Caption="Display name" /> <DataGridColumn TItem="Item" Field="@nameof(Item.DisplayName)" Caption="Display name" />
<DataGridColumn TItem="Item" Field="@nameof(Item.StackSize)" Caption="Stack size" /> <DataGridColumn TItem="Item" Field="@nameof(Item.StackSize)" Caption="Stack size" />
<DataGridColumn TItem="Item" Field="@nameof(Item.MaxDurability)" Caption="Maximum durability" /> <DataGridColumn TItem="Item" Field="@nameof(Item.MaxDurability)" Caption="Maximum durability" />

@ -1,4 +1,6 @@
using System; using System;
using Blazored.LocalStorage;
using Blazorise.DataGrid;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using myBlazorApp.Models; using myBlazorApp.Models;
@ -6,17 +8,52 @@ namespace myBlazorApp.Pages
{ {
public partial class List public partial class List
{ {
private Item[] items; private List<Item> items;
private int totalItem { get; set; }
[Inject] [Inject]
public HttpClient Http { get; set; } public HttpClient Http { get; set; }
[Inject]
public ILocalStorageService LocalStorage { get; set; }
[Inject]
public IWebHostEnvironment WebHostEnvironment { get; set; }
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public NavigationManager NavigationManager { get; set; }
protected override async Task OnInitializedAsync() protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(!firstRender)
{
return;
}
var currentData = await LocalStorage.GetItemAsync<Item[]>("data");
if (currentData == null)
{
var originalData = Http.GetFromJsonAsync<Item[]>($"{NavigationManager.BaseUri}fake-data.json").Result;
await LocalStorage.SetItemAsync("data", originalData);
}
}
private async Task OnReadData(DataGridReadDataEventArgs<Item> e)
{ {
items = await Http.GetFromJsonAsync<Item[]>($"{NavigationManager.BaseUri}fake-data.json"); if (e.CancellationToken.IsCancellationRequested)
{
return;
}
var response = (await LocalStorage.GetItemAsync<Item[]>("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList();
if (!e.CancellationToken.IsCancellationRequested)
{
totalItem = (await LocalStorage.GetItemAsync<List<Item>>("data")).Count;
items = new List<Item>(response);
}
} }
} }
} }

@ -1,8 +1,10 @@
using Blazorise; using Blazored.LocalStorage;
using Blazorise;
using Blazorise.Bootstrap; using Blazorise.Bootstrap;
using Blazorise.Icons.FontAwesome; using Blazorise.Icons.FontAwesome;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Blazored.LocalStorage;
using myBlazorApp.Data; using myBlazorApp.Data;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -15,6 +17,7 @@ builder.Services.AddHttpClient();
builder.Services.AddBlazorise(); builder.Services.AddBlazorise();
builder.Services.AddBootstrapProviders(); builder.Services.AddBootstrapProviders();
builder.Services.AddFontAwesomeIcons(); builder.Services.AddFontAwesomeIcons();
builder.Services.AddBlazoredLocalStorage();
var app = builder.Build(); var app = builder.Build();

@ -12,6 +12,7 @@
<None Remove="Blazorise.DataGrid" /> <None Remove="Blazorise.DataGrid" />
<None Remove="Blazorise.Bootstrap" /> <None Remove="Blazorise.Bootstrap" />
<None Remove="Blazorise.Icons.FontAwesome" /> <None Remove="Blazorise.Icons.FontAwesome" />
<None Remove="Blazored.LocalStorage" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
@ -21,5 +22,6 @@
<PackageReference Include="Blazorise.DataGrid" Version="1.1.2" /> <PackageReference Include="Blazorise.DataGrid" Version="1.1.2" />
<PackageReference Include="Blazorise.Bootstrap" Version="1.1.2" /> <PackageReference Include="Blazorise.Bootstrap" Version="1.1.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.1.2" /> <PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.1.2" />
<PackageReference Include="Blazored.LocalStorage" Version="4.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Loading…
Cancel
Save