目录
介绍
在我使用Blazor.net的一项作业中,很少有表单具有输入控件作为日期选择器日历。根据业务逻辑的自定义需求不可能使用EditForm中的当前Blazor InputDate组件实现。下面列出了一些限制使用默认组件的逻辑:
- 限制日期,如开始日期和结束日期,或者限制未来或过去的日期
- 输入字段格式
以上几点可以在以后的版本中实现,但为了完成开发,我们选择使用Jquery。了解使用Blazor限制JavaScript在应用程序中的使用,当前版本不完全满足开发条件。希望未来的版本更新相同。我们可以使用第三方组件,但由于某些政策而受到限制。因此,为了清除开发障碍,我们决定使用jquery datepicker并创建一个可以在整个过程中使用的自定义组件。
下面是相同的代码以及如何在不同场景中使用它的解释。
使用代码
代码就像一个简单的插件,只需配置组件并在应用程序中使用它。下面是相同的代码。
_Host.cshtml
提供对jquery库的引用。请注意site.js是一个自定义js,其代码如下所示:
<script src="js/Jquery-3.5.1.min.js"></script>
<script src="jquery-ui-1.12.1/jquery-ui.min.js"></script>
<script src="js/site.js"></script>
site.js
window.siteFunction={
InitDatePickerwithSelect: function (element, formatDate, minDate, maxDate) {
$(element).datepicker('destroy');
$(element).datepicker({
showOtherMonths: true,
selectOtherMonths: true,
changeMonth: true,
changeYear: true,
dateFormat: formatDate,
minDate: minDate == null ? null : new Date(minDate),
maxDate: maxDate == null ? null : new Date(maxDate),
onSelect: function (date) {
var myElement = $(this)[0];
var event = new Event('change');
myElement.dispatchEvent(event);
}
});
},
SetMinMaxDate: function (element, minDate, maxDate) {
var min = minDate == null ? null : new Date(minDate);
var max = maxDate == null ? null : new Date(maxDate);
$(element).datepicker('option', 'minDate', min);
$(element).datepicker('option', 'maxDate', max);
}
}
JQDatePicker.razor
根据以下代码在项目的共享UI文件夹中创建一个razor组件。例如,BlazorApp/Pages/Component。
<input type="text" id="@(Id)" class="form-control datepicker @(Class)"
data-provide="datepicker"
disabled="@Disabled"
@ref="currentElement"
@bind-value="BindValue"
@bind-value:event="oninput"
@bind-value:format="@Format"
@onchange="OnChange" />
JQDatePicker.razor.cs
在razor组件所在的文件夹中创建与上述相同的razor.cs类。以下代码充当创建的razor页面的后端代码。
#region Microsoft References
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
#endregion
#region System References
using System;
using System.Threading.Tasks;
#endregion
namespace BlazorApp.Pages.Components
{
public partial class JQDatePicker{
#region Parameter
[Parameter] public DateTime? Value
{
get=>_value;
set
{
if(_value==value) return;
_value=value;
ValueChanged.InvokeAsync(Value);
}
}
[Parameter] public string Format { get; set; }
[Parameter] public EventCallback<DateTime?> ValueChanged {get;set;}
[Parameter] public string Id { get; set; }
[Parameter] public string Class { get; set; }
[Parameter] public bool Disabled { get; set; }
[Parameter] public DateTime? MinDate { get; set; }
[Parameter] public DateTime? MaxDate { get; set; }
#endregion
#region Inject
[Inject] IJSRuntime JSRuntime { get; set; }
#endregion
private DateTime? _value ;
private string DatePickerFormat { get; set; }
ElementReference currentElement { get; set; }
#region Protected Method
/// <summary>
/// Method to initialize variable on component initialization
/// </summary>
protected override async Task OnInitializedAsync()
{
Format = string.IsNullOrEmpty(Format) ? "dd/MMM/yyyy" : Format;
DatePickerFormat = string.IsNullOrEmpty(DatePickerFormat) ?
"dd/M/yy" : DatePickerFormat;
}
/// <summary>
///
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await RenderDatePicker();
}
if (!firstRender)
await SetMinMaxDate();
}
#endregion
#region Private Method
/// <summary>
/// Method to invoke Date picker js function
/// </summary>
/// <returns></returns>
private async Task RenderDatePicker()
{
await JSRuntime.InvokeVoidAsync("siteFunction.InitDatePickerwithSelect",
currentElement, DatePickerFormat, MinDate, MaxDate);
}
/// <summary>
/// Method to invoke setminmaxdate js function
/// </summary>
/// <returns></returns>
private async Task SetMinMaxDate()
{
await JSRuntime.InvokeVoidAsync("siteFunction.SetMinMaxDate",
currentElement, MinDate, MaxDate);
}
/// <summary>
/// Method to handle date picker change
/// </summary>
/// <param name="e">ChangeEventArgs</param>
private void OnChange(ChangeEventArgs e)
{
DateTime dateTime;
if (DateTime.TryParse(e.Value.ToString(), out dateTime))
{
ValueChanged.InvokeAsync(dateTime);
}
}
#endregion
}
}
下面是每个变量和函数的描述:
组件属性 |
描述 |
Value |
要传递的模型属性 |
Format |
UI组件的UI格式 |
ValueChanged |
在值更改时设置模型属性的事件回调。这有助于两种方式的绑定 |
Id |
要设置的组件的id属性 |
Class |
要设置的组件的类属性 |
Disabled |
要设置的禁用属性,即如果为true其他启用则禁用 |
MinDate |
要设置的属性以限制过去的日期。如果为null或未设置,则日历不会限制过去的日期 |
MaxDate |
在限制未来日期的情况下要设置的属性。如果设置null或未设置,则日历不会限制未来日期 |
变量 |
描述 |
DatePickerFormat |
要为jquery datepicker设置的格式。保持可配置,但可以更改为参数。 |
currentElement |
传递DOM元素引用的变量 |
方法 |
描述 |
OnInitializedAsync |
在组件初始化时执行的方法 |
OnAfterRenderAsync |
每次渲染组件时执行的方法 |
RenderDatePicker |
调用设置jquery的JavaScript datepicker函数的方法 |
SetMinMaxDate |
调用设置datepicker最小和最大日期的JavaScript函数的方法 |
OnChange |
更改输入字段时调用的方法 |
如何使用?
下面是一组示例代码,展示了如何使用双向绑定来使用上述组件。
DatePicker.razor
下面是显示如何使用能够组件的示例代码。
@page "/datepicker"
<div class="container">
<div class="col-12">
<div class="row">
<div class="form-group">
<label for="txtStartDate">Start Date</label>
<JQDatePicker Id="txtStartDate" BindValue="@StartDate"
MaxDate="@EndDate"
Format="dd/MMM/yyyy"
>
</JQDatePicker>
</div>
</div>
<div class="row">
<p>Start Date : @StartDate</p>
</div>
</div>
</div>
@code{
private DateTime? StartDate{get;set;}
private DateTime? EndDate{get;set;}
}
以下是显示如何使用Min Max日期函数的示例代码:
<div class="form-group">
<label for="txtStartDate">Start Date</label>
<JQDatePicker Id="txtStartDate" BindValue="@StartDate"
MaxDate="@EndDate"
Format="dd/MMM/yyyy"
>
</JQDatePicker>
</div>
<div class="form-group">
<label for="txtEndDate">End Date</label>
<JQDatePicker Id="txtEndDate" BindValue="@EndDate"
MinDate="@StartDate"
Format="dd/MMM/yyyy"
>
</JQDatePicker>
</div>
<div class="row">
<p>Start Date : @StartDate</p>
</div>
<div class="row">
<p>End Date : @EndDate</p>
</div>
@code{
private DateTime? StartDate{get;set;}
private DateTime? EndDate{get;set;}
}
示例代码可在GitHub上获得。
https://www.codeproject.com/Tips/5290232/Blazor-datepicker-Component-using-JQuery