Browse Source

* Updated UserEditForm to use MudBlazor for name field.

* Fixed RequiredIfAttribute, so that it shows up in the
  ValidationMessage component.
master^2
Jaime Wyant 4 years ago
parent
commit
4335e38616
  1. 106
      531Calculator/Components/MyValidationMessage.cs
  2. 9
      531Calculator/Components/UserEditForm.razor
  3. 3
      531Calculator/DataAnnotations/RequiredIfAttribute.cs

106
531Calculator/Components/MyValidationMessage.cs

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Rendering;
namespace FiveThreeOneCalculator.Components
{
/// <summary>
/// Displays a list of validation messages for a specified field within a cascaded <see cref="EditContext"/>.
/// </summary>
public class MyValidationMessage<TValue> : ComponentBase, IDisposable
{
private EditContext? _previousEditContext;
private Expression<Func<TValue>>? _previousFieldAccessor;
private readonly EventHandler<ValidationStateChangedEventArgs>? _validationStateChangedHandler;
private FieldIdentifier _fieldIdentifier;
/// <summary>
/// Gets or sets a collection of additional attributes that will be applied to the created <c>div</c> element.
/// </summary>
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary<string, object>? AdditionalAttributes { get; set; }
[CascadingParameter] EditContext CurrentEditContext { get; set; } = default!;
/// <summary>
/// Specifies the field for which validation messages should be displayed.
/// </summary>
[Parameter] public Expression<Func<TValue>>? For { get; set; }
/// <summary>`
/// Constructs an instance of <see cref="ValidationMessage{TValue}"/>.
/// </summary>
public MyValidationMessage()
{
_validationStateChangedHandler = (sender, eventArgs) => StateHasChanged();
}
/// <inheritdoc />
protected override void OnParametersSet()
{
if (CurrentEditContext == null)
{
throw new InvalidOperationException($"{GetType()} requires a cascading parameter " +
$"of type {nameof(EditContext)}. For example, you can use {GetType()} inside " +
$"an {nameof(EditForm)}.");
}
if (For == null) // Not possible except if you manually specify T
{
throw new InvalidOperationException($"{GetType()} requires a value for the " +
$"{nameof(For)} parameter.");
}
else if (For != _previousFieldAccessor)
{
_fieldIdentifier = FieldIdentifier.Create(For);
_previousFieldAccessor = For;
}
if (CurrentEditContext != _previousEditContext)
{
DetachValidationStateChangedListener();
CurrentEditContext.OnValidationStateChanged += _validationStateChangedHandler;
_previousEditContext = CurrentEditContext;
}
}
/// <inheritdoc />
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
var l = CurrentEditContext.GetValidationMessages().ToArray();
foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier))
{
builder.OpenElement(0, "div");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "class", "validation-message");
builder.AddContent(3, message);
builder.CloseElement();
}
}
/// <summary>
/// Called to dispose this instance.
/// </summary>
/// <param name="disposing"><see langword="true"/> if called within <see cref="IDisposable.Dispose"/>.</param>
protected virtual void Dispose(bool disposing)
{
}
void IDisposable.Dispose()
{
DetachValidationStateChangedListener();
Dispose(disposing: true);
}
private void DetachValidationStateChangedListener()
{
if (_previousEditContext != null)
{
_previousEditContext.OnValidationStateChanged -= _validationStateChangedHandler;
}
}
}
}

9
531Calculator/Components/UserEditForm.razor

@ -21,12 +21,9 @@
@if (NameRequired) @if (NameRequired)
{ {
<MudItem xs="12">
<label for="name" class="pt-7 text-lg font-semibold">Name</label>
<div>
<InputText id="name" @bind-Value="UserModel.Name" class="input-text" />
<ValidationMessage For="@(() => UserModel.Name)" />
</div>
<MudItem xs="10">
<MudTextField @bind-Value="UserModel.Name" Label="Name" />
<ValidationMessage For="@(() => UserModel.Name)" />
</MudItem> </MudItem>
} }

3
531Calculator/DataAnnotations/RequiredIfAttribute.cs

@ -32,7 +32,8 @@ namespace FiveThreeOneCalculator.DataAnnotations
if (!_innerAttribute.IsValid(value)) if (!_innerAttribute.IsValid(value))
{ {
string name = validationContext.DisplayName; string name = validationContext.DisplayName;
return new ValidationResult(ErrorMessage = name + " Is required.");
return new ValidationResult(ErrorMessage = name + " Is required.",
new string[] { name });
} }
} }
return ValidationResult.Success; return ValidationResult.Success;

Loading…
Cancel
Save