0

I am using two jQuery date pickers so that a user can book something, upon both date pickers being selected a button called request is displayed. Does anybody know how I could prevent someone trying to make a booking through disabled days by not showing the request button and instead showing an error message? i.e if from 13th March is selected then the request button is not shown whenever the to date is 15th march as 14th March is disabled.

Hope that makes sense.

enter image description here

The disabled days are being called from my database and being stored in a JavaScript variable called bookedDays.

The JavaScript code I am using is below:

$(document).ready(function() {

    $('#request').hide();
    $('.days').html('Please select a date range of at least the same day. <br/> <i>Max booking: 2 Months.</i>');
    $( "#from" ).datepicker({
      defaultDate: new Date(),
      changeMonth: true,
      numberOfMonths: 1,
      minDate: new Date(),
      maxDate: "+1M",
      beforeShowDay: isAvailable,
      onClose: function( selectedDate ) {
        var day = $("#from").datepicker('getDate');
day.setDate(day.getDate()+1);
        $( "#to" ).datepicker( "option", "minDate", day );

      }
    });

    $( "#to" ).datepicker({

      defaultDate: new Date(),
      changeMonth: true,
      numberOfMonths: 1,
      minDate: ("#to"),
      maxDate: ("+2M"),
      beforeShowDay: isAvailable,
      onClose: function( selectedDate ) {
        $( "#from" ).datepicker( "option", "maxDate", selectedDate );
      }
    });

    function isAvailable(date){
    var dateAsString = date.getFullYear().toString() + "-" + (date.getMonth()+1).toString() + "-" + date.getDate();
    var result = $.inArray( dateAsString, bookedDays ) ===-1 ? [true] : [false];
    return result;
  }


    $('#to').on('change',function(){
     var days = (daydiff(parseDate($('#from').val()), parseDate($('#to').val())));
      var cogs = $('#cogsday').html();
      cogs = cogs.replace(/\D/g,'');
      var x = days;
      var y = cogs * x;
      $('.days').html('You have chosen to borrow this item for <b>'+ days + '</b> days at a cost of <b>' + y + '</b> cogs.<br/><br/>');
        if(days){
            if (borrowercogs >= (y)) {
        $('#request').show();
      } else {
           $('#request').hide();
           $('.days').html('You have chosen to borrow this item for <b>'+ days + '</b> days at a cost of <b>' + y + '</b> cogs.<br/><i style=color:red>You do not have enough cogs to borrow for this duration.</i><br/>');
      }
        }

      $('#request').click(function() {

                var cogs = $('#cogsday').html();

                cogs = cogs.replace(/\D/g,'');

        var x = days ;

        var y = cogs * x;
        $('#total').text(y);
        $('#nameID').val(y);
        $('#days').text(days);
        $('#daysID').val(days);

        });
    })

    function parseDate(str) {
    var mdy = str.split('/')
    return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function daydiff(first, second) {
    return Math.round((second-first)/(1000*60*60*24));
}

  });

Any help would be appreciated. Thanks

user2244961
  • 151
  • 1
  • 3
  • 12
  • http://stackoverflow.com/questions/15400775/jquery-ui-datepicker-disable-array-of-dates – Mike Mar 05 '15 at 14:50
  • @Mike - Isn't that just disabling the dates though? I already have them disabling ok but I want to prevent booking from before a disabled date to after a disabled date – user2244961 Mar 05 '15 at 14:56
  • flip the boolean, from == -1 to !=-1 – Mike Mar 05 '15 at 15:01
  • Ah, I think I misunderstood your original question... I think I get it now, you can do this kind of validation after the user has selected dates, but you cannot do it with any native form control method for the jQuery datepicker, it does not have this functionality (disallowing ranges of dates that include disabled dates.) Although, it's quite simple if you just loop through the range of dates and check to see if any of those dates are disabled. – Mike Mar 05 '15 at 15:09
  • Yeah sorry for not making it more clear but its hard to explain. Do you have any idea how to loop through the range of dates to see if any are disabled or know of anywhere I could get help with this? :) – user2244961 Mar 05 '15 at 15:13
  • 1
    Check my answer again, I've improved it, this time it should be pretty clear what you need to do with your code :) – Mike Mar 05 '15 at 15:46

1 Answers1

1

UPDATED

JSFIDDLE

var array = ["2015-03-14","2015-03-15","2015-03-16"]

var _selectedDay = "";
var _cascadeDisabled = false;

$('#from').datepicker({
    beforeShowDay: function(date) {
        var _date = jQuery.datepicker.formatDate('yy-mm-dd', date);
        var _isDisabledDate = array.indexOf(_date) != -1;      

        return [ array.indexOf(_date) == -1 ]
    },
    onClose: function(dateStr, event) {
        _selectedDay = dateStr;
    }
});

$('#to').datepicker({
    beforeShowDay: function(date) {
        var _date = jQuery.datepicker.formatDate('yy-mm-dd', date);
        var _isDisabledDate = array.indexOf(_date) != -1;
        if(_selectedDay.length && _isDisabledDate 
          && _selectedDay < _date) {
            _cascadeDisabled = true;
        }

        if(_cascadeDisabled) return false;

        return [ array.indexOf(_date) == -1 ]
    },
    onClose: function(dateStr, event) {
        _cascadeDisabled = false;
    }
});


$("#clear").click(function() {
    $("input[type='text']").val("");
});

As you can see, what we're doing here is setting a global variable with the "FROM" datepicker, and then in the "TO" datepicker, we loop through until we hit a disabled date, from then on forward we set the global variable "cascade" to cascade all the future dates to be disabled, effectively making it impossible to book a range of dates that includes a disabled date.

Mike
  • 874
  • 1
  • 8
  • 15
  • I'm not too sure how to go about adding this to my code as my beforeShowDay is already calling the isAvailable function? – user2244961 Mar 05 '15 at 15:11
  • Ignore this, I'm rewriting the proper answer now. but to put it basically, you're going to cascade the disabled dates as you loop/iterate through them – Mike Mar 05 '15 at 15:14
  • No problem. I looked there and now understand the need to loop through the array but just not sure how to do it with the code I already have – user2244961 Mar 05 '15 at 15:33
  • 1
    Check my answer now/the JSFiddle, it doesn't have your to/from setup, but you can port my code into yours, you just need to set your "from date" from the "from datepicker" and then use my code on your "to datepicker" – Mike Mar 05 '15 at 15:37
  • It's looking good, thanks very much for your time on this. On my original code the variable bookedDays contained all the disabled dates (set in php file) rather than hard coding them in like the above example. I have tried var array = bookedDays. Do you know how I could fix that? – user2244961 Mar 05 '15 at 16:03
  • You should be able to assign the dates into the array, I'm not sure what your "bookedDays" array/object looks like, could you post a JSFiddle with a mockup of the structure of this variable? – Mike Mar 05 '15 at 16:08
  • As the data is being read from my database it is difficult to replicate but i have put the code in to the following fiddle https://jsfiddle.net/4nvsLkL4/ – user2244961 Mar 05 '15 at 16:12