Reputation: 9360
Hello i have 2
variables of type int
that i would like to bind to the min
and max
values of an input
of type time
.
How can i do this?
I do not know what to place in the bind
field since there are 2 different variables.
Also there is the min
and max
attributes.
<input type="time" min="@model.min" max="@model.max" bind=?/>
What should i put in the bind
?
Update
On a more thoroughly analysis i decided i will need 2 variables of type Timespan
and i will bind these to 2 inputs of type time
.
Upvotes: 9
Views: 14228
Reputation: 1554
.NET 6.0.8 now has nice functionality for this in InputDate
, that supports the TimeOnly
type (among others). I found out as i was studying the .NET source code and about to create my own (due to ccStars' answer)
<InputDate Type="InputDateType.Time" @bind-Value="@model.TimeVar" />
Where TimeVar
has type TimeOnly?
. It's nice that it handles nullable types.
Upvotes: 10
Reputation: 825
Hopefully this helps, I was also trying to bind a Timespan a input of type="time"
I managed to achieve it with the help from the following site
https://www.meziantou.net/creating-a-inputselect-component-for-enumerations-in-blazor.htm
This is the code I created to achieve this
InputTime.cs
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Rendering;
using System;
using System.Globalization;
namespace Example
{
public sealed class InputTime : InputBase<TimeSpan>
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddAttribute(1, "type", "time");
builder.AddMultipleAttributes(2, AdditionalAttributes);
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, null));
builder.CloseElement(); // close the select element
}
protected override bool TryParseValueFromString(string value, out TimeSpan result, out string validationErrorMessage)
{
validationErrorMessage = null;
return BindConverter.TryConvertTo<TimeSpan>(value, CultureInfo.CurrentCulture, out result);
}
}
}
Razor Page
<div class="form-group">
<label>Time From</label>
<InputTime @bind-Value="MyModel.TimeFrom" class="form-control"></InputTime>
<ValidationMessage For="() => MyModel.TimeFrom"></ValidationMessage>
</div>
Upvotes: 1
Reputation: 2407
You can also do the following:
<input type="time" @bind="SomeTime" @bind:format="HH:mm"/>
@code {
public DateTime SomeTime = new DateTime();
private TimeSpan _time = SomeTime.TimeOfDay;
}
Please not this doesn't bind to the TimeSpan directly!
Upvotes: 2
Reputation: 5894
I wrote a little component for this which utilizes databinding and works with the proper data types.
usage:
<LabeledTime @bind-Value="shutdownDelay"></LabeledTime>
component:
<label class="form-label" for="@LabelId">
@ChildContent
</label>
<input id="@LabelId" type="time" value="@ValueInternal.ToString("hh\\:mm")" step="60" @onchange="InternalValueChanged"/>
@code {
private long LabelId = DateTime.Now.Ticks;
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public TimeSpan Value { get; set; }
[Parameter]
public EventCallback<TimeSpan> ValueChanged { get; set; }
private TimeSpan ValueInternal { get; set; }
protected override void OnParametersSet()
{
ValueInternal = Value;
base.OnParametersSet();
}
private void InternalValueChanged(ChangeEventArgs obj)
{
if (!TimeSpan.TryParseExact(obj.Value.ToString(), "hh\\:mm\\:ss", null, out var result))
return;
ValueInternal = result;
Value = result;
ValueChanged.InvokeAsync(result);
}
}
Upvotes: 1
Reputation: 844
Previous solution was not working for me with .net Core 3.1 so I'll add an updated one:
Use Blazor :
<EditForm Model=@model OnValidSubmit="Submit">
<InputText type="time" @bind-Value="TimeProxy" />
</EditForm>
Code changes are necessary as well.
@code {
// This field is required as you can not use property in out statement
private TimeSpan LocalTime = TimeSpan.FromHours(0);
private string TimeProxy {
get => model.Time.ToString();
set => TimeSpan.TryParse(value,out LocalTime);
}
private void Submit() {
model.Time = LocalTime;
// following submit logic...
}
}
Upvotes: 7
Reputation: 8964
You cannot bind a TimeSpan directly to an input in Blazor, but you can use a property to convert it to/from a string.
<input type="time" min="@model.min" max="@model.max" bind="@TimeProxy" />
and
@functions
{
string TimeProxy { get => model.Time.ToString(); set => TimeSpan.TryParse(value,out model.Time); }
}
Upvotes: 6