mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-02-04 05:35:44 +00:00
193 lines
6.2 KiB
C#
193 lines
6.2 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Rendering;
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
|
|
namespace Radzen.Blazor
|
|
{
|
|
/// <summary>
|
|
/// Base class of Radzen validator components.
|
|
/// </summary>
|
|
public abstract class ValidatorBase : RadzenComponent, IRadzenFormValidator
|
|
{
|
|
/// <summary>
|
|
/// Gets or sets the form which contains this validator.
|
|
/// </summary>
|
|
[CascadingParameter]
|
|
public IRadzenForm? Form { get; set; }
|
|
|
|
/// <summary>
|
|
/// Specifies the component which this validator should validate. Must be set to the <see cref="IRadzenFormComponent.Name" /> of an existing component.
|
|
/// </summary>
|
|
[Parameter]
|
|
public string Component { get; set; } = default!;
|
|
|
|
/// <summary>
|
|
/// Specifies the message displayed when the validator is invalid.
|
|
/// </summary>
|
|
[Parameter]
|
|
public abstract string Text { get; set; }
|
|
|
|
/// <summary>
|
|
/// Determines if the validator is displayed as a popup or not. Set to <c>false</c> by default.
|
|
/// </summary>
|
|
[Parameter]
|
|
public bool Popup { get; set; }
|
|
|
|
/// <summary>
|
|
/// Returns the validity status.
|
|
/// </summary>
|
|
/// <value><c>true</c> if this validator is valid; otherwise, <c>false</c>.</value>
|
|
public bool IsValid { get; protected set; } = true;
|
|
|
|
/// <summary>
|
|
/// Provided by the <see cref="RadzenTemplateForm{TItem}" /> which contains this validator. Used internally.
|
|
/// </summary>
|
|
/// <value>The edit context.</value>
|
|
[CascadingParameter]
|
|
public EditContext? EditContext { get; set; }
|
|
|
|
/// <summary>
|
|
/// Stores the validation messages.
|
|
/// </summary>
|
|
protected ValidationMessageStore? messages;
|
|
private FieldIdentifier FieldIdentifier { get; set; }
|
|
|
|
/// <inheritdoc />
|
|
public override async Task SetParametersAsync(ParameterView parameters)
|
|
{
|
|
await base.SetParametersAsync(parameters);
|
|
|
|
if (Visible)
|
|
{
|
|
if (EditContext != null && messages == null)
|
|
{
|
|
messages = new ValidationMessageStore(EditContext);
|
|
Unsubscribe();
|
|
EditContext.OnFieldChanged += ValidateField;
|
|
EditContext.OnValidationRequested += ValidateModel;
|
|
EditContext.OnValidationStateChanged += ValidationStateChanged;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RemoveFromEditContext();
|
|
}
|
|
}
|
|
|
|
void Unsubscribe()
|
|
{
|
|
if (EditContext != null)
|
|
{
|
|
EditContext.OnFieldChanged -= ValidateField;
|
|
EditContext.OnValidationRequested -= ValidateModel;
|
|
EditContext.OnValidationStateChanged -= ValidationStateChanged;
|
|
}
|
|
}
|
|
|
|
void RemoveFromEditContext()
|
|
{
|
|
if (EditContext != null && messages != null)
|
|
{
|
|
Unsubscribe();
|
|
|
|
if (FieldIdentifier.FieldName != null)
|
|
{
|
|
messages.Clear(FieldIdentifier);
|
|
}
|
|
}
|
|
|
|
messages = null;
|
|
IsValid = true;
|
|
}
|
|
|
|
private void ValidateField(object? sender, FieldChangedEventArgs args)
|
|
{
|
|
if (Form == null) return;
|
|
var component = Form.FindComponent(Component);
|
|
if (component != null && args != null)
|
|
{
|
|
if (args.FieldIdentifier.Equals(component.FieldIdentifier))
|
|
{
|
|
ValidateModel(sender!, ValidationRequestedEventArgs.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ValidateModel(object? sender, ValidationRequestedEventArgs args)
|
|
{
|
|
if (Form == null) return;
|
|
var component = Form.FindComponent(Component);
|
|
|
|
if (component == null)
|
|
{
|
|
throw new InvalidOperationException($"Cannot find component with Name {Component}");
|
|
}
|
|
|
|
if (component.FieldIdentifier.FieldName != null)
|
|
{
|
|
var previousIsValid = IsValid;
|
|
IsValid = Validate(component);
|
|
|
|
messages?.Clear(component.FieldIdentifier);
|
|
|
|
if (!IsValid)
|
|
{
|
|
messages?.Add(component.FieldIdentifier, Text);
|
|
}
|
|
|
|
if (previousIsValid != IsValid)
|
|
{
|
|
EditContext?.NotifyValidationStateChanged();
|
|
}
|
|
}
|
|
|
|
FieldIdentifier = component.FieldIdentifier;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override string GetComponentCssClass()
|
|
{
|
|
return $"rz-message rz-messages-error {(Popup ? "rz-message-popup" : "")}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs validation against the specified component.
|
|
/// </summary>
|
|
/// <param name="component">The component to validate.</param>
|
|
/// <returns><c>true</c> if validation is successful, <c>false</c> otherwise.</returns>
|
|
protected abstract bool Validate(IRadzenFormComponent component);
|
|
|
|
private void ValidationStateChanged(object? sender, ValidationStateChangedEventArgs e)
|
|
{
|
|
StateHasChanged();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Dispose()
|
|
{
|
|
base.Dispose();
|
|
|
|
RemoveFromEditContext();
|
|
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(builder);
|
|
if (Visible && !IsValid)
|
|
{
|
|
builder.OpenElement(0, "div");
|
|
builder.AddAttribute(1, "style", Style);
|
|
builder.AddAttribute(2, "class", GetCssClass());
|
|
builder.AddMultipleAttributes(3, Attributes);
|
|
builder.AddContent(4, Text);
|
|
builder.CloseElement();
|
|
}
|
|
}
|
|
}
|
|
}
|