ارائهی قالبی عمومی برای استفاده از تقویمهای جاوااسکریپتی در Blazor
نویسنده: وحید نصیری
تاریخ: ۱۴۰۱/۰۴/۲۱ ۱۴:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
@typeparam T @inherits InputBase<T>
protected override bool TryParseValueFromString(
string? value,
[MaybeNullWhen(false)] out T result,
[NotNullWhen(false)] out string? validationErrorMessage)
{
// ...
}
protected override string FormatValueAsString(T? value)
{
// ...
} <link href="_content/BlazorPersianJavaScriptDatePicker.Lib/css/PersianDatePicker.css" rel="stylesheet"/> <script src="_content/BlazorPersianJavaScriptDatePicker.Lib/js/PersianDatePicker.js?v=1"></script>
@using BlazorPersianJavaScriptDatePicker.Lib
@typeparam T
@inherits InputBase<T>
<div>
<span style="cursor:pointer"
onclick="PersianDatePicker.Show(document.getElementById('@ElementId'), '@Today')">
📅
</span>
<input
@attributes="@AdditionalAttributes"
type="text" dir="ltr"
@ref="ElementReference"
name="@ElementId" id="@ElementId"
autocapitalize="off" autocorrect="off" autocomplete="off"
value="@EnteredValue"
@oninput="OnInput"/>
@if (ValueExpression is not null)
{
<ValidationMessage For="@ValueExpression"/>
}
</div> function setValue(date) {
_textBox.value = date;
// NOTE: To notify the addEventListener('change', fn)
_textBox.dispatchEvent(new Event('change'));
_textBox.focus();
hide();
try {
_textBox.onchange();
}catch(ex) {}
} window.activateDatePicker = {
enableDatePicker: function (element, objectReference) {
element.addEventListener('change', function (evt) {
objectReference.invokeMethodAsync("OnInputFieldChanged", this.value);
});
}
}; <script src="_content/BlazorPersianJavaScriptDatePicker.Lib/js/activateDatePicker.js?v=1"></script>
public partial class PersianDatePicker<T> : IDisposable
{
private bool _isDisposed;
private DotNetObjectReference<PersianDatePicker<T>>? _objectReference;
private string ElementId { get; } = Guid.NewGuid().ToString("N");
private ElementReference? ElementReference { set; get; }
private string Today { get; } = DateTime.Now.ToShortPersianDateString();
[Inject] private IJSRuntime JsRuntime { set; get; } = default!;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_objectReference = DotNetObjectReference.Create(this);
await JsRuntime.InvokeVoidAsync("activateDatePicker.enableDatePicker", ElementReference, _objectReference);
EnteredValue = CurrentValueAsString;
StateHasChanged();
}
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!_isDisposed)
{
try
{
_objectReference?.Dispose();
}
finally
{
_isDisposed = true;
}
}
}
} [JSInvokable] public void OnInputFieldChanged(string? value)
public partial class PersianDatePicker<T> : IDisposable
{
private string? _enteredValue;
private string? EnteredValue
{
set => _enteredValue = value;
get => UsePersianNumbers ? _enteredValue.ToPersianNumbers() : _enteredValue;
}
[Parameter] public bool UsePersianNumbers { set; get; }
[Parameter] public string ParsingErrorMessage { get; set; } = "لطفا در ورودی {0} تاریخ شمسی معتبری را وارد نمائید.";
[Parameter] public int BeginningOfCentury { set; get; } = 1400;
private void OnInput(ChangeEventArgs e)
{
SetCurrentValue(e.Value as string);
}
private void SetCurrentValue(string? value)
{
EnteredValue = value;
CurrentValueAsString = value;
}
[JSInvokable]
public void OnInputFieldChanged(string? value)
{
SetCurrentValue(value);
}
protected override void OnInitialized()
{
base.OnInitialized();
SanityCheck();
}
protected override bool TryParseValueFromString(
string? value,
[MaybeNullWhen(false)] out T result,
[NotNullWhen(false)] out string? validationErrorMessage)
{
validationErrorMessage = string.Format(CultureInfo.InvariantCulture, ParsingErrorMessage, DisplayName);
if (!value.TryParsePersianDateToDateTimeOrDateTimeOffset(out result, BeginningOfCentury))
{
return false;
}
if (result is null)
{
throw new InvalidOperationException(validationErrorMessage);
}
validationErrorMessage = null;
return true;
}
protected override string FormatValueAsString(T? value)
{
return !string.IsNullOrWhiteSpace(EnteredValue) ? EnteredValue : value.FormatDateToShortPersianDate();
}
private void SanityCheck()
{
if (!Value.IsDateTimeOrDateTimeOffsetType())
{
throw new InvalidOperationException(
"The `Value` type is not a supported `date` type. DateTime, DateTime?, DateTimeOffset and DateTimeOffset? are supported.");
}
}
// ...
} using System.ComponentModel.DataAnnotations;
namespace BlazorPersianJavaScriptDatePicker.ViewModels;
public class InputPersianDateViewModel
{
[Required] public string Name { set; get; } = default!;
[Required] public DateTime BirthDayGregorian { set; get; } = DateTime.Now.AddYears(-40);
public DateTime? LoginAt { set; get; } = DateTime.Now.AddMinutes(-2);
[Required] public DateTimeOffset LogoutAt { set; get; }
public DateTimeOffset? RegisterAt { set; get; } = DateTimeOffset.Now.AddMinutes(-10);
} <EditForm Model="Model" OnValidSubmit="DoSave">
<DataAnnotationsValidator/>
<div>
<label>تاریخ تولد</label>
<div>
<PersianDatePicker
@bind-Value="Model.BirthDayGregorian"
UsePersianNumbers="false"
/>
</div>
</div>
<button type="submit">ارسال</button>
</EditForm> یک نکتهی تکمیلی: استفاده از این DatePicker در برنامههای Blazor SSR
اگر علاقمند باشید تا از این DatePicker در برنامههای Blazor SSR بهصورت یک کامپوننت استفاده کنید، روش کار به صورت زیر است: