124 lines
4.2 KiB
C#
124 lines
4.2 KiB
C#
using Microsoft.AspNetCore.Components;
|
|
using Microsoft.AspNetCore.Components.Forms;
|
|
using Microsoft.AspNetCore.Components.Rendering;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MP.Stats.Components
|
|
{
|
|
/// <summary>
|
|
/// override calsse inputdate da
|
|
/// https://github.com/dotnet/aspnetcore/issues/18078
|
|
/// </summary>
|
|
/// <typeparam name="TValue"></typeparam>
|
|
public class InputDateTime<TValue> : InputDate<TValue>
|
|
{
|
|
#region Private Fields
|
|
|
|
private const string DateFormat = "yyyy-MM-ddTHH:mm:ss";
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Methods
|
|
|
|
private static bool TryParseDateTime(string value, out TValue result)
|
|
{
|
|
var success = BindConverter.TryConvertToDateTime(value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue);
|
|
if (success)
|
|
{
|
|
result = (TValue)(object)parsedValue;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
result = default;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static bool TryParseDateTimeOffset(string value, out TValue result)
|
|
{
|
|
var success = BindConverter.TryConvertToDateTimeOffset(value, CultureInfo.InvariantCulture, DateFormat, out var parsedValue);
|
|
if (success)
|
|
{
|
|
result = (TValue)(object)parsedValue;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
result = default;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Protected Methods
|
|
|
|
/// <inheritdoc />
|
|
protected override void BuildRenderTree(RenderTreeBuilder builder)
|
|
{
|
|
builder.OpenElement(0, "input");
|
|
builder.AddMultipleAttributes(1, AdditionalAttributes);
|
|
builder.AddAttribute(2, "type", "datetime-local");
|
|
builder.AddAttribute(3, "class", CssClass);
|
|
builder.AddAttribute(4, "value", BindConverter.FormatValue(CurrentValueAsString));
|
|
builder.AddAttribute(5, "onchange", EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
|
|
builder.CloseElement();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override string FormatValueAsString(TValue value)
|
|
{
|
|
switch (value)
|
|
{
|
|
case DateTime dateTimeValue:
|
|
return BindConverter.FormatValue(dateTimeValue, DateFormat, CultureInfo.InvariantCulture);
|
|
|
|
case DateTimeOffset dateTimeOffsetValue:
|
|
return BindConverter.FormatValue(dateTimeOffsetValue, DateFormat, CultureInfo.InvariantCulture);
|
|
|
|
default:
|
|
return string.Empty; // Handles null for Nullable<DateTime>, etc.
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
protected override bool TryParseValueFromString(string value, out TValue result, out string validationErrorMessage)
|
|
{
|
|
// Unwrap nullable types. We don't have to deal with receiving empty values for nullable
|
|
// types here, because the underlying InputBase already covers that.
|
|
var targetType = Nullable.GetUnderlyingType(typeof(TValue)) ?? typeof(TValue);
|
|
|
|
bool success;
|
|
if (targetType == typeof(DateTime))
|
|
{
|
|
success = TryParseDateTime(value, out result);
|
|
}
|
|
else if (targetType == typeof(DateTimeOffset))
|
|
{
|
|
success = TryParseDateTimeOffset(value, out result);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException($"The type '{targetType}' is not a supported date type.");
|
|
}
|
|
|
|
if (success)
|
|
{
|
|
validationErrorMessage = null;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
validationErrorMessage = string.Format(ParsingErrorMessage, FieldIdentifier.FieldName);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
}
|
|
} |