How to disable the past dates in the Kendo date picker? - asp.net-mvc

How to disable the past dates in the Kendo date picker ? ( Date Picker validation)
That will allow the user to select only the current date and future date.
In the HTML :
#Html.EditorFor(Model => Model.AppointmentDate)
In the JQuery :
$('#AppointmentDatee').data('kendoDatePicker')

The shortest way to disable past dates is using min parameter with current date value:
var presentDate = new Date();
$(function () {
var datepicker = $('#AppointmentDate').kendoDatePicker({
value: presentDate,
min: presentDate,
}).data('kendoDatePicker');
});
If you're using Razor with #Html.Kendo() helper, use DatePickerBuilderBase.Min() method:
#(Html.Kendo().DatePicker().Name("AppointmentDate").Min(DateTime.Today))
However, the min parameter will remove all disabled past dates (i.e. they're not shown in calendar view). If you want to show disabled dates but the user cannot interact with them (by clicking the date), use k-state-disabled CSS class in empty option inside month parameter:
var datepicker = $('#AppointmentDate2').kendoDatePicker({
value: presentDate,
min: presentDate,
month: {
empty: '<div class="k-state-disabled">#= data.value #</div>'
}
}).data('kendoDatePicker');
If #(Html.Kendo()) helper is used, use DisabledDates to call a function which disables past dates like example below:
<script>
var getPastDates = function(begin, end) {
for (var dtarr = [], date = start; date < end; date.setDate(date.getDate() + 1)) {
dtarr.push(new Date(dt));
}
return dtarr;
}
function disablePastDates(date) {
var pastDate = getPastDates(new Date('0001-01-01T00:00:00Z'), new Date());
if (date && compareDates(date, dates)) {
return true;
}
else {
return false;
}
}
function compareDates(date, dates) {
for (var i = 0; i < dates.length; i++) {
if (dates[i].getDate() == date.getDate() &&
dates[i].getMonth() == date.getMonth() &&
dates[i].getYear() == date.getYear()) {
return true;
}
}
}
</script>
Helper usage:
#(Html.Kendo().DatePicker().Name("AppointmentDate").DisableDates("disablePastDates"))
Working examples:
JSFiddle demo 1 (hidden past dates)
JSFiddle demo 2 (grayed-out past dates)
References:
Kendo.Mvc.UI.Fluent.DatePickerBuilderBase.Min(DateTime)
Show Out-of-Range Dates as Disabled
Kendo MVC DatePicker - Disable dates
Similar issue (with different approach):
How to disable past dates without hiding them in Kendo date picker?

if you use jquery for your kendoDatePicker , this code may help you!
$("#MyDatapickerElement").kendoDatePicker({
value: new Date(),
disableDates: function (date) {
if (date <= new Date()) {
return true;
} else {
return false;
}
}
});

If using Html.Kendo().DatePicker() you can show the disabled dates using the MonthTemplate. Example below shows the Minimum Date set to DateTime.Today and sets the MonthTemplate to show past dates as disabled.
Html.Kendo().DatePicker()
.Name("MyDate")
.Min(DateTime.Today)
.MonthTemplate(m=>m
.Empty("<div class=\"k-state-disabled\">#= data.value #</div>")
)

Related

Showing only days in React Datepicker calendar

I am trying to use React Datepicker in my React application. I am following this document - https://reactdatepicker.com/
I need a date picker which will only show 31 days.
Here is the simple code from the react-datepicker documents.
<DatePicker selected={dayPicker} onChange={(date) => setDayPicker(date)} dateFormat="yyy/MM/dd" isClearable={true}
/>
It shows the full calendar. How can I customize the calendar ? Is it possible to remove the header from the calendar and replace it with a text "Days" ?
Following code will give you date picker for current year with only Month in header.
You just need to use renderCustomHeader property of DatePicker.
const year = 2022; // can be provided externally
const month = 2; // can be provided externally
const date = 24; // can be provided externally
const [startDate, setStartDate] = useState(new Date(year, month, date));
const minDate = new Date(year, month, 1);
const maxDate = new Date(year, month + 1 , 0);
const renderDayContents = (day, date) => {
if(date < minDate || date > maxDate){
return <span></span>;
}
return <span>{date.getDate()}</span>;
};
return (
<DatePicker
selected = {startDate}
minDate = {minDate}
maxDate = {maxDate}
onChange = {(date) => setStartDate(date)}
renderCustomHeader = {() => <div></div>}
renderDayContents = {renderDayContents}
dateFormat = "dd"
/>
);
This is how it will look:
Explaination:
We can create out customer header with the renderCustomHeader property of DatePicker.
This functions returns JSX (kind of html) which has empty div as we don't want to show anything in header.
Apart from renderCustomHeader property, we have set minDate and maxDate property of DatePicker to restrict it for current month.
You need to copy above code in a component where you are using DatePicker.
You can refer https://reactdatepicker.com/#example-custom-header to know more about custom header for DatePicker

Error in date validation MVC

My model class property looks like this
public DateTime PurchaseDate { get; set; }
and inside view
#Html.TextBoxFor(model => model.PurchaseDate, new { #class = "form-control date-picker" })
#Html.ValidationMessageFor(model => model.PurchaseDate)
and I am giving a date like this in form
19/06/2015
But it gives validation message and not allows page to be submitted, message is like this
The field PurchaseDate must be a date.
if I give date in mm/dd/yyyy format it works. Can anyone point out what I am doing wrong here?
The client side error is occurring because by default jquery.validate tests the value using the MM/dd/yyyy format. You can override the $.validator.addMethod('date', function (value, element) function to test that the value is in the dd/MM/yyyy you expect. Note the following code is from my own jquery plugin associated with a #Html.DatePickerFor() helper method which renders a data-dateformat attribute in the output based on the servers culture, so it may be an overkill for your needs
Add the following scripts (not in document.ready, but after jquery.validate.unobtrusive)
Date.prototype.isValid = function () {
return !isNaN(this.getTime());
}
globalDate = function (value, formatString) {
// Initialise a new date
var date = new Date(0);
if (value == undefined) {
// Return todays date
return date;
}
// Get the components of the format
// The separator can be forward slash, hyphen, dot and/or space
var regex = new RegExp(/([dMy]+)([\s/.-]+)([dMy]+)([\s/.-]+)([dMy]+)/);
//var format = regex.exec(this.inputFormat);
var format = regex.exec(formatString);
// Get the components of the value
regex = new RegExp(/(\d+)([\s/.-]+)(\d+)([\s/.-]+)(\d+)/);
value = regex.exec(value);
// Check the value is valid
if (value === null || value[2] !== format[2] || value[4] !== format[4]) {
// Its not valid
date.setTime(Number.NaN);
return date;
}
// TODO: What if year entered as 2 digits?
var day = Number.NaN;
var month = Number.NaN;
var year = Number.NAN;
if (format[1].charAt(0) === 'd') {
// little-endian (day, month, year)
day = parseInt(value[1]);
month = parseInt(value[3]) - 1;
year = parseInt(value[5]);
} else if (format[1].charAt(0) === 'M') {
// middle-endian (month, day, year)
day = parseInt(value[3]);
month = parseInt(value[1]) - 1;
year = parseInt(value[5]);
} else {
// big endian (year, month, day)
day = parseInt(value[5]);
month = parseInt(value[3]) - 1;
year = parseInt(value[1]);
}
date.setFullYear(year);
date.setMonth(month);
date.setDate(day);
// Check its valid
if (date.getDate() !== day || date.getMonth() !== month || date.getFullYear() !== year) {
date.setTime(Number.NaN);
return date;
}
return date;
}
$.validator.addMethod('date', function (value, element) {
var format = "dd/MM/yyyy";
return this.optional(element) || globalDate(value, format).isValid();
}
If you only ever want to test for the format dd/MM/yyyy, then you could simplify the globalDate() function by just using
var date = new Date();
date.setHours(0, 0, 0, 0);
var components = value.split('/');
var day = components[0];
var month = components[1];
var year = components[2];
date.setFullYear(year);
....
Edit
Further to OP's comments regarding server side validation failing, the server culture needs to accept a date string in the format dd/MM/yyyy. In the web.config.cs file
<system.web>
<globalization culture="en-AU" uiCulture="en-AU"/> // adjust to your culture code
....
If you want to explicitly set the expected date format for your model property then you can do this using the DisplayAttribute
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime PurchaseDate { get; set; }
Otherwise, the current culture of the server would be used (which in your case happens to be MM/dd/yyyy).
It appears that in order for client-side validation to respect the DataFormatString we need to use EditorFor in place of TextBoxFor
#Html.EditorFor(model => model.PurchaseDate, new { #class = "form-control date-picker" })
#Html.ValidationMessageFor(model => model.PurchaseDate)

Highchart xAxis labels formatter not displaying returned value

I've been fighting this problem for most of the day now, so I figure I'd ask here...
I'm creating a plot using highcharts, and I want to use a datetime xAxis. The label I wish to show on this axis is a calculated value, relative to a set of specific dates. So I use a labels.formatter function which have access to the previous and the last dates, and relative to these dates I do some logics.
The logic is that if this.value (from within the formatter) is before the last one, the axis should show months since previous ones, if this.value == last it should show 0 and if this.value > last it should show months since last.
I have some helper functions that are called in my code, they have been used in many occasions and work as they should.
Below is the implementation of my label formatter for the xAxis.
gVars.reportAddedResistance.MonthSinceUsed = new Array();
this.highchart.options.xAxis.labels.formatter = function() {
var mbDec;
var mod;
var result;
var returnValue = null;
var isSet;
var previous = new Date(self.data.plotConf.previousDrydockDate);
var last = new Date(self.data.plotConf.lastDrydockDate);
var val = new Date(this.value);
if(val.getTime() < last.getTime()) {
// BEFORE LAST DRYDOCK
mbDec = Utils.monthsBetweenDecimal(previous, val);
mod = mbDec % 1;
if(mod <= (1 / 30.4375)) {
result = Math.round(mbDec);
isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
if(isSet == -1) {
gVars.reportAddedResistance.MonthSinceUsed.push(result);
//console.log('',"LESS Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
returnValue = result;
}
}
}
else if(val.getTime() == last.getTime()){
// AT LAST DRYDOCK
var result = 0;
isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
if(isSet == -1) {
gVars.reportAddedResistance.MonthSinceUsed.push(result);
//console.log('',"EVEN Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
returnValue = result;
}
}
else if(val.getTime() > last.getTime()){
// AFTER LAST DRYDOCK
mbDec = Utils.monthsBetweenDecimal(last, val);
mod = mbDec % 1;
if(mod <= (1 / 30.4375)) {
result = Math.round(mbDec);
isSet = gVars.reportAddedResistance.MonthSinceUsed.indexOf(result);
if(isSet == -1) {
gVars.reportAddedResistance.MonthSinceUsed.push(result);
//console.log('',"MORE Returning "+result+" Used: "+gVars.reportAddedResistance.MonthSinceUsed);
returnValue = result;
}
}
}
return returnValue;
};
The value of previous is (from console.log):
Date {Tue Jun 15 2010 02:00:00 GMT+0200 (Romance Daylight Time)}
The value of last is (from console.log):
Date {Sat Jun 15 2013 02:00:00 GMT+0200 (Romance Daylight Time)}
If I enable the console.log output I get this output, which to me indicates that the logics and date comparisons is working as expected:
LESS Returning 31 Used: 31
LESS Returning 32 Used: 31,32
LESS Returning 33 Used: 31,32,33
LESS Returning 34 Used: 31,32,33,34
LESS Returning 35 Used: 31,32,33,34,35
EVEN Returning 0 Used: 31,32,33,34,35,0
MORE Returning 1 Used: 31,32,33,34,35,0,1
MORE Returning 2 Used: 31,32,33,34,35,0,1,2
MORE Returning 3 Used: 31,32,33,34,35,0,1,2,3
MORE Returning 4 Used: 31,32,33,34,35,0,1,2,3,4
MORE Returning 5 Used: 31,32,33,34,35,0,1,2,3,4,5
MORE Returning 6 Used: 31,32,33,34,35,0,1,2,3,4,5,6
MORE Returning 7 Used: 31,32,33,34,35,0,1,2,3,4,5,6,7
MORE Returning 8 Used: 31,32,33,34,35,0,1,2,3,4,5,6,7,8
My problem is, that the returned values are not displayed on my plot. If I change the formatter function to just return this.value it displays them all, without any problems, but for some reason I cannot identify the return values (as seen in the above console.log output) is not shown.
My xAxis is configured like this:
xAxis: {
type : 'datetime',
dateTimeLabelFormats: {
day: '%Y-%m-%d',
week: '%Y-%m-%d',
month: '%Y-%m-%d',
year: '%Y-%m'
},
startOnTick : false,
tickInterval : 24 * 3600 * 1000 * 1, // 1 day
title : {
text : 'Months relative to drydockings',
style : {
fontSize : '9pt',
fontFamily : 'Arial'
}
},
labels : {
maxStaggerLines : 1,
style : {
fontSize : '7pt',
fontFamily : 'Arial'
}
}
},
I'm stuck - PLEASE HELP!!! :-)
EDIT: I'm using Highcharts JS v3.0.7 (2013-10-24)
The solution to my problem was to add this to the formatter:
if(this.isFirst) {
gVars.noOfSeriesCalled++;
}
if(gVars.noOfSeriesCalled == this.axis.series.length) {
// The stuff thats posted above
}
else {
return null;
}
I think its an error in the library that I have to use a global variable to keep track of how many iterations I've been through.
The correct implementation, as seen from my perspective, would be that the formatting function were called once for each tick in the xAxis, regardless of how many series are added to the plot.

how to disable previously selected dates in jquery datepicker

I have written code in jsfiddle.net/udgeet/VUb5r/
I have to disable the previously selected date
You can use datePicker's beforeShowDay option to specify which dates you want to enable or disable.
Then it's just a case of writing a functions to
a) get the dates from the select into an array:
function daysToDisable() {
var dates = [];
for (i = 0; i < $('#inputdates option').length; i++) {
dates[i] = new Date($('#inputdates option').eq(i).val()).toString();
}
return dates;
}
and b) return true or false if the current date is in the array
function disableDates(date) {
var days = daysToDisable();
for (i = 0; i < days.length; i++) {
if ($.inArray(date.toString(), days) != -1) {
return [false];
}
}
return [true];
}
http://jsfiddle.net/vy562/1/

jquery date picker

just wondering is there a way to disable all the weekends in the jquery date picker?
Just having a quick look at the documentation, best guess would be to use the beforeShowDay event to disable the days you don't want to be selectable.
use "$("#datepicker").datepicker({ beforeShowDay: $.datepicker.noWeekends });" (change the id selector to match your field).
Do you not want them to be clickable or do you just want to not display them?
The following will hide them:
$("#yourDatePicker").datepicker({ beforeShowDay: $.datepicker.noWeekends });
If you still want to display the weekends, just not let them be selectable, you can use the beforeShowDay. This will check each day to see if it is a Sunday or Saturday, and if it is, returns false so that it will be disabled.
$(document).ready(function () {
$('#myDatePicker').datepicker({
beforeShowDay: disableWeekends
});
function disableWeekends(date) {
var daysToDisable = [0, 6];
var day = date.getDay();
for (i = 0; i < daysToDisable.length; i++) {
if ($.inArray(day, daysToDisable) != -1) {
return [false];
}
}
return [true];
}
});

Resources