Jquery UI Datepicker - Dependent Datepicker Exclude Holidays in Maxdate - javascript

I am trying to exclude Array Dates and Sundays in Dependent Datepicker.
The first datepicker works really well while the second datepicker doesn't exclude Array dates and sundays in Maxdate.
Second datepicker must selectable within 7 working days which should exclude Sunday and Array Dates.
I believe there's should be an easy way to achieve this.
Any Suggestion?
Here's the code :(
$(document).ready(function() {
var d = new Date();
var array = ["10-12-2019","05-12-2019"];
var monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"];
today = monthNames[d.getMonth()] + ' ' + d.getDate() + ' ' + d.getFullYear();
function includeDate(date) {
var dateStr = jQuery.datepicker.formatDate('dd-mm-yy', date);
// Date 0 = Sunday & 6 = Saturday
return date.getDay() !== 0 && array.indexOf(dateStr) === -1;
}
function getTomorrow(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
$('#datepicker2').attr('readonly', 'readonly');
$('#datepicker1').datepicker(
{
defaultDate: "+1d",
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: 1,
beforeShowDay: function(date) {
return [includeDate(date)];
},
maxDate: (function(max) {
var nextAvailable = new Date();
var count = 0;
var extra = 0;
while(count < max) {
nextAvailable = getTomorrow(nextAvailable);
if ( !includeDate(nextAvailable) ) {
extra++;
} else {
count++;
}
}
return max + extra;
})
(3)
});
$('#datepicker1').change(function () {
var from = $('#datepicker1').datepicker('getDate');
var date_diff = Math.ceil((from.getTime() - Date.parse(today)) / 86400000);
var maxDate_d = date_diff + 7 +'d';
date_diff = date_diff + 'd';
$('#datepicker2').val('').removeAttr('readonly').removeClass('hasDatepicker').datepicker({
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: date_diff +1,
beforeShowDay: function(date) {
return [includeDate(date)];
},
maxDate: (function(max) {
var nextAvailable = $('#datepicker1').datepicker('getDate');
var count = 0;
var extra = 0;
while(count < max) {
nextAvailable = getTomorrow(nextAvailable);
if ( !includeDate(nextAvailable) ) {
extra++;
} else {
count++;
}
}
return max + extra;
})
(7)
});
});
});
http://jsfiddle.net/nLveychs/83/

For your code, it is almost right. You just forgot one thing for the second date picker. That is, you did not add the date_diff value to the return value of the maxDate() anonymous function. I was going to pass the date_diff by adding it to the parameter. Nonetheless, I found a bug. It can't be done that way, because any previous un-selectable days, will turn into additional extra days. Thus, the only way to add date_diff is start from the day of date picker1 and add the return value of maxDate's anonymous function to date_diff.
I also took out some unnecessary codes. You can just get the date differences simply subtracting datepicker1 date to today date without needing to parse a date string. Plus, date_diff can be as was without needing a "d" to be added to it.
Also, take note that, when you calculate the different days between two dates, for your code, it work that way, because datepicker's date picked object is set to the 0 hour of the day. That code may not work for other scenario. The for sure way to get the day difference between two dates is by setting their hours, minutes, seconds, and milliseconds(if needed) to zeroes.
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
<script src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script>
$(document).ready(function() {
var array = ["10-12-2019","05-12-2019"];
function includeDate(date) {
var dateStr = jQuery.datepicker.formatDate('dd-mm-yy', date);
// Date 0 = Sunday & 6 = Saturday
return date.getDay() !== 0 && array.indexOf(dateStr) === -1;
}
function getTomorrow(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
$('#datepicker2').attr('readonly', 'readonly');
$('#datepicker1').datepicker(
{
defaultDate: "+1d",
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: 1,
beforeShowDay: function(date) {
return [includeDate(date)];
},
maxDate: (function(max) {
var nextAvailable = new Date();
var count = 0;
var extra = 0;
while(count < max) {
nextAvailable = getTomorrow(nextAvailable);
if ( !includeDate(nextAvailable) ) {
extra++;
} else {
count++;
}
}
return max + extra;
})
(3)
});
$('#datepicker1').change(function () {
var from = $('#datepicker1').datepicker('getDate');
// Date diff can be obtained like this without needing to parse a date string.
var date_diff = Math.ceil((from - new Date()) / 86400000);
$('#datepicker2').val('').removeAttr('readonly').removeClass('hasDatepicker').datepicker({
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: date_diff + 1,
beforeShowDay: function(date) {
return [includeDate(date)];
},
maxDate: (function(max) {
var nextAvailable = $('#datepicker1').datepicker('getDate');
var count = 0;
var extra = 0;
while(count < max) {
nextAvailable = getTomorrow(nextAvailable);
if ( !includeDate(nextAvailable) ) {
extra++;
} else {
count++;
}
}
/*
* Date diffent have to be added to return value.
*/
return max + date_diff + extra;
})
(7)
});
});
});
</script>
<p>datepicker1 <input id="datepicker1"></p>
<p>datepicker2 <input id="datepicker2"></p>

Related

Choose year for Datepicker

Good afternoon. In my project, I need to display a calendar for a year. I did it with datepicker. Now I need to make it so that I can select the year of this calendar from another page. Please tell me how to do this? (A year comes to the page with a request)
function drawDatepicker(){
$('#picker').datepicker({
showOtherMonths: true,
selectOtherMonths: true,
numberOfMonths: [3,4],
stepMonths: 0,
yearRange: chouseYear + ":" + chouseYear,
showCurrentAtPos: new Date().getMonth(),
onSelect: function (dateText, datePicker) {
datePicker.drawMonth += $("#picker").datepicker("option", "showCurrentAtPos");
var radVal = $('input[name="typeDay"]:checked').val();
if(radVal == 1){
addOrRemoveDate(dateText, day_off);
}
if(radVal == 2){
addOrRemoveDate(dateText, radonica);
}
console.log(day_off);
console.log(radonica);
},
beforeShowDay: function (date) {
var year = date.getFullYear();
var month = padNumber(date.getMonth() + 1);
var day = padNumber(date.getDate());
var dateString = day + "." + month + "." + year;
var gotDate1 = jQuery.inArray(dateString, day_off);
if (gotDate1 >= 0) {
return [true, "ui-state-highlight"];
}
var gotDate2 = jQuery.inArray(dateString, radonica);
if (gotDate2>=0){
return [true, "ui-widget-header"];
}
return [true, ""];
}
});
}
Screen calendar
I found this solution to the problem. I specified defaultDate 01.01 of the desired year and showCurrentAtPos to 0. If the current year is specified, then defaultDate is today, and showCurrentAtPos is the number of the month
defaultDate: defaultDate,
showCurrentAtPos: sCAPos,

JQuery UI Datepicker - MaxDate exclude disabled days

I am trying to exclude disabled dates when counting MaxDate.
I tried many ways but still doesn't work.
Any suggestion?
02-12-2019 and Sundays has been disabled but the Maxdate include the disabled date.
Maxdate should be 3 days which excludes disabled days and Maxdays starts by today.
My goal is to add days if the days between today until max days has disabled.
Add 1 day per disabled day
Update
Now i am able to Exclude sunday when counting maxdate but i still can't exclude the array date where it should add one more day after 02-12-2019.
Updated Code :(
<script>
var array = ["02-12-2019"]
//new
function includeDate(date) {
return date.getDay() !== 7 && date.getDay() !== 0;
}
function getTomorrow(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
//prev
$('input').datepicker(
{
defaultDate: "+1d",
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: 1,
beforeShowDay: function(date) {
var string = jQuery.datepicker.formatDate('dd-mm-yy', date);
var isDisabled = ($.inArray(string, array) != -1);
return [includeDate(date) && !isDisabled];
},
maxDate: (function(max) {
var today = new Date();
var nextAvailable = getTomorrow(today);
var count = 0;
var countz = 1;
var newMax = 0;
while(count < max) {
if (includeDate(nextAvailable) ) {
count++;
}
if (includeDate(nextAvailable) ) {
countz++;
}
newMax++;
nextAvailable = getTomorrow(nextAvailable);
}
return newMax;
})
(3)
});
http://jsfiddle.net/3o1dmvw5/96/
This below should be the solution. The problem with your code is that you forgot to verify the date string to see if it is in the array or not using your includeDate() function. Thus, your includeDate() function allow that date, while maxDate didn't allow that date.
Also, you can also use array.indexOf() instead of jQuery's inArray. I am pretty sure that native array.indexOf() probably is faster.
Besides that, I modify your maxDate() function a little bit. It now look less confusing. I used window onload so that I can debug the code easy. You can just take that out.
For my version, when it come to verify the days, beforeShowDay and includeDate does the same thing. Thus, I edited beforeShowDay() to just return the value from the function includeDate().
Also, you should change the input selector to an ID(#) or Class(.). Otherwise, your datepicker will proc on all input fields.
Also, I modified you includeDate() function. There isn't a day 7 as 0 - 6 = Sunday - Saturday.
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
<script src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script>
var array = ["02-12-2019"]
//new
function includeDate(date) {
var dateStr = jQuery.datepicker.formatDate('dd-mm-yy', date);
// Date 0 = Sunday & 6 = Saturday
return date.getDay() !== 0 && array.indexOf(dateStr) === -1;
}
function getTomorrow(date) {
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
}
//prev
window.onload = function(){
$('input').datepicker(
{
defaultDate: "+1d",
inline: true,
showOtherMonths: true,
changeMonth: true,
selectOtherMonths: true,
required: true,
showOn: "focus",
numberOfMonths: 1,
minDate: 1,
beforeShowDay: function(date) {
return [includeDate(date)];
},
maxDate: (function(max) {
// Next available is today at first.
var nextAvailable = new Date();
var count = 0;
var extra = 0;
while(count < max) {
/*
* Next available is here so that getTomorrow does not need
* to run an extra time when the loop is completed.
*
*/
nextAvailable = getTomorrow(nextAvailable);
// If the day is not available then we need to add an extra day.
if ( !includeDate(nextAvailable) ) {
extra++;
// Else we just increase the count.
} else {
count++;
}
}
// Return max + extra.
return max + extra;
})
(3)
});
};
</script>
<p>Date: <input type="text" id="datepicker"></p>

enable previous dates of one week on date picker in jquery

i am trying to disable all the dates on datepicker except dates 7days before from current date but it disables all the dates. it works fine when i un-comment the commented code lines and comment the else part "return true" line.
but it disables the weekends too. so how can i achieve it without using noweekends(currentdate)
$(document).ready(function () {
$(function () {
{
var currentDate = new Date();
$("#StartDate").datepicker({ beforeShowDay: DisableSpecificDates });
$("#StartDate").datepicker({ dateFormat: 'yy-mm-dd' }).val();
$("#StartDate").datepicker("setDate", currentDate);
}
});
$(function () {
{
var currentDate = new Date();
$("#StartDte").datepicker({ beforeShowDay:DisableSpecificDates });
$("#StartDte").datepicker("setDate", currentDate);
}
});
function DisableSpecificDates(currentdate) {
//var weekenddate = $.datepicker.noWeekends(currentdate);
var difference;
var minDate = new Date();
var todaydate = new Date();
var d = todaydate.getDate();
var prevdays = 0;
difference = d - 6;
if (d <= prevdays && d > 0) {
minDate.setDate(difference);
}
else {
minDate.setDate(difference);
}
var datemin =new Date (minDate);
var day = todaydate.getDay();
switch (day)
{
case 0:
case 1:
prevdays = 4;
break;
case 2:
case 3:
case 4:
case 5:
prevdays = 2;
break;
case 6:
prevdays = 3;
break;
}
datemin.setDate(datemin.getDate()+1);
var dateOfMin = (minDate.getDate()) - prevdays - 1;
minDate.setDate(dateOfMin);
if (currentdate > todaydate || currentdate < minDate)
{
return false;
}
return true;
//return weekenddate;
}
Seems like you want to set date range as example below , so below will fix date range and also disable weekends
$( "#datepicker" ).
datepicker({ minDate: -20, maxDate: "+1M +10D", beforeShowDay: $.datepicker.noWeekends });
check datepicker : Date Range
or try like this
$('#date-time-picker').datepicker({
format: 'YYYY-MM-DD',
useCurrent: false,
showClose: true,
minDate: '2018-03-09',
maxDate: '2018-03-15',
beforeShowDay: $.datepicker.noWeekends
})
but here you need to give mindate and max date from script , for simplicity i hardcoded date

Calculate date from jquery datepicker

I am calculating the age from jquery datepicker. But this works when only the date is in(mm/dd/yy) format. I need to get this working in dd/mm/yy.
//Code
$('#dob').datepicker({
onSelect: function(value, ui) {
var today = new Date(),
dob = new Date(value),
age = new Date(today - dob).getFullYear() - 1970;
$('#age').text(age);
},
maxDate: '+0d',
yearRange: '1920:2010',
changeMonth: true,
changeYear: true
});
If i try to set dateFormat: 'mm/dd/yy' in the property this wont work.
Any help?
Demo Fiddle mm/dd/yy Demo Fiddle dd/mm/yy
jQuery
onSelect: function (value, ui) {
var today = new Date();
var format = value.split("/");
var dob = new Date(format[2], format[0], format[1]);
var diff = (today - dob);
var age = Math.floor(diff / 31536000000);
$('#age').text(age);
},
Reference
Hope it helps....
Try this:
http://jsfiddle.net/lotusgodkk/GCu2D/120/
Js:
$('#dob').datepicker({
onSelect: function(value, ui) {
console.log(ui.selectedYear)
var today = new Date(),
dob = new Date(value),
age = ui.selectedYear - 1970; //This is the update
$('#age').text(age);
},
maxDate: '+0d',
yearRange: '1920:2010',
changeMonth: true,
changeYear: true,
});
If you inspect the ui object in console, you'll see that it stores year,day,month separately. You can access them like ui.selectedDay or selectedYear . Hope this helps.
this answer will work fine for the all the dates as the month starts from 0 in date function. for date format(dd-mm-yy).
var now= new Date();
var year= now.getFullYear();
$('#dob').datepicker({
onSelect: function (value, ui) {
var today = new Date();
console.log(today.getFullYear());
var format = value.split("-");
console.log(format[2]);
var dob = new Date(format[2], format[1]-1, format[0]);
console.log(dob);
var diff = (today - dob);
var age = Math.floor(diff / 31536000000);
$('#age').text(age);
},
dateFormat: 'dd-mm-yy',
maxDate: '+0d',
yearRange: '1920:'+year,
changeMonth: true,
changeYear: true
});
$("#dob").datepicker({
onSelect: function (value, ui) {
debugger
var today = new Date();
var year = today.getFullYear() - ui.selectedYear;
var month = today.getMonth() - ui.selectedMonth;
var date = today.getDate() - ui.selectedDay;
if ((year == 0 && month == 0 && date < 0) || (year == 0 && month < 0) || (year < 0)) {
$("#lbl6").show();
$("#age").val("");
} else if ((year == 0) || (year > 0 && month == 0 && date >= 0) || (year > 0 && month > 0)) {
$("#age").val(year);
} else if ((year > 0 && month == 0 && date < 0) || (year > 0 && month < 0)) {
$("#age").val(year - 1);
}
},
dateFormat: 'dd M y',
changeMonth: true,
changeYear: true,
yearRange: '1900:2020'
});

datepicker national holidays count

I have 2 inputs where dates are selected #startdate and #enddate. I am using datepicker and have currently disabled weekends and holidays, this is working great!
I then have a #days input which calculates the difference between the 2 dates, this date difference then has a weekend count taken from it.
I would like to create a holiday count so I can also minus this from the differnce in days.
So i would end up with
$('#days').val((Math.abs(($d2new-$d1new)/86400000) - weekend_count - holidaycount) + 1);
My current code is as follows (this has been taken form other stackoverflow questions and is working great :) towards the bottom is the var holidaycount which is what i am struggling with. Any help would be greatly appreciated.
//holidays
var natDays = [
[1, 1, 'uk'],
[1, 2, 'uk'],
[1, 3, 'uk'],
[1, 4, 'uk'],
[12, 24, 'uk'],
[12, 25, 'uk'],
[12, 26, 'uk'],
[12, 27, 'uk'],
[12, 28, 'uk'],
[12, 29, 'uk'],
[12, 30, 'uk'],
[12, 31, 'uk']
];
function noWeekendsOrHolidays(date) {
var noWeekend = $.datepicker.noWeekends(date);
if (noWeekend[0]) {
return nationalDays(date);
} else {
return noWeekend;
}
}
function nationalDays(date) {
for (i = 0; i < natDays.length; i++) {
if (date.getMonth() == natDays[i][0] - 1 && date.getDate() == natDays[i][1]) {
return [false, natDays[i][2] + '_day'];
}
}
return [true, ''];
}
// do initialization here
$("#startdate").datepicker({
dateFormat: 'dd-mm-yy',
changeMonth: true,
changeYear: true,
firstDay: 1,
yearRange: '0:+100',
beforeShowDay: noWeekendsOrHolidays,
onSelect: function( selectedDate ) {
$("#enddate").datepicker("option","minDate",selectedDate );
$("#enddate2").datepicker("option","minDate",selectedDate );
},
minDate: '+1d',
maxDate: '+' + DAY_DIFFERENCE + 'd'
});
// do initialization here
$("#enddate").datepicker({
dateFormat: 'dd-mm-yy',
changeMonth: true,
changeYear: true,
firstDay: 1,
yearRange: '0:+100',
beforeShowDay: noWeekendsOrHolidays,
maxDate: '+' + DAY_DIFFERENCE + 'd'
});
// do initialization here
$("#enddate2").datepicker({
dateFormat: 'dd-mm-yy',
changeMonth: true,
changeYear: true,
firstDay: 1,
yearRange: '0:+100',
beforeShowDay: noWeekendsOrHolidays,
onSelect: function( selectedDate ) {
$d1 = $('#startdate').val();
$d2 = $('#enddate2').val();
$myDateParts1 = $d1.split("-");
$myDateParts2 = $d2.split("-");
$d1flip = new Date($myDateParts1[2], ($myDateParts1[1]-1), $myDateParts1[0]);
$d2flip = new Date($myDateParts2[2], ($myDateParts2[1]-1), $myDateParts2[0]);
$newdate1 = $d1flip.format("ddd mmm dd hh:MM:ss yyyy");
$newdate2 = $d2flip.format("ddd mmm dd hh:MM:ss yyyy");
// For Opera and older winXP IE n such
$d1new = Date.parse($newdate1);
$d2new = Date.parse($newdate2);
var weekend_count = 0;
for (i = $d1new.valueOf(); i <= $d2new.valueOf(); i+= 86400000){
var temp = new Date(i);
if (temp.getDay() == 0 || temp.getDay() == 6) {
weekend_count++;
}
}
var holidaycount = 0;
for (i = $d1new.valueOf(); i <= $d2new.valueOf(); i+= 86400000){
var temp = new Date(i);
if (**date in var natDays & is in selected difference range**) {
holidaycount++;
}
}
console.log(weekend_count);
console.log(holidaycount);
$('#days').val((Math.abs(($d2new-$d1new)/86400000) - weekend_count - holidaycount) + 1);
}
});
}, 'html');
return false;
});
}
EDIT
From the answer, I have inserted the function and tried this....
console.log(holidaycount); returns 0 but with the chosen dates i selected it should have been 10
var holidaycount = 0;
for (i = $d1new.valueOf(); i <= $d2new.valueOf(); i+= 86400000){
var temp = new Date(i);
if (isHoliday(temp)) {
holidaycount++;
}
}
UPDATE: modified getMonth() to getMonth() + 1 accordingly to the comments.
**date in var natDays & is in selected difference range**
date is in selected difference range is always true as new Date(i) is inside said range (just like in the loop for weekend_count: you didn't bother with checking whether you're in the range).
Now, checking if the date inside temp is a holiday, you may want to use a function (though you still can do it straight in your code):
/* dateObject is a JS Date object (e.g. dateObject = new Date();) */
/* country is the country we test holidays for */
function isHoliday(dateObject, country) {
/* let's assume natDays is global, otherwise pass it as a third argument to this function */
for(var i = 0; i < natDays.length; i++) {
/* natDays[i][0] is a day, natDays[i][1] is a month, natDays[i][2] is a country indicator */
if(parseInt(dateObject.getDate()) == parseInt(natDays[i][0]) && parseInt(dateObject.getMonth()) + 1 == parseInt(natDays[i][1]) && country.toLowerCase() == natDays[i][2].toLowerCase()) {
/* found a day and a month matching our current Date's day and month: interrupt and tell caller dateObject is a holiday */
return true;
}
}
/* end of loop, we parsed all possible holidays without finding any match for our Date: tell caller the given Date is not a holiday */
return false;
}
Now to put it in your code:
if (isHoliday(temp, 'uk')) {
holidaycount++;
}
This should do the trick, though it may require some refactoring (did not test this code), and there is probably more elegant ways to do it (like modding the Date object's prototype to use this function as a method of the object).

Categories

Resources