Telerik UI for MVC => DateTime bug - c#

I am working with Telerik (Kendo) UI for ASP.NET MVC and I am using grid. The problem is that I have bug with DateTime type. Here source:
This is a part from my model:
public class Discussion
{
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime Date { get; set; }
// More code...
}
This is my editor template(which comes from Telerik UI)
#model DateTime?
<div style="background-color: red; color: aqua; font-size: 28px;">
#(Html.Kendo().DatePickerFor(m => m)
.Format("MM/dd/yyyy"))
</div>
And in view (in grid) this is for date property:
columns.Bound(model => model.Date).Width(150).Format("{0:MM/dd/yyyy}");
The problem is that after I create new element => http://prntscr.com/8iq7si
in my controller I receive date with value: {1.1.0001 г. 0:00:00} => http://prntscr.com/8iq8eq
In very rare cases the date is send, but than there is some bug with format and ModelState is never valid.
P.S Here what is generated html:
<input data-val="true" data-val-date="The field Date must be a date." data-val-required="The Date field is required." id="Date" name="Date" type="text" value="01.01.0001" data-role="datepicker" class="k-input" role="combobox" aria-expanded="false" aria-owns="Date_dateview" aria-disabled="false" aria-readonly="false" data-bind="value:Date" style="width: 100%;">

Related

How to use DateRangePicker on C# Razor page?

I'm having trouble on how to implement a date range picker on a C# Razor Page. I've seen some examples for singular date pickers (like picking one date), but not much for date ranges.
So the page I'm working on uses HTML Helpers. It gets it's properties from this class/model:
public class Appointment{
[Display(Name = "Name")]
public string Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
#using (Html.BeginForm(..., ..., FormMethod.Get, ...){
<div>
#Html.LabelFor(x => x.Name)
</div>
<div>
#Html.TextBoxFor(x => x.Name)
</div>
-- the date range input field would be below the above input field, but I'm confused how to use the Html Helper for the two dates for the singular daterangepicker input field
}
The JavaScript example code for the daterangepicker is from this site, and looks like this:
<script type="text/javascript">
$(function() {
var start = moment().subtract(29, 'days');
var end = moment();
function cb(start, end) {
$('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
}
$('#reportrange').daterangepicker({
startDate: start,
endDate: end,
ranges: {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
});
</script>
Basically I'm confused on how a singular input field is going to map to both StartDate and EndDate. I see that TextBoxFor accepts one property, but not sure how you would handle more than that.
This Javascript will generate a text about the Date range, In my opinion, you can add some code to bind value to your datetime in model, Please refer to this demo.
PageModel
[BindProperty]
public Appointment appointment { get; set; }
View
<form asp-action="Privacy" method="post">
<div class="form-group">
<label asp-for="appointment.Name" class="control-label"></label>
<input asp-for="appointment.Name" class="form-control" />
</div>
<input asp-for="appointment.StartDate" type="hidden" class="form-control" />
<input asp-for="appointment.EndDate" type="hidden" class="form-control" />
<hr />
<div id="reportrange" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc; width: 100%">
<i class="fa fa-calendar"></i>
<span></span> <i class="fa fa-caret-down"></i>
</div>
<button type="submit">Submit</button>
</form>
Javscript
function cb(start, end) {
$('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
// add this code to bind value.
var s = start.toJSON();
var e = end.toJSON();
$('#appointment_StartDate').val(s);
$('#appointment_EndDate').val(e);
}
Demo:

MVC Model validation on lose focus

Is it possible to change when client side validation happens when using MVC data annotations? Currently, all validation seems to occure on keyup, but I need it to occure onchange or losefocus.
ViewModel:
[Display(Name = "First Name")]
[Required(ErrorMessage = "First Name is Required")]
public string FirstName { get; set; }
cshtml
#Html.TextBoxFor(m => m.FirstName, new { placeholder = Html.DisplayNameFor(n => n.FirstName) })
#Html.ValidationMessageFor(m => m.FirstName)
Rendered HTML
<div class="field">
<input data-val="true"
data-val-required="First Name is Required"
id="FirstName"
name="FirstName"
placeholder="First Name"
type="text"
value="">
<span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
</div>
This works as it should, but when I type into input, validation occurs as I type. How can I make validation occure after I've clicked or tabbed off the input?
Versions
.NET 4.6.1
Microsoft.Aspnet.Mvc 5.2.3
Microsoft.jQuery.Unobtrusive.Validation 3.2.3
I was able to use Javascript to get the desired behavior.
$.validator.setDefaults({
onkeyup: false
})
All validation now happens on blur

MVC TextBoxFor display date format instead of value

I’m working on ASP.NET application, and I have an issue with date formatting.
TextBoxFor is displaying Date Format instead of date.
Regional Settings:
United Kingdom, date format: “yyyy-mm-dd”.
.NET Globalization - IIS Settings:
Culture: Invariant Language (Invariant Country)
Enable Client Based Culture: false
UI Culture: Invariant Language (Invariant Country)
File: Windows-1252
Requests: utf-8
Response Headers: utf-8
Responses: utf-8
MainView (I have tried ToShortDateString() and ToString("d")) :
<td>
#item.InvoiceDate.ToShortDateString()
</td>
<td>
#item.DueDate.ToString("d")
</td>
Edit View:
<div class="form-group">
<div class="col-md-10">
#Html.Label("Invoice Date:")
<div class="fiveSpace"></div>
#Html.TextBoxFor(model => model.InvoiceDate, "{0:d}", new { type = "date" })
#Html.ValidationMessageFor(model => model.InvoiceDate)
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Due Date:")
<div class="fiveSpace"></div>
#Html.TextBoxFor(model => model.DueDate, "{0:d}", new { type = "date" })
#Html.ValidationMessageFor(model => model.DueDate)
</div>
</div>
Model:
[Required(ErrorMessage = "Please select Invoice Date.")]
public DateTime? InvoiceDate { get; set; }
[Required(ErrorMessage = "Please select Due Date.")]
public DateTime? DueDate { get; set; }
And result:
Table row
Once I try to edit dates:
Date and Inspect element
Correct value is stored in "value" but TextBoxFor displays date format. Also, when I have changed regional setting to other country, in MainView I always received dates in format "dd/mm/yyyy" and in edit view dates were displayed with US format, "mm/dd/yyyy".
I have tried:
set up <globalization uiCulture="en-GB" culture="en-GB" /> in web.config
add [DisplayFormat(DataFormatString = "{0:d}"] to model
Is the problem on my side, or IIS?
Resolved.
I've replaced mentioned TextBoxFor with:
#Html.TextBoxFor(model => model.InvoiceDate, new { #type = "date", #Value = Model.InvoiceDate.Value.ToString("yyyy-MM-dd") })
and it works.
The TextBoxFor with type="date" converts it to the <input type="date"> HTML tag which doesn't support date format customization according to the MDN.
It can be achieved by some 3rd-party JS libraries like Masked Input Plugin for jQuery or datetime-input web component

Bootstrap datepicker. Trouble binding: The value is not valid

I'm having trouble binding a property of my model using bootstrap datepicker. I'm getting the following error:
The value DATE is not valid for DATEFIELD
This is how the property is defined in my model:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime FechaDesignado { get; set; }
This is how the view is constructed:
<div class="form-group">
<div>
<input type="datetime" class="datepicker form-control" asp-for="#item.FechaDesignado"/>
<span asp-validation-for="#item.FechaDesignado" class="text-danger"></span>
</div>
</div>
Which translates to:
<div class="form-group" form="form1">
<div>
<input type="datetime" class="datepicker form-control" data-val="true" data-val-required="The FechaDesignado field is required." name="item.FechaDesignado" value="09/01/1901" />
<span class="text-danger field-validation-valid" data-valmsg-for="item.FechaDesignado" data-valmsg-replace="true"></span>
</div>
</div>
This is how it looks on my DB.
This is the code for datepicker:
<script type="text/javascript">
$(function () {
$('.datepicker').datepicker({
"autoclose": true
});
});
</script>
Post Action inside the Controller:
[HttpPost, ActionName("Management")]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> Management(int? id)
{
var storetoupdate = _context.Stores.SingleOrDefault(m => m.StoreID == id.Value);
if (await TryUpdateModelAsync(
storetoupdate, "item",
s => s.StoreName, s => s.IncomePeriodicity, s=>s.Usuario, s => s.FechaDesignado))
{
await _context.SaveChangesAsync();
return RedirectToAction("Management");
}
return RedirectToAction("Management");
}
Question: Seems like I must convert the date input field to a datetime object using DateTime.ParseExact but I don't know how to edit the controller for this. Sorry but I'm learning all this.
Thanks.
You can use DateTime.ParseExact for convert date format to datetime. Please see this for more information.
Edit
You can use data-format attribute like this for post correct format date:
<input data-format="0:MM/dd/yyyy" type="datetime" class="datepicker form-control" asp-for="#item.FechaDesignado"/>

Specify a format for "asp-for" HTML Tag (ASP.NET Core)

In an ASP.NET Core project I have to display a (readonly) date in a specific format (say "dd/mm/yyyy HH:MM")
<div class="form-group">
<label asp-for="Date" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Date" readonly class="form-control" />
</div>
</div>
How can I do it, knowing that the Date field is declared in the model like this
public DateTime Date { get { return this.Timestamp.DateTime; } }
?
Try this.
<input asp-for="Date" asp-format="{0:dd/MM/yyyy HH:mm}" readonly class="form-control" />
Alternatively, you could decorate the property with DisplayFormatAttribute.
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy HH:MM}")]
public DateTime Date { get { return this.Timestamp.DateTime; } }
The markup you have would not need to change.
If it is read only, you could hardcode as -
<input value="#Model.Date.ToString("dd/MM/yyyy HH:mm")" readonly class="form-control" />
Or display as text
<div class="form-group">
<label asp-for="Date" class="col-md-2 control-label"></label>
<div class="col-md-10 form-control-static">
#Model.Date.ToString("dd/MM/yyyy HH:mm")
</div>
</div>
Using ASP.Core TagHelpers as per your question;
[DataType(DataType.Date)]
public DateTime Date { get { return this.Timestamp.DateTime; } }
will format the input fields nicely in accordance with your locale setting.
I haven't found a tag helper solution for any other tags, looks like hardcoding as per Win's answer

Categories