Blazor API Review: Forms

Fixes: #12549
This commit is contained in:
Ryan Nowak 2019-07-27 16:48:17 -07:00 committed by Ryan Nowak
parent 56193850b9
commit 82478eac6b
19 changed files with 132 additions and 138 deletions

View File

@ -419,8 +419,10 @@ namespace Microsoft.AspNetCore.Components.Forms
public Microsoft.AspNetCore.Components.Forms.FieldIdentifier Field(string fieldName) { throw null; }
public System.Collections.Generic.IEnumerable<string> GetValidationMessages() { throw null; }
public System.Collections.Generic.IEnumerable<string> GetValidationMessages(Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { throw null; }
public System.Collections.Generic.IEnumerable<string> GetValidationMessages(System.Linq.Expressions.Expression<System.Func<object>> accessor) { throw null; }
public bool IsModified() { throw null; }
public bool IsModified(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { throw null; }
public bool IsModified(System.Linq.Expressions.Expression<System.Func<object>> accessor) { throw null; }
public void MarkAsUnmodified() { }
public void MarkAsUnmodified(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { }
public void NotifyFieldChanged(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { }
@ -431,24 +433,20 @@ namespace Microsoft.AspNetCore.Components.Forms
{
public static Microsoft.AspNetCore.Components.Forms.EditContext AddDataAnnotationsValidation(this Microsoft.AspNetCore.Components.Forms.EditContext editContext) { throw null; }
}
public static partial class EditContextExpressionExtensions
public sealed partial class FieldChangedEventArgs : System.EventArgs
{
public static System.Collections.Generic.IEnumerable<string> GetValidationMessages(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, System.Linq.Expressions.Expression<System.Func<object>> accessor) { throw null; }
public static bool IsModified(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, System.Linq.Expressions.Expression<System.Func<object>> accessor) { throw null; }
}
public sealed partial class FieldChangedEventArgs
{
internal FieldChangedEventArgs() { }
public FieldChangedEventArgs(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { }
public Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct FieldIdentifier
public readonly partial struct FieldIdentifier : System.IEquatable<Microsoft.AspNetCore.Components.Forms.FieldIdentifier>
{
private readonly object _dummy;
public FieldIdentifier(object model, string fieldName) { throw null; }
public string FieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public object Model { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public static Microsoft.AspNetCore.Components.Forms.FieldIdentifier Create<T>(System.Linq.Expressions.Expression<System.Func<T>> accessor) { throw null; }
public bool Equals(Microsoft.AspNetCore.Components.Forms.FieldIdentifier otherIdentifier) { throw null; }
public override bool Equals(object obj) { throw null; }
public override int GetHashCode() { throw null; }
}
@ -457,24 +455,23 @@ namespace Microsoft.AspNetCore.Components.Forms
public ValidationMessageStore(Microsoft.AspNetCore.Components.Forms.EditContext editContext) { }
public System.Collections.Generic.IEnumerable<string> this[Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier] { get { throw null; } }
public System.Collections.Generic.IEnumerable<string> this[System.Linq.Expressions.Expression<System.Func<object>> accessor] { get { throw null; } }
public void Add(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier, System.Collections.Generic.IEnumerable<string> messages) { }
public void Add(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier, string message) { }
public void AddRange(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier, System.Collections.Generic.IEnumerable<string> messages) { }
public void Add(System.Linq.Expressions.Expression<System.Func<object>> accessor, System.Collections.Generic.IEnumerable<string> messages) { }
public void Add(System.Linq.Expressions.Expression<System.Func<object>> accessor, string message) { }
public void Clear() { }
public void Clear(in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { }
public void Clear(System.Linq.Expressions.Expression<System.Func<object>> accessor) { }
}
public static partial class ValidationMessageStoreExpressionExtensions
public sealed partial class ValidationRequestedEventArgs : System.EventArgs
{
public static void Add(this Microsoft.AspNetCore.Components.Forms.ValidationMessageStore store, System.Linq.Expressions.Expression<System.Func<object>> accessor, string message) { }
public static void AddRange(this Microsoft.AspNetCore.Components.Forms.ValidationMessageStore store, System.Linq.Expressions.Expression<System.Func<object>> accessor, System.Collections.Generic.IEnumerable<string> messages) { }
public static void Clear(this Microsoft.AspNetCore.Components.Forms.ValidationMessageStore store, System.Linq.Expressions.Expression<System.Func<object>> accessor) { }
public static readonly new Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs Empty;
public ValidationRequestedEventArgs() { }
}
public sealed partial class ValidationRequestedEventArgs
public sealed partial class ValidationStateChangedEventArgs : System.EventArgs
{
internal ValidationRequestedEventArgs() { }
}
public sealed partial class ValidationStateChangedEventArgs
{
internal ValidationStateChangedEventArgs() { }
public static readonly new Microsoft.AspNetCore.Components.Forms.ValidationStateChangedEventArgs Empty;
public ValidationStateChangedEventArgs() { }
}
}
namespace Microsoft.AspNetCore.Components.Rendering

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace Microsoft.AspNetCore.Components.Forms
{
@ -158,6 +159,16 @@ namespace Microsoft.AspNetCore.Components.Forms
}
}
/// <summary>
/// Gets the current validation messages for the specified field.
///
/// This method does not perform validation itself. It only returns messages determined by previous validation actions.
/// </summary>
/// <param name="accessor">Identifies the field whose current validation messages should be returned.</param>
/// <returns>The current validation messages for the specified field.</returns>
public IEnumerable<string> GetValidationMessages(Expression<Func<object>> accessor)
=> GetValidationMessages(FieldIdentifier.Create(accessor));
/// <summary>
/// Determines whether the specified fields in this <see cref="EditContext"/> has been modified.
/// </summary>
@ -167,6 +178,14 @@ namespace Microsoft.AspNetCore.Components.Forms
? state.IsModified
: false;
/// <summary>
/// Determines whether the specified fields in this <see cref="EditContext"/> has been modified.
/// </summary>
/// <param name="accessor">Identifies the field whose current validation messages should be returned.</param>
/// <returns>True if the field has been modified; otherwise false.</returns>
public bool IsModified(Expression<Func<object>> accessor)
=> IsModified(FieldIdentifier.Create(accessor));
/// <summary>
/// Validates this <see cref="EditContext"/>.
/// </summary>

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Components.Forms
Validator.TryValidateProperty(propertyValue, validationContext, results);
messages.Clear(fieldIdentifier);
messages.AddRange(fieldIdentifier, results.Select(result => result.ErrorMessage));
messages.Add(fieldIdentifier, results.Select(result => result.ErrorMessage));
// We have to notify even if there were no messages before and are still no messages now,
// because the "state" that changed might be the completion of some async validation task

View File

@ -1,35 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// Provides extension methods to simplify using <see cref="EditContext"/> with expressions.
/// </summary>
public static class EditContextExpressionExtensions
{
/// <summary>
/// Gets the current validation messages for the specified field.
///
/// This method does not perform validation itself. It only returns messages determined by previous validation actions.
/// </summary>
/// <param name="editContext">The <see cref="EditContext"/>.</param>
/// <param name="accessor">Identifies the field whose current validation messages should be returned.</param>
/// <returns>The current validation messages for the specified field.</returns>
public static IEnumerable<string> GetValidationMessages(this EditContext editContext, Expression<Func<object>> accessor)
=> editContext.GetValidationMessages(FieldIdentifier.Create(accessor));
/// <summary>
/// Determines whether the specified fields in this <see cref="EditContext"/> has been modified.
/// </summary>
/// <param name="editContext">The <see cref="EditContext"/>.</param>
/// <param name="accessor">Identifies the field whose current validation messages should be returned.</param>
/// <returns>True if the field has been modified; otherwise false.</returns>
public static bool IsModified(this EditContext editContext, Expression<Func<object>> accessor)
=> editContext.IsModified(FieldIdentifier.Create(accessor));
}
}

View File

@ -1,21 +1,27 @@
// 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;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// Provides information about the <see cref="EditContext.OnFieldChanged"/> event.
/// </summary>
public sealed class FieldChangedEventArgs
public sealed class FieldChangedEventArgs : EventArgs
{
/// <summary>
/// Creates a new instance of <see cref="FieldChangedEventArgs"/>.
/// </summary>
/// <param name="fieldIdentifier">The <see cref="Forms.FieldIdentifier"/></param>
public FieldChangedEventArgs(in FieldIdentifier fieldIdentifier)
{
FieldIdentifier = fieldIdentifier;
}
/// <summary>
/// Identifies the field whose value has changed.
/// </summary>
public FieldIdentifier FieldIdentifier { get; }
internal FieldChangedEventArgs(in FieldIdentifier fieldIdentifier)
{
FieldIdentifier = fieldIdentifier;
}
}
}

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Components.Forms
/// Uniquely identifies a single field that can be edited. This may correspond to a property on a
/// model object, or can be any other named value.
/// </summary>
public readonly struct FieldIdentifier
public readonly struct FieldIdentifier : IEquatable<FieldIdentifier>
{
/// <summary>
/// Initializes a new instance of the <see cref="FieldIdentifier"/> structure.
@ -68,8 +68,15 @@ namespace Microsoft.AspNetCore.Components.Forms
/// <inheritdoc />
public override bool Equals(object obj)
=> obj is FieldIdentifier otherIdentifier
&& otherIdentifier.Model == Model
&& string.Equals(otherIdentifier.FieldName, FieldName, StringComparison.Ordinal);
&& Equals(otherIdentifier);
/// <inheritdoc />
public bool Equals(FieldIdentifier otherIdentifier)
{
return
otherIdentifier.Model == Model &&
string.Equals(otherIdentifier.FieldName, FieldName, StringComparison.Ordinal);
}
private static void ParseAccessor<T>(Expression<Func<T>> accessor, out object model, out string fieldName)
{

View File

@ -33,14 +33,30 @@ namespace Microsoft.AspNetCore.Components.Forms
public void Add(in FieldIdentifier fieldIdentifier, string message)
=> GetOrCreateMessagesListForField(fieldIdentifier).Add(message);
/// <summary>
/// Adds a validation message for the specified field.
/// </summary>
/// <param name="accessor">Identifies the field for which to add the message.</param>
/// <param name="message">The validation message.</param>
public void Add(Expression<Func<object>> accessor, string message)
=> Add(FieldIdentifier.Create(accessor), message);
/// <summary>
/// Adds the messages from the specified collection for the specified field.
/// </summary>
/// <param name="fieldIdentifier">The identifier for the field.</param>
/// <param name="messages">The validation messages to be added.</param>
public void AddRange(in FieldIdentifier fieldIdentifier, IEnumerable<string> messages)
public void Add(in FieldIdentifier fieldIdentifier, IEnumerable<string> messages)
=> GetOrCreateMessagesListForField(fieldIdentifier).AddRange(messages);
/// <summary>
/// Adds the messages from the specified collection for the specified field.
/// </summary>
/// <param name="accessor">Identifies the field for which to add the messages.</param>
/// <param name="messages">The validation messages to be added.</param>
public void Add(Expression<Func<object>> accessor, IEnumerable<string> messages)
=> Add(FieldIdentifier.Create(accessor), messages);
/// <summary>
/// Gets the validation messages within this <see cref="ValidationMessageStore"/> for the specified field.
///
@ -74,6 +90,13 @@ namespace Microsoft.AspNetCore.Components.Forms
_messages.Clear();
}
/// <summary>
/// Removes all messages within this <see cref="ValidationMessageStore"/> for the specified field.
/// </summary>
/// <param name="accessor">Identifies the field for which to remove the messages.</param>
public void Clear(Expression<Func<object>> accessor)
=> Clear(FieldIdentifier.Create(accessor));
/// <summary>
/// Removes all messages within this <see cref="ValidationMessageStore"/> for the specified field.
/// </summary>

View File

@ -1,41 +0,0 @@
// 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;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// Provides extension methods to simplify using <see cref="ValidationMessageStore"/> with expressions.
/// </summary>
public static class ValidationMessageStoreExpressionExtensions
{
/// <summary>
/// Adds a validation message for the specified field.
/// </summary>
/// <param name="store">The <see cref="ValidationMessageStore"/>.</param>
/// <param name="accessor">Identifies the field for which to add the message.</param>
/// <param name="message">The validation message.</param>
public static void Add(this ValidationMessageStore store, Expression<Func<object>> accessor, string message)
=> store.Add(FieldIdentifier.Create(accessor), message);
/// <summary>
/// Adds the messages from the specified collection for the specified field.
/// </summary>
/// <param name="store">The <see cref="ValidationMessageStore"/>.</param>
/// <param name="accessor">Identifies the field for which to add the messages.</param>
/// <param name="messages">The validation messages to be added.</param>
public static void AddRange(this ValidationMessageStore store, Expression<Func<object>> accessor, IEnumerable<string> messages)
=> store.AddRange(FieldIdentifier.Create(accessor), messages);
/// <summary>
/// Removes all messages within this <see cref="ValidationMessageStore"/> for the specified field.
/// </summary>
/// <param name="store">The <see cref="ValidationMessageStore"/>.</param>
/// <param name="accessor">Identifies the field for which to remove the messages.</param>
public static void Clear(this ValidationMessageStore store, Expression<Func<object>> accessor)
=> store.Clear(FieldIdentifier.Create(accessor));
}
}

View File

@ -1,16 +1,24 @@
// 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;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// Provides information about the <see cref="EditContext.OnValidationRequested"/> event.
/// </summary>
public sealed class ValidationRequestedEventArgs
public sealed class ValidationRequestedEventArgs : EventArgs
{
internal static readonly ValidationRequestedEventArgs Empty = new ValidationRequestedEventArgs();
/// <summary>
/// Gets a shared empty instance of <see cref="ValidationRequestedEventArgs"/>.
/// </summary>
public static new readonly ValidationRequestedEventArgs Empty = new ValidationRequestedEventArgs();
internal ValidationRequestedEventArgs()
/// <summary>
/// Creates a new instance of <see cref="ValidationRequestedEventArgs"/>.
/// </summary>
public ValidationRequestedEventArgs()
{
}
}

View File

@ -1,16 +1,24 @@
// 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;
namespace Microsoft.AspNetCore.Components.Forms
{
/// <summary>
/// Provides information about the <see cref="EditContext.OnValidationStateChanged"/> event.
/// </summary>
public sealed class ValidationStateChangedEventArgs
public sealed class ValidationStateChangedEventArgs : EventArgs
{
internal static readonly ValidationStateChangedEventArgs Empty = new ValidationStateChangedEventArgs();
/// <summary>
/// Gets a shared empty instance of <see cref="ValidationStateChangedEventArgs"/>.
/// </summary>
public new static readonly ValidationStateChangedEventArgs Empty = new ValidationStateChangedEventArgs();
internal ValidationStateChangedEventArgs()
/// <summary>
/// Creates a new instance of <see cref="ValidationStateChangedEventArgs" />
/// </summary>
public ValidationStateChangedEventArgs()
{
}
}

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Components.Forms
}
[Fact]
public void CanAddMessagesByRange()
public void CanAddMessagesMultiple()
{
// Arrange
var messages = new ValidationMessageStore(new EditContext(new object()));
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Components.Forms
var entries = new[] { "A", "B", "C" };
// Act
messages.AddRange(field1, entries);
messages.Add(field1, entries);
// Assert
Assert.Equal(entries, messages[field1]);

View File

@ -276,8 +276,8 @@ namespace Microsoft.AspNetCore.Components.Forms
{
public static partial class EditContextFieldClassExtensions
{
public static string FieldClass(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { throw null; }
public static string FieldClass<TField>(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, System.Linq.Expressions.Expression<System.Func<TField>> accessor) { throw null; }
public static string FieldCssClass(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, in Microsoft.AspNetCore.Components.Forms.FieldIdentifier fieldIdentifier) { throw null; }
public static string FieldCssClass<TField>(this Microsoft.AspNetCore.Components.Forms.EditContext editContext, System.Linq.Expressions.Expression<System.Func<TField>> accessor) { throw null; }
}
public partial class EditForm : Microsoft.AspNetCore.Components.ComponentBase
{
@ -308,7 +308,6 @@ namespace Microsoft.AspNetCore.Components.Forms
protected T CurrentValue { get { throw null; } set { } }
protected string CurrentValueAsString { get { throw null; } set { } }
protected Microsoft.AspNetCore.Components.Forms.EditContext EditContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected string FieldClass { get { throw null; } }
protected Microsoft.AspNetCore.Components.Forms.FieldIdentifier FieldIdentifier { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
[Microsoft.AspNetCore.Components.ParameterAttribute]
public T Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
@ -372,6 +371,7 @@ namespace Microsoft.AspNetCore.Components.Forms
[Microsoft.AspNetCore.Components.ParameterAttribute]
public System.Linq.Expressions.Expression<System.Func<T>> For { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder) { }
protected virtual void Dispose(bool disposing) { }
protected override void OnParametersSet() { }
void System.IDisposable.Dispose() { }
}
@ -381,6 +381,7 @@ namespace Microsoft.AspNetCore.Components.Forms
[Microsoft.AspNetCore.Components.ParameterAttribute(CaptureUnmatchedValues=true)]
public System.Collections.Generic.IReadOnlyDictionary<string, object> AdditionalAttributes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder) { }
protected virtual void Dispose(bool disposing) { }
protected override void OnParametersSet() { }
void System.IDisposable.Dispose() { }
}

View File

@ -14,23 +14,23 @@ namespace Microsoft.AspNetCore.Components.Forms
public static class EditContextFieldClassExtensions
{
/// <summary>
/// Gets a string that indicates the status of the specified field. This will include
/// Gets a string that indicates the status of the specified field as a CSS class. This will include
/// some combination of "modified", "valid", or "invalid", depending on the status of the field.
/// </summary>
/// <param name="editContext">The <see cref="EditContext"/>.</param>
/// <param name="accessor">An identifier for the field.</param>
/// <returns>A string that indicates the status of the field.</returns>
public static string FieldClass<TField>(this EditContext editContext, Expression<Func<TField>> accessor)
=> FieldClass(editContext, FieldIdentifier.Create(accessor));
public static string FieldCssClass<TField>(this EditContext editContext, Expression<Func<TField>> accessor)
=> FieldCssClass(editContext, FieldIdentifier.Create(accessor));
/// <summary>
/// Gets a string that indicates the status of the specified field. This will include
/// Gets a string that indicates the status of the specified field as a CSS class. This will include
/// some combination of "modified", "valid", or "invalid", depending on the status of the field.
/// </summary>
/// <param name="editContext">The <see cref="EditContext"/>.</param>
/// <param name="fieldIdentifier">An identifier for the field.</param>
/// <returns>A string that indicates the status of the field.</returns>
public static string FieldClass(this EditContext editContext, in FieldIdentifier fieldIdentifier)
public static string FieldCssClass(this EditContext editContext, in FieldIdentifier fieldIdentifier)
{
var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();
if (editContext.IsModified(fieldIdentifier))

View File

@ -143,8 +143,8 @@ namespace Microsoft.AspNetCore.Components.Forms
/// Gets a string that indicates the status of the field being edited. This will include
/// some combination of "modified", "valid", or "invalid", depending on the status of the field.
/// </summary>
protected string FieldClass
=> EditContext.FieldClass(FieldIdentifier);
private string FieldClass
=> EditContext.FieldCssClass(FieldIdentifier);
/// <summary>
/// Gets a CSS class string that combines the <c>class</c> attribute and <see cref="FieldClass"/>

View File

@ -85,9 +85,14 @@ namespace Microsoft.AspNetCore.Components.Forms
StateHasChanged();
}
protected virtual void Dispose(bool disposing)
{
}
void IDisposable.Dispose()
{
DetachValidationStateChangedListener();
Dispose(disposing: true);
}
private void DetachValidationStateChangedListener()

View File

@ -82,9 +82,14 @@ namespace Microsoft.AspNetCore.Components.Forms
StateHasChanged();
}
protected virtual void Dispose(bool disposing)
{
}
void IDisposable.Dispose()
{
DetachValidationStateChangedListener();
Dispose(disposing: true);
}
private void DetachValidationStateChangedListener()

View File

@ -213,28 +213,23 @@ namespace Microsoft.AspNetCore.Components.Forms
// Act/Assert: Initally, it's valid and unmodified
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
Assert.Equal("valid", inputComponent.FieldClass);
Assert.Equal("valid", inputComponent.CssClass); // Same because no Class was specified
Assert.Equal("valid", inputComponent.CssClass); // no Class was specified
// Act/Assert: Modify the field
rootComponent.EditContext.NotifyFieldChanged(fieldIdentifier);
Assert.Equal("modified valid", inputComponent.FieldClass);
Assert.Equal("modified valid", inputComponent.CssClass);
// Act/Assert: Make it invalid
var messages = new ValidationMessageStore(rootComponent.EditContext);
messages.Add(fieldIdentifier, "I do not like this value");
Assert.Equal("modified invalid", inputComponent.FieldClass);
Assert.Equal("modified invalid", inputComponent.CssClass);
// Act/Assert: Clear the modification flag
rootComponent.EditContext.MarkAsUnmodified(fieldIdentifier);
Assert.Equal("invalid", inputComponent.FieldClass);
Assert.Equal("invalid", inputComponent.CssClass);
// Act/Assert: Make it valid
messages.Clear();
Assert.Equal("valid", inputComponent.FieldClass);
Assert.Equal("valid", inputComponent.CssClass);
}
@ -256,12 +251,10 @@ namespace Microsoft.AspNetCore.Components.Forms
// Act/Assert
var inputComponent = await RenderAndGetTestInputComponentAsync(rootComponent);
Assert.Equal("valid", inputComponent.FieldClass);
Assert.Equal("my-class other-class valid", inputComponent.CssClass);
// Act/Assert: Retains custom class when changing field class
rootComponent.EditContext.NotifyFieldChanged(fieldIdentifier);
Assert.Equal("modified valid", inputComponent.FieldClass);
Assert.Equal("my-class other-class modified valid", inputComponent.CssClass);
}
@ -393,8 +386,6 @@ namespace Microsoft.AspNetCore.Components.Forms
public new FieldIdentifier FieldIdentifier => base.FieldIdentifier;
public new string FieldClass => base.FieldClass;
protected override bool TryParseValueFromString(string value, out T result, out string validationErrorMessage)
{
throw new NotImplementedException();

View File

@ -18,11 +18,11 @@
<form @onsubmit="HandleSubmit">
<p class="user-name">
User name:
<input @bind="person.UserName" class="@editContext.FieldClass(() => person.UserName)" />
<input @bind="person.UserName" class="@editContext.FieldCssClass(() => person.UserName)" />
</p>
<p class="accepts-terms">
Accept terms:
<input type="checkbox" @bind="person.AcceptsTerms" class="@editContext.FieldClass(() => person.AcceptsTerms)" />
<input type="checkbox" @bind="person.AcceptsTerms" class="@editContext.FieldCssClass(() => person.AcceptsTerms)" />
</p>
<button type="submit">Submit</button>

View File

@ -5,10 +5,10 @@
<DataAnnotationsValidator />
<p class="user-name">
User name: <input @bind="UserName" class="@context.FieldClass(() => UserName)" />
User name: <input @bind="UserName" class="@context.FieldCssClass(() => UserName)" />
</p>
<p class="accepts-terms">
Accept terms: <input type="checkbox" @bind="AcceptsTerms" class="@context.FieldClass(() => AcceptsTerms)" />
Accept terms: <input type="checkbox" @bind="AcceptsTerms" class="@context.FieldCssClass(() => AcceptsTerms)" />
</p>
<button type="submit">Submit</button>