1

When a user selects a date by clicking on the calendar, is it possible to find the next/closest disabled future date.

From what I've seen disabled dates do not output a date in the markup, they only output the day (I need the year,month,day), so looking for the next 'ui-state-disabled' element wont work.

j08691
  • 190,436
  • 28
  • 232
  • 252
kb.
  • 886
  • 3
  • 14
  • 33
  • 2
    surely it must only be disabled barbecue you disabled it? in which case you already know – andrew Mar 23 '14 at 19:51
  • yes that's true I did disable it, but it bears no relation to the selected date the user clicks. when the user selects a date I need to look ahead on the calendar & find the next disabled date – kb – kb. Mar 24 '14 at 16:39
  • I do not understand the point. You probably use an array to store disabled dates and your `beforeShowDay` function looks uses `$.inArray`, so why not loop over the same array? – Salman A Apr 01 '14 at 08:27
  • Try to approach the problem from the other side. Don't analyze the DOM elements of datepicker - but work with data. Is that your function defined the disabled dates? If so (I hope it is) - use the same logic/data to find the next disabled date. – jslayer Apr 02 '14 at 10:17

3 Answers3

2

AFIK, there is no official resource for finding out the disabled dates in jQuery Datepicker.

However jQuery UI Datepicker is a library upon Javascript, there is always a workaround. Below is a workaround I have tried.

Step #1:

Below is a way to disable a list of dates in jQuery Datepicker.

var array = ["2014-03-14", "2014-03-18", "2014-03-16", "2014-04-01"]

$('input').datepicker({
    dateFormat: 'yy-mm-dd',
    beforeShowDay: function (date) {
        var string = jQuery.datepicker.formatDate('yy-mm-dd', date);
        return [array.indexOf(string) == -1]
    },
    onSelect: function (date) {
            console.log(findNextDisabledDateWithinMonth(date));
    }
});

Now here my approach to get the next disabled date within the month.

Step #2:

function findNextDisabledDateWithinMonth(date) {
    var currentDate = Number(date.split('-')[2]);
    var month = $('.ui-datepicker-title>.ui-datepicker-month').text(); //Number(date.split('-')[1])
    var year = $('.ui-datepicker-title>.ui-datepicker-year').text();  //Number(date.split('-')[0])
    var nextConsectiveDates = [];
    $.each($('.ui-state-disabled').find('.ui-state-default'), function (i, value) {
        var numericDate = +$(value).text();
        if (currentDate < numericDate) {
            nextConsectiveDates.push(numericDate);
        }
    });
    var nextDisabledDate = nextConsectiveDates[0] + "-" + month + "-" + year;
    return nextDisabledDate;
}

JSFiddle

NOTE: This is work only for the selected date's month


Approach #2

As @ Salman A mentioned in his comment, I feel the best way is to go with it. Since my approach will is constrained within month.

Here is an elegant approach to solve your problem.

var array = ["2014-05-01", "2014-04-14", "2014-04-18", "2014-04-16"];
// Convert all those string dates into Date array
var arrayAsDateObjects = convertStringToDateObject(array);

$('input').datepicker({
    dateFormat: 'yy-mm-dd',
    beforeShowDay: function (date) {
        var string = jQuery.datepicker.formatDate('yy-mm-dd', date);
        return [array.indexOf(string) == -1]
    },
    onSelect: function (date) {
        alert(findNextDisabledDateWithinMonth(date).toDateString());
    }
});

//To find the next exact disabled date based on the selected date
function findNextDisabledDateWithinMonth(date) {
    var splitDate = date.split("-");
    var selectedDate = new Date(splitDate[0], Number(splitDate[1]) - 1, splitDate[2]);
    var nextDisabledDate = null;
    $.each(arrayAsDateObjects, function (i, ele) {
        if (selectedDate < ele) {
            nextDisabledDate = ele;
            return false;
        } else {
            nextDisabledDate = "No Disabled dates available";
        }
    });
    return nextDisabledDate;
}

//convert all the string dates to Date object
function convertStringToDateObject(array) {
    var ls = [];
    $.each(array, function (i, ele) {
        var splitDate = ele.split("-");
        var date = new Date(splitDate[0], Number(splitDate[1]) - 1, splitDate[2]);
        ls.push(date);
    });
    // Sort the dates in ascending order(https://stackoverflow.com/a/10124053/1671639)
    ls.sort(function (a, b) {
        return a - b;
    });
    return ls;
}

JSFiddle

for sorting dates, I took reference from @Phrogz 's answer

Community
  • 1
  • 1
Praveen
  • 50,562
  • 29
  • 125
  • 152
0

I hoped that the datepicker would have had a function built in for this, but looks like it doesn't. So I had to just look through my list of disabled dates & determine the answer from the list, which is what I was trying to avoid, as the list is huge.

kb.
  • 886
  • 3
  • 14
  • 33
  • We can set minDate & maxDate parameters in Datepicker.Chek out this, http://stackoverflow.com/questions/22006328/disable-future-dates-after-today-in-jquery-ui-datepicker – AK47 Apr 02 '14 at 10:00
  • What it represents your list? Is this 1-dimensional array of values ? – jslayer Apr 02 '14 at 10:35
0

Here's a day from the date picker on my website.

<td class=" " 
  onclick="DP_jQuery_139.datepicker._selectDay('#Dob',2,2014, this);return false;">
     <a class="ui-state-default" href="#">21</a>
</td>

Could you parse the on click for the parent td? Or does disabling a date also remove the parent on click event? Anyway here something that might point you in the right direction. Untested, you can fiddle with it. It's late and I need to get some rest.

$('.ui-datepicker-calendar a.ui-state-default').click(function() {
   var clickhandler = $(this).closest('td').next('td:has(a.ui-state-disabled)').attr('onclick');
   var monthYear = clickhandler.replace(/^.*,?/,'').replace(/, this.*/,'').split(',');
   // do something with your monthYear array here
});
B2K
  • 2,423
  • 1
  • 19
  • 30