JS Datepicker: Disable past dates + specific days of the week + specific dates - javascript

I have a datepicker in JS where I disabled passed dates AND only allow saturdays like this:
$(document).ready(function(){
$("#aankomstdatum").datepicker({
dateFormat: "dd-mm-yy",
numberOfMonths:2,
minDate: 0,
beforeShowDay: function(date){
var day = date.getDay();
return [day == 6];
}});
});
I also have a code that lets me disable specific dates like this:
/** Days to be disabled as an array */
var disableddates = ["26-05-2018"];
function DisableSpecificDates(date) {
var m = date.getMonth();
var d = date.getDate();
var y = date.getFullYear();
// First convert the date in to the mm-dd-yyyy format
// Take note that we will increment the month count by 1
var currentdate = (m + 1) + '-' + d + '-' + y ;
// We will now check if the date belongs to disableddates array
for (var i = 0; i < disableddates.length; i++) {
// Now check if the current date is in disabled dates array.
if ($.inArray(currentdate, disableddates) != -1 ) {
return [false];
}
}
}
With adding this, it works:
beforeShowDay: DisableSpecificDates
The issue I have is that i can't make both work. I'm not sure How can disable the past dates and all days except saturdays AND also disable specific given dates in the array, while seperatly they do work. I always get syntax errors when trying for example:
beforeShowDay: DisableSpecificDates, function(date){
var day = date.getDay();
return [day == 6];
}});
Is this possible to do?

Yes, it's possible to achieve this. You want to create one function and return [false] from it if:
date is a Saturday or
date is contained within disableddates array
Here's the example:
var disableddates = ["26-04-2018"];
function DisableDates(date) {
var selectable = !isSaturday(date) && !isDateDisabled(date);
return [selectable];
}
function isSaturday(date) {
var day = date.getDay();
return day === 6;
}
function isDateDisabled(date) {
var m = date.getMonth() + 1;
var d = date.getDate();
var y = date.getFullYear();
// First convert the date in to the dd-mm-yyyy format
if(d < 10) d = '0' + d;
if(m < 10) m = '0' + m;
var currentdate = d + '-' + m + '-' + y;
// Check if disableddates array contains the currentdate
return disableddates.indexOf(currentdate) >= 0;
}
And then just pass DisableDates function as the value of your beforeShowDay option:
$("#aankomstdatum").datepicker({
dateFormat: "dd-mm-yy",
numberOfMonths:2,
minDate: 0,
beforeShowDay: DisableDates
});

Related

Rearrange date fromat

Is there a better way to write this code? I'm taking a "date" parameter (which is a string in this case) thats formatted in one of two ways mm/dd/yy' or m/d/yy and I need to reformat it to look like this yyyymmdd
functionName = function(date){
var month = "", day = "", year = "";
if(!date.length) return;
else {
date.slice(0, 2) < 10 ? month = '0' + date.slice(0, 2) : month = date.slice(0, 2);
date.slice(3, 5) < 10 ? day = '0' + date.slice(3, 5) : day = date.slice(3, 5);
year = "20" + date.slice(6, 8);
}
return year + month + day;
}
Also how should I check to see if the date was in the 1900's and format it accordingly?
There is no way to make a full year from a two digit year, it's missing information.
However you could simplify your function using .split() and .padStart()
function FormatDate (date) {
if (date) {
date = date.split('/'); //date[0] = month, date[1] = day, date[2] = year
return date[2] + date[0].padStart(2, '0') + date[1].padStart(2, '0');
}
}
console.log(FormatDate('07/09/20')); //outputs 200709

Expand date range using JS?

I have this variable {{ $daterange }} with json like this
{
"starts_at": "2020-05-20",
"ends_at": "2020-05-23"
},
{
"starts_at": "2020-05-24",
"ends_at": "2020-05-26"
},
{
"starts_at": "2020-05-27",
"ends_at": "2020-05-29"
}
What I want to do is to expand something like this,
2020-05-20
2020-05-21
2020-05-22
2020-05-23
2020-05-24
2020-05-25
2020-05-26
2020-05-27
2020-05-28
2020-05-29
I'm planning to assign these dates inside of expandedDate variable
var expandedDate = [ ....dates ];
This should be done using jquery/js
UPDATE*
Recently this code works and can get all dates between 2 dates. It will list down all dates between 2 date range written in the code.
// Returns an array of dates between the two dates
var getDates = function(startDate, endDate) {
var dates = [],
currentDate = startDate,
addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = addDays.call(currentDate, 1);
}
return dates;
};
// Usage
var dates = getDates(new Date(2013,10,22), new Date(2013,11,25));
dates.forEach(function(date) {
console.log(date);
});
How can I populate {{ $daterange }} contains multiple date range.
Think I missed your update with existing code. The following code seems to get the desired output using javascript. Just added comments to each step as an explanation. Hope it is helpful.
//sample input data
var daterange = [{
"starts_at": "2020-05-27",
"ends_at": "2020-06-23"
},
{
"starts_at": "2020-05-24",
"ends_at": "2020-05-26"
},
{
"starts_at": "2020-05-27",
"ends_at": "2020-05-29"
}
];
// function to get dates between two dates
var getDaysAsArray = function(start_date, end_date) {
for (var arr = [], d = new Date(start_date); d <= end_date; d.setDate(d.getDate() + 1)) {
arr.push(new Date(d));
}
return arr;
};
// function to convert date into the format yyyy-mm-dd
var getFormattedDay = function(date) {
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
month = date.getMonth()+1 < 10 ? "0" + (date.getMonth()+1) : date.getMonth()+1;
year = date.getFullYear();
return year + "-" + month + "-" + day;
}
//main logic
var expandedDate = [];
//Iterate through the list of arrays in the date range
for (var key in daterange) {
//get first pair of from and to date
var from_string = daterange[key].starts_at;
var to_string = daterange[key].ends_at;
// convert the string date to date format for from and to.
var from_date = new Date(from_string.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3"));
var to_date = new Date(to_string.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3"));
// call getDaysAsArray to convert dates into strings and into an array.
var daylist = getDaysAsArray(from_date, to_date);
// iterate through the daylist and push it into the final array you want to use
for (var day in daylist) {
expandedDate.push(getFormattedDay(daylist[day]));
}
}
// final result required
console.log(expandedDate);
Here's the complete code on how to solve this question
Based on #thommu
var daterange = [
{
"starts_at": "2020-05-24",
"ends_at": "2020-05-26"
},
{
"starts_at": "2020-05-27",
"ends_at": "2020-05-29"
}
];
// function to get dates between two dates
var getDaysAsArray = function(start_date, end_date) {
for (var arr = [], d = new Date(start_date); d <= end_date; d.setDate(d.getDate() + 1)) {
arr.push(new Date(d));
}
return arr;
};
// function to convert date into the format yyyy-mm-dd
var getFormattedDay = function(date) {
day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
month = date.getMonth() < 10 ? "0" + date.getMonth() : date.getMonth();
year = date.getFullYear();
return year + "-" + month + "-" + day;
}
//main logic
var expandedDate = [];
//Iterate through the list of arrays in the date range
for (var key in daterange) {
//get first pair of from and to date
var from_string = daterange[key].starts_at;
var to_string = daterange[key].ends_at;
// convert the string date to date format for from and to.
var xfrom_date = new Date(from_string.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3"));
var xto_date = new Date(to_string.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1/$2/$3"));
//Add +1 month to correct the data
var from_date = new Date(xfrom_date.setMonth(xfrom_date.getMonth()+1));
var to_date = new Date(xto_date.setMonth(xto_date.getMonth()+1));
// call getDaysAsArray to convert dates into strings and into an array.
var daylist = getDaysAsArray(from_date, to_date);
// iterate through the daylist and push it into the final array you want to use
for (var day in daylist) {
expandedDate.push(getFormattedDay(daylist[day]));
}
}
//Filter Duplicated Dates
var dateDuplicate = expandedDate;
var uniqueDate = [];
$.each(dateDuplicate, function(i, el){
if($.inArray(el, uniqueDate) === -1) uniqueDate.push(el);
});
// final result required
console.log(uniqueDate);

JavaScript code returning NaN instead of numeric value

When I inputted the code below into jsfiddle it worked exactly as I wanted. However when I implemented it into my project the value returns as NaN.
<script type="text/javascript">
$(function () {
$('#datepicker8').datepicker({
showOnFocus: false,
showTrigger: '#calImg',
beforeShowDay: $.datepicker.noWeekends,
pickerClass: 'noPrevNext',
dateFormat: "dd-mm-yy", changeMonth: true, changeYear: true,
onSelect: function (dateStr) {
var min = $(this).datepicker('getDate');
$('#datepicker9').datepicker('option', 'minDate', min || '0');
datepicked();
}
});
$('#datepicker9').datepicker({
showOnFocus: false,
showTrigger: '#calImg',
beforeShowDay: $.datepicker.noWeekends,
pickerClass: 'noPrevNext',
dateFormat: "dd-mm-yy", changeMonth: true, changeYear: true,
onSelect: function (dateStr) {
var max = $(this).datepicker('getDate');
$('#datepicker8').datepicker('option', 'maxDate', max || '+1Y');
datepicked();
}
});
});
var datepicked = function () {
var from = $('#datepicker8');
var to = $('#datepicker9');
var nights = $('#CalcDate1');
var startDate = from.datepicker('getDate');
startDate.setDate(startDate.getDate() + 1);
var endDate = to.datepicker('getDate')
// Validate input
if (endDate && startDate) {
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0, 0, 0, 1); // Start just after midnight
endDate.setHours(23, 59, 59, 999); // End just before midnight
var diff = endDate - (startDate + 1); // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
var days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
var days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
var days = days - 1
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
var days = days - 1
nights.val(days);
}
}
</script>
I added the code below thinking that it would deal with NaN but it hasn't worked.
if (!isNaN(days)) {
document.getElementById('CalcDate1').value = days;
}
else {
document.getElementById('CalcDate1').value = "";
}
The jsfiddle link is JsFiddle
Its this line here:
var diff = endDate - (startDate + 1);
that is causing the issue. On your fiddle where its working
var diff = endDate - startDate;
This is causing the issue because endDate and startDate are objects and you are trying to concatenate an object with a number

Put date range to array

I have two JQuery datepicker on my page, I want to put all the days between the two dates to an array.
How Can I work it out?
Here is my snippet:
function mennyi() {
var dtFrom = document.getElementById('arrival').value;
var dtTo = document.getElementById('departure').value;
var dt1 = new Date(dtFrom);
var dt2 = new Date(dtTo);
var diff = dt2.getDate() - dt1.getDate();
var days = diff;
alert(dtTo);
document.getElementById("nights").innerHTML = days + " nights"; {
$('#arrival').datepicker({ dateFormat: 'dd-mm-yy' }).val();
$('#departure').datepicker({ dateFormat: 'dd-mm-yy' }).val();
var start = new Date(document.getElementById('arrival').value),
end = new Date(document.getElementById('departure').value),
currentDate = new Date(start),
between = []
;
while (end > currentDate) {
between.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}
$('#lista').html(between.join('<br> '));};
return false;
}
function isNumeric(val) {
var ret = parseInt(val);
};
Now it works, but the thing is how can I change the date format, before I put the string into the array?

disable jQuery DatePicker dates

I have attempted to enable selection of only the first date of each month in a jQuery datepicker. The possible dates are listed in var enabledates.
var enabledDays = ["6-1-2013", "7-1-2013", "8-1-2013",
"9-1-2013", "10-1-2013", "11-1-2013"];
function nationalDays(date) {
var m = date.getMonth(), d = date.getDate(), y = date.getFullYear();
for (i = 0; i < enabledDays.length; i++) {
if($.inArray((m+1) + '-' + d + '-' + y, enabledDays) != -1
|| new Date() > date) {
return [true];
}
}
return [false];
}
$(function(){
$.datepicker.setDefaults($.extend($.datepicker.regional["ru"]));
$("#datepicker1, #datepicker2, #datepicker3").datepicker({
dateFormat: "yy-mm-dd",
duration: "normal",
numberOfMonths: [ 1, 2 ],
constrainInput: true,
beforeShowDay: nationalDays
});
});
How can I apply this first date constraint to the whole calendar?
If you just want to enable a range I would say you can use the Option properties minDate an maxDate.
Regarding your Problem to enable all Dates from an array. Please have a look at this fiddle http://jsfiddle.net/uYe9X/
function available(date) {
var dt= date.getDate() + "-" + (date.getMonth()+1) + "-" + date.getFullYear();
if (availableDates.indexOf(dt) !== -1) {
return [true, "","available"];
} else {
return [false,"","not available"];
}
}
As Pedro mentioned you could use the beforeShowDay Callback to reference a function which computes if the day should be enabled. The callback is used for every day which is displayed in the datepicker.
http://api.jqueryui.com/datepicker/#option-beforeShowDay

Categories