Custom Input
Per facilitare lo sviluppo dei form, sfruttando la struttura a componenti tipica delle applicazioni Blazor, possiamo costruire dei componenti custom.
Evoluzione di Select
Uno dei componenti più sfrutatti è sicuramente InputSelect
.
Il componente InputSelect
genera l’HTML del tag <input>
e le relative option
.
Vediamo un esempio:
<InputSelect id="jobcategory" @bind-Value="@JobCategoryId" class="form-control">
@foreach (var jobCategory in JobCategories)
{
<option value="@jobCategory.JobCategoryId">
@jobCategory.JobCategoryName
</option>
}
</InputSelect>
Costruzione del componente
Per costruire un componente custom è necessario partire da una base.
Dato che AspNet.Core è un progetto open source possiamo partire dai sorgenti del componente base.
Collegandoci al sito https://github.com/aspnet/AspNetCore possiamo ricercare InputSelect e scaricare il relativo sorgente (vedasi qui).
Evoluzione
Creare un componente derivato che evolva il componente originale è relativamente semplice.
Abbiamo due strade possibili:
- estendere la classe base
InputSelect<TValue>
- creare un componente ex novo estendendo
InputBase<TValue>
Sorgente di partenza
Questo è il sorgente completo del componente InputSelect
:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components.Rendering;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// A dropdown selection component.
/// </summary>
public class InputSelect<TValue> : InputBase<TValue>
{
/// <summary>
/// Gets or sets the child content to be rendering inside the select element.
/// </summary>
[Parameter] public RenderFragment? ChildContent { get; set; }
/// <inheritdoc />
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "select");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "class", CssClass);
builder.AddAttribute(3, "value", BindConverter.FormatValue(CurrentValueAsString));
builder.AddAttribute(4, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.AddContent(5, ChildContent);
builder.CloseElement();
}
/// <inheritdoc />
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage)
=> this.TryParseSelectableValueFromString(value, out result, out validationErrorMessage);
}
}
Se volessivo ad esempio creare un componente per filtrare i valori sulla base di un campo di testo dovremo effettuare l’override del metodo BuildRenderTree
.
A quel punto il nuovo componente potrebbe essere utilizzato direttamente dalle pagine Razor:
<CustomInputSelect Filtering="true" ... />