@@ -21,16 +21,10 @@ public abstract partial class FluentInputBase<TValue> : FluentComponentBase, IDi
2121 internal readonly string UnknownBoundField = "(unknown)" ;
2222
2323 private readonly EventHandler < ValidationStateChangedEventArgs > _validationStateChangedHandler ;
24-
2524 private bool _hasInitializedParameters ;
26- private bool _parsingFailed ;
27- private string ? _incomingValueBeforeParsing ;
28- private bool _previousParsingAttemptFailed ;
29- private ValidationMessageStore ? _parsingValidationMessages ;
30- private Type ? _nullableUnderlyingType ;
3125
3226 [ CascadingParameter ]
33- private EditContext ? CascadedEditContext { get ; set ; }
27+ private protected EditContext ? CascadedEditContext { get ; set ; }
3428
3529 /// <summary>
3630 /// When true, the control will be immutable by user interaction. <see href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/readonly">readonly</see> HTML attribute for more information.
@@ -132,12 +126,6 @@ public abstract partial class FluentInputBase<TValue> : FluentComponentBase, IDi
132126 [ Parameter ]
133127 public virtual bool Embedded { get ; set ; } = false ;
134128
135- /// <summary>
136- /// Gets or sets the error message to show when the field can not be parsed.
137- /// </summary>
138- [ Parameter ]
139- public virtual string ParsingErrorMessage { get ; set ; } = "The {0} field must have a valid format." ;
140-
141129 /// <summary>
142130 /// Gets the associated <see cref="Microsoft.AspNetCore.Components.Forms.EditContext"/>.
143131 /// This property is uninitialized if the input does not have a parent <see cref="EditForm"/>.
@@ -157,16 +145,14 @@ public abstract partial class FluentInputBase<TValue> : FluentComponentBase, IDi
157145 /// </summary>
158146 internal string FieldDisplayName => DisplayName ?? ( FieldBound ? FieldIdentifier . FieldName : UnknownBoundField ) ;
159147
160- protected async Task SetCurrentValueAsync ( TValue ? value )
148+ protected virtual async Task SetCurrentValueAsync ( TValue ? value )
161149 {
162150 var hasChanged = ! EqualityComparer < TValue > . Default . Equals ( value , Value ) ;
163151 if ( ! hasChanged )
164152 {
165153 return ;
166154 }
167155
168- _parsingFailed = false ;
169-
170156 // If we don't do this, then when the user edits from A to B, we'd:
171157 // - Do a render that changes back to A
172158 // - Then send the updated value to the parent, which sends the B back to this component
@@ -197,65 +183,6 @@ protected TValue? CurrentValue
197183 set => _ = SetCurrentValueAsync ( value ) ;
198184 }
199185
200- /// <summary>
201- /// Gets or sets the current value of the input, represented as a string.
202- /// </summary>
203- protected string ? CurrentValueAsString
204- {
205- // InputBase-derived components can hold invalid states (e.g., an InputNumber being blank even when bound
206- // to an int value). So, if parsing fails, we keep the rejected string in the UI even though it doesn't
207- // match what's on the .NET model. This avoids interfering with typing, but still notifies the EditContext
208- // about the validation error message.
209- get => _parsingFailed ? _incomingValueBeforeParsing : FormatValueAsString ( CurrentValue ) ;
210- set => _ = SetCurrentValueAsStringAsync ( value ) ;
211-
212- }
213-
214- /// <summary>
215- /// Attempts to set the current value of the input, represented as a string.
216- /// </summary>
217- /// <param name="value"></param>
218- protected async Task SetCurrentValueAsStringAsync ( string ? value )
219- {
220- _incomingValueBeforeParsing = value ;
221- _parsingValidationMessages ? . Clear ( ) ;
222-
223- if ( _nullableUnderlyingType != null && string . IsNullOrEmpty ( value ) )
224- {
225- // Assume if it's a nullable type, null/empty inputs should correspond to default(T)
226- // Then all subclasses get nullable support almost automatically (they just have to
227- // not reject Nullable<T> based on the type itself).
228- _parsingFailed = false ;
229- CurrentValue = default ! ;
230- }
231- else if ( TryParseValueFromString ( value , out var parsedValue , out var validationErrorMessage ) )
232- {
233- _parsingFailed = false ;
234- await SetCurrentValueAsync ( parsedValue ) ;
235- }
236- else
237- {
238- _parsingFailed = true ;
239-
240- // EditContext may be null if the input is not a child component of EditForm.
241- if ( EditContext is not null && FieldBound )
242- {
243- _parsingValidationMessages ??= new ValidationMessageStore ( EditContext ) ;
244- _parsingValidationMessages . Add ( FieldIdentifier , validationErrorMessage ) ;
245-
246- // Since we're not writing to CurrentValue, we'll need to notify about modification from here
247- EditContext . NotifyFieldChanged ( FieldIdentifier ) ;
248- }
249- }
250-
251- // We can skip the validation notification if we were previously valid and still are
252- if ( _parsingFailed || _previousParsingAttemptFailed )
253- {
254- EditContext ? . NotifyValidationStateChanged ( ) ;
255- _previousParsingAttemptFailed = _parsingFailed ;
256- }
257- }
258-
259186 /// <summary>
260187 /// Constructs an instance of <see cref="InputBase{TValue}"/>.
261188 /// </summary>
@@ -266,23 +193,13 @@ protected FluentInputBase()
266193 }
267194
268195 /// <summary>
269- /// Formats the value as a string. Derived classes can override this to determine the formating used for <see cref="CurrentValueAsString"/>.
196+ /// Formats the value as a string.
270197 /// </summary>
271198 /// <param name="value">The value to format.</param>
272199 /// <returns>A string representation of the value.</returns>
273200 protected virtual string ? FormatValueAsString ( TValue ? value )
274201 => value ? . ToString ( ) ;
275202
276- /// <summary>
277- /// Parses a string to create an instance of <typeparamref name="TValue"/>. Derived classes can override this to change how
278- /// <see cref="CurrentValueAsString"/> interprets incoming values.
279- /// </summary>
280- /// <param name="value">The string value to be parsed.</param>
281- /// <param name="result">An instance of <typeparamref name="TValue"/>.</param>
282- /// <param name="validationErrorMessage">If the value could not be parsed, provides a validation error message.</param>
283- /// <returns>True if the value could be parsed; otherwise false.</returns>
284- protected abstract bool TryParseValueFromString ( string ? value , [ MaybeNullWhen ( false ) ] out TValue result , [ NotNullWhen ( false ) ] out string ? validationErrorMessage ) ;
285-
286203 /// <summary>
287204 /// Gets a CSS class string that combines the <c>class</c> attribute and and a string indicating
288205 /// the status of the field being edited (a combination of "modified", "valid", and "invalid").
@@ -339,7 +256,6 @@ public override Task SetParametersAsync(ParameterView parameters)
339256 EditContext . OnValidationStateChanged += _validationStateChangedHandler ;
340257 }
341258
342- _nullableUnderlyingType = Nullable . GetUnderlyingType ( typeof ( TValue ) ) ;
343259 _hasInitializedParameters = true ;
344260 }
345261 else if ( CascadedEditContext != EditContext )
0 commit comments