Skip to content

Commit

Permalink
RadzenDatePicker floating label and RadzenFormField support (#1933)
Browse files Browse the repository at this point in the history
* Added support to use RadzenDatePicker in RadzenFormField

- added rz-state-empty css class to RadzenDatePicker if there is no value
- added css to handle floating labels for any form field component within RadzenFormField

* RadzenDatePicker minor code fixes and improvements

* RadzenDatePicker Demo show time part
  • Loading branch information
rklfss authored Feb 3, 2025
1 parent b92ef79 commit 9ea1b44
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
28 changes: 28 additions & 0 deletions Radzen.Blazor.Tests/DatePickerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,34 @@ public void DatePicker_Renders_TabIndexParameter()
Assert.Contains(@$"tabindex=""{value}""", component.Markup);
}

[Fact]
public void DatePicker_Renders_EmptyCssClass_WhenValueIsEmpty()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");

var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>();

component.SetParametersAndRender(parameters => parameters.Add(p => p.Value, null));

Assert.Contains(@$"rz-state-empty", component.Markup);
}

[Fact]
public void DatePicker_DoesNotRender_EmptyCssClass_WhenValueIsNotEmpty()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");

var component = ctx.RenderComponent<RadzenDatePicker<DateTime>>();

component.SetParametersAndRender(parameters => parameters.Add(p => p.Value, DateTime.Now));

Assert.DoesNotContain(@$"rz-state-empty", component.Markup);
}

[Fact]
public void DatePicker_Renders_DisabledParameter()
{
Expand Down
18 changes: 7 additions & 11 deletions Radzen.Blazor/RadzenDatePicker.razor
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
@using Radzen
@using Radzen.Blazor.Rendering
@using Microsoft.AspNetCore.Components.Forms
@using System.Linq.Expressions
@using System.Globalization
@using Microsoft.JSInterop

@typeparam TValue
@inherits RadzenComponent
@implements IRadzenFormComponent
@if (Visible)
{
<div @ref="@Element" @attributes="Attributes" class="@($"rz-datepicker{(Disabled ? " rz-state-disabled" : "")}") @GetCssClass()" style="@getStyle()" id="@GetId()">
<div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" style="@getStyle()" id="@GetId()">
@if (!Inline)
{
<input @ref="@input" @attributes="InputAttributes" disabled="@Disabled" readonly="@IsReadonly" value="@FormattedValue" tabindex="@(Disabled ? "-1" : $"{TabIndex}")"
@onchange="@ParseDate" autocomplete="off" type="text" name="@Name" @onkeydown="@(args => OnKeyPress(args))" @onkeydown:preventDefault=preventKeyPress @onkeydown:stopPropagation
class="rz-inputtext @InputClass @(ReadOnly ? "rz-readonly" : "") @(!ShowButton ? "rz-input-trigger" : "")" id="@Name" placeholder="@Placeholder" />
class="rz-inputtext @InputClass @(ReadOnly ? "rz-readonly" : "") @(!ShowButton ? "rz-input-trigger" : "")" id="@Name" placeholder="@CurrentPlaceholder" />
@if (ShowButton)
{
<button aria-label="@ToggleAriaLabel" @onmousedown=@OnToggle class="@($"rz-datepicker-trigger rz-button rz-button-icon-only{(Disabled ? " rz-state-disabled" : "")} {ButtonClass}")" tabindex="-1" type="button">
Expand All @@ -33,10 +29,10 @@
@if (!TimeOnly)
{
<div class="rz-calendar-header">
<a id="@(GetId() + "pm")" tabindex="-1" aria-label="@PrevMonthAriaLabel" @onclick:preventDefault="true" class="rz-button rz-button-md rz-variant-text rz-button-icon-only rz-secondary rz-shade-default rz-calendar-prev" @onclick="@(async () => { if (!Disabled) { try { if(CurrentDate.AddMonths(-1).Year >= YearFrom) {CurrentDate = CurrentDate.AddMonths(-1);}} catch (ArgumentOutOfRangeException) {}} })">
<a id="@(GetId() + "pm")" tabindex="-1" aria-label="@PrevMonthAriaLabel" @onclick:preventDefault="true" class="rz-button rz-button-md rz-variant-text rz-button-icon-only rz-secondary rz-shade-default rz-calendar-prev" @onclick="@(() => { if (!Disabled) { try { if(CurrentDate.AddMonths(-1).Year >= YearFrom) {CurrentDate = CurrentDate.AddMonths(-1);}} catch (ArgumentOutOfRangeException) {}} })">
<span class="notranslate rzi rz-calendar-prev-icon"></span>
</a>
<a id="@(GetId() + "nm")" tabindex="-1" aria-label="@NextMonthAriaLabel" @onclick:preventDefault="true" class="rz-button rz-button-md rz-variant-text rz-button-icon-only rz-secondary rz-shade-default rz-calendar-next" @onclick="@(async () => { if (!Disabled) { try { if(CurrentDate.AddMonths(1).Year <= YearTo) {CurrentDate = CurrentDate.AddMonths(1);}} catch (ArgumentOutOfRangeException) {} } })">
<a id="@(GetId() + "nm")" tabindex="-1" aria-label="@NextMonthAriaLabel" @onclick:preventDefault="true" class="rz-button rz-button-md rz-variant-text rz-button-icon-only rz-secondary rz-shade-default rz-calendar-next" @onclick="@(() => { if (!Disabled) { try { if(CurrentDate.AddMonths(1).Year <= YearTo) {CurrentDate = CurrentDate.AddMonths(1);}} catch (ArgumentOutOfRangeException) {} } })">
<span class="notranslate rzi rz-calendar-next-icon"></span>
</a>
<div class="rz-calendar-title">
Expand Down Expand Up @@ -116,19 +112,19 @@
{
<div class="rz-timepicker" @onmousedown:stopPropagation>
<RadzenNumeric InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "hour" }})" TValue="int" Disabled="@Disabled" Value="@(HourFormat == "12" ? ((CurrentDate.Hour + 11) % 12) + 1 : CurrentDate.Hour)"
Min="@(HourFormat == "12" ? 1 : -1)" Max="@(HourFormat == "12" ? 12 : 24)" TValue="double" Step="@HoursStep"
Min="@(HourFormat == "12" ? 1 : -1)" Max="@(HourFormat == "12" ? 12 : 24)" Step="@HoursStep"
Change="@UpdateHour" class="rz-hour-picker" @oninput=@OnUpdateHourInput Format="@(PadHours ? "00" : "")" Name="@($"{UniqueID}-h")" />
<div class="rz-separator">
<span>:</span>
</div>
<RadzenNumeric InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "minutes" }})" TValue="int" Disabled="@Disabled" Value="CurrentDate.Minute" TValue="double" Step="@MinutesStep" Min="0" Max="59"
<RadzenNumeric InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "minutes" }})" TValue="int" Disabled="@Disabled" Value="CurrentDate.Minute" Step="@MinutesStep" Min="0" Max="59"
Change="@UpdateMinutes" class="rz-minute-picker" @oninput=@OnUpdateHourMinutes Format="@(PadMinutes ? "00" : "")" Name="@($"{UniqueID}-m")"/>
@if (ShowSeconds)
{
<div class="rz-separator">
<span>:</span>
</div>
<RadzenNumeric InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "seconds" }})" TValue="int" Disabled="@Disabled" Value="CurrentDate.Second" TValue="double" Step="@SecondsStep" Min="0" Max="59"
<RadzenNumeric InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "seconds" }})" TValue="int" Disabled="@Disabled" Value="CurrentDate.Second" Step="@SecondsStep" Min="0" Max="59"
Change="@UpdateSeconds" class="rz-second-picker" @oninput=@OnUpdateHourSeconds Format="@(PadSeconds ? "00" : "")" Name="@($"{UniqueID}-s")"/>
}
@if (HourFormat == "12")
Expand Down
16 changes: 15 additions & 1 deletion Radzen.Blazor/RadzenDatePicker.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,7 @@ private string ButtonClasses
/// <summary>
/// Gets or sets the FormFieldContext of the component
/// </summary>
[CascadingParameter]
public IFormFieldContext FormFieldContext { get; set; } = null;

/// <summary>
Expand Down Expand Up @@ -922,6 +923,9 @@ private string getStyle()
return $"{(Inline ? "overflow:auto;" : "")}{(Style != null ? Style : "")}";
}

/// <summary> Gets the current placeholder. Returns empty string if this component is inside a RadzenFormField.</summary>
protected string CurrentPlaceholder => FormFieldContext?.AllowFloatingLabel == true ? " " : Placeholder;

/// <summary>
/// Closes this instance popup.
/// </summary>
Expand Down Expand Up @@ -982,10 +986,13 @@ async Task OnChange()
/// <inheritdoc />
protected override string GetComponentCssClass()
{
return ClassList.Create()
return ClassList.Create("rz-datepicker")
.Add("rz-datepicker-inline", Inline)
.AddDisabled(Disabled)
.Add("rz-state-empty", !HasValue)
.Add(FieldIdentifier, EditContext)
.ToString();

}

private async Task SetDay(DateTime newValue)
Expand Down Expand Up @@ -1062,8 +1069,15 @@ public override async Task SetParametersAsync(ParameterView parameters)
shouldClose = !visible;
}

var disabledChanged = parameters.DidParameterChange(nameof(Disabled), Disabled);

await base.SetParametersAsync(parameters);

if (disabledChanged)
{
FormFieldContext?.DisabledChanged(Disabled);
}

if (shouldClose && !firstRender && IsJSRuntimeAvailable)
{
await JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
Expand Down
9 changes: 6 additions & 3 deletions Radzen.Blazor/themes/components/blazor/_form-field.scss
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,8 @@ $form-field-helper-padding: 0 0.5rem !default;
.rz-checkbox-list-horizontal ~ &,
.rz-chkbox ~ &,
.rz-fileupload ~ &,
.rz-state-empty:has(.rz-placeholder) ~ & {
.rz-state-empty:has(.rz-placeholder) ~ &,
.rz-form-field.rz-state-focused & {
inset-inline-end: auto;
inset-block-start: var(--rz-form-field-label-floating-top);
padding-block-start: 0;
Expand All @@ -383,7 +384,8 @@ $form-field-helper-padding: 0 0.5rem !default;
.rz-form-field:not(.rz-variant-outlined) .rz-checkbox-list-horizontal ~ &,
.rz-form-field:not(.rz-variant-outlined) .rz-chkbox ~ &,
.rz-form-field:not(.rz-variant-outlined) .rz-fileupload ~ &,
.rz-form-field:not(.rz-variant-outlined) .rz-state-empty:has(.rz-placeholder) ~ & {
.rz-form-field:not(.rz-variant-outlined) .rz-state-empty:has(.rz-placeholder) ~ &,
.rz-form-field:not(.rz-variant-outlined).rz-state-focused & {
background-color: inherit !important;
}

Expand All @@ -393,7 +395,8 @@ $form-field-helper-padding: 0 0.5rem !default;

.rz-state-focused &,
.rz-variant-filled.rz-state-focused &,
.rz-variant-flat.rz-state-focused & {
.rz-variant-flat.rz-state-focused &,
.rz-form-field.rz-state-focused & {
color: var(--rz-form-field-label-focus-color);
}

Expand Down
4 changes: 4 additions & 0 deletions RadzenBlazorDemos/Pages/FormFieldInputTypes.razor
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<RadzenFormField Text="RadzenAutoComplete" Variant="@variant">
<RadzenAutoComplete Data=@companyNames @bind-Value="@autoCompleteValue" />
</RadzenFormField>
<RadzenFormField Text="RadzenDatePicker" Variant="@variant">
<RadzenDatePicker @bind-Value="@date" ShowTime="@true" />
</RadzenFormField>
<RadzenFormField Text="RadzenColorPicker" Variant="@variant">
<RadzenColorPicker @bind-Value="@color" />
</RadzenFormField>
Expand Down Expand Up @@ -61,6 +64,7 @@
string dropDownDataGridValue = "";
string autoCompleteValue = "";
string color = "rgb(68, 58, 110)";
DateTime? date = DateTime.Today;

IEnumerable<string> companyNames;

Expand Down

0 comments on commit 9ea1b44

Please sign in to comment.