Use php array to disable dates in datepicker and times in timepicker from onSelect in DatePicker

I have a datepicker input and a time input that I would like to use to assign a person for appointments.

When the user clicks on enter to open the datepicker menu, I would like to gray out specific dates. I have a php function that returns this datetimes array in the format of the string "Ymd H: i: s". But I don't know how to use this function return value to give the javascript function what it needs to disable the date range in the datepicker.

In the onSelect event of my datepicker, I want it to enable / disable the time options in my timepicker, according to which timeslots are booked for that day. But I dont know how.

  • Datepicker uses beforeshowDay: to disable booked dates

  • user selects date from datepicker

  • Datepicker enables / disables time in timepicker

I figured out how to disable timers in the timepicker Here . example code:

$('input.timepicker').timepicker({
    'disableTimeRanges': [
        ['1am', '2am'],
        ['3am', '4:01am']
    ]
});

      

But this is how I will disable the time ranges within the scope of the timepicker. I don't know how to disable them from BeforeShowDay in datepicker?

<script type="text/javascript">   
    $(document).ready(function(){
        $( "#datepickerListAppointments" ).datepicker(
        {
            minDate:'0',
            beforeShowDay:
            function(dt)
            {   // need to disable days other than tuesday and wednesday too.
                return [dt.getDay() === 2 || dt.getDay() === 3, ""];
            },
            onSelect : function(){
                should disable/enable timepicker times from here?
            }
        });

        $('input.timepicker').timepicker({
            timeFormat: 'h:mm p',
            interval: 90,
            minTime: '9',
            maxTime: '10:30am',
            defaultTime: '9',
            startTime: '9:00',
            dynamic: false,
            dropdown: true,
            scrollbar: false                
        });

    });

      

This is a function that gives data if it helps to know.

function get_next_open_appointments($numAppointments, $timeSlotToExclude = "")
{
    global $db;
    $whereCondition = "WHERE FirstName = :null ";
    if ($timeSlotToExclude != "")
    {
        $whereCondition .= "AND AppointmentTime != '$timeSlotToExclude' ";
    }

    $query = "SELECT DISTINCT AppointmentTime FROM appointments
              $whereCondition
              ORDER BY AppointmentTime ASC LIMIT $numAppointments";
    $statement = $db->prepare($query);
    $statement->bindValue(':null', "");
    $statement->execute();
    $datesArray = array();
    while ($row = $statement->fetch()) 
    {
        array_push($datesArray, $row['AppointmentTime']);
    }
    $statement->closeCursor();
    return $datesArray;
}

      

UPDATE:

Hugo de Carmo pointed me in the right direction and I got the dates to disable / enable accordingly. However, I don't know how to use the dates I pulled out in the code below to disable / enable the time in the timepicker.

Here's the new code:

<script type="text/javascript">   
    $(document).ready(function(){

        // uses php to get open appointments, and put them in a javascript array
        <?php $datetime_openings = get_next_open_appointments(200);
        $date_openings = array();
        foreach ($datetime_openings as $dt)
        {
            array_push($date_openings, substr($dt,0,10)); // just the date part
        }

        $json_date_openings = json_encode($date_openings);
        echo "var arr_Openings = ". $json_date_openings . ";\n";
        ?>

        $( "#datepickerOpenAppointments" ).datepicker(
        {
            minDate:'0',
            beforeShowDay:
            function(dt)
            {
                var string = jQuery.datepicker.formatDate('yy-mm-dd', dt);
                var bFound = (arr_Openings.indexOf(string) != -1);
                return [ bFound ]; 
            },
            onSelect : function(){
               //    Should disable/enable time ranges here?
        });

        $('input.timepicker').timepicker({
            timeFormat: 'h:mm p',
            interval: 90,
            minTime: '9',
            maxTime: '10:30am',
            defaultTime: '9',
            startTime: '9:00',
            dynamic: false,
            dropdown: true,
            scrollbar: false                
        });

    });

      

+3


source to share


3 answers


Try this,
sorry i didn't use beforeshowDay
select date 2017-7-14 and 2017-7-17 and see



var disabledDateTime = {
  '2017-7-14':[
  	['2:30am','3:00am'],
    ['6:30am','9:00am']
  ],
	'2017-7-17':[
  	['1:00am','3:00am'],
    ['5:30am','7:00am'],
    ['11:30am','2:00pm']
  ]
};

$(function() {
  $('#pickTime').timepicker();
  $('#pickDate').datepicker({
    'format': 'yyyy-m-d',
    'autoclose': true
  }).on('changeDate',function(e){
    var ts = new Date(e.date);
    var m = ts.getMonth()+1;
    var dt = ts.getFullYear() + '-' + m + '-' + ts.getDate();
    var opt = {'disableTimeRanges': []}
    if(typeof(disabledDateTime[dt])!='undefined'){
      $('#pickTime').timepicker('setTime', '');
      opt = {'disableTimeRanges': disabledDateTime[dt]}
    }
    $('#pickTime').timepicker('option',opt);
  });
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<link href="https://jonthornton.github.io/jquery-timepicker/lib/bootstrap-datepicker.css" rel="stylesheet"/>
<script src="https://jonthornton.github.io/jquery-timepicker/lib/bootstrap-datepicker.js"></script>
<link href="https://jonthornton.github.io/jquery-timepicker/jquery.timepicker.css" rel="stylesheet"/>
<script src="https://jonthornton.github.io/jquery-timepicker/jquery.timepicker.js"></script>

<input id="pickDate" type="text" class="date" />
<input id="pickTime" type="text" class="time" />
      

Run codeHide result


+4


source


Someone has already answered this question here .

Either way, the following code should give you an idea of ​​how to solve the problem.

// supose your script return a json similar to the following
{
    "data": [
        // ...
        "17-07-11"
    ]
}

$(function() {
  $.getJSON("/path/to/script", function(response){
    $('#datepickerListAppointments').datepicker({
      beforeShowDay: function(dt) {
        var config = [];
        config[1] = 'class';

        if ((dt.getDay() === 2) || (dt.getDay() === 3)) {
          config[0] = false;
          return config;
        }

        var string = jQuery.datepicker.formatDate('yy-mm-dd', dt);
        config[0] = (response.data.indexOf(string) === -1);
        return config;
      }
    });
  });
});

      

I assumed you are communicating with the server using some kind of API, so use getJSON if you want to handle server errors, I suggest you use ajax concatenating Promise .



Edit 1

You can extract everything from your date using the DateTime class , here is a snippet:

$openings = array();

$date = DateTime::createFromFormat("y/m/d H:i", "17/07/15 08:30");

if (!isset($openings[$date->format("y-m-d")])) {
    $openings[$date->format("y-m-d")] = array();
}

$openings[$date->format("y-m-d")][] = array(
    "hour" => $date->format("Ha"),
    "minute" => $date->format("i")
);

/* result
array(1) {
  ["17-07-15"]=>
  array(1) {
    [0]=>
    array(2) {
      ["hour"]=>
      string(4) "08am"
      ["minute"]=>
      string(2) "30"
    }
  }
}
*/

      

Then you can disable the time in the timepicker based on the date, you will probably need to register a callback function in your datepix to update the timepicker based on the selected date, or you will have to override the timepicker with new settings.

+3


source


Yes, you can dynamically update the timepicker disableTimeRanges

inside a function onSelect

using the option

component's timepicker method .

I suppose that:

  • You are using jQuery UI datepicker (since you haven't tagged your question with twitter-bootstrap

    and bootstrap-datepicker

    hasn't minDate

    )
  • You are using the first version get_next_open_appointments

    which returns an array of datetimes ( ['2017-07-25 09:30:00', ...]

    see for example fakeDisabledTimes

    in the snippet)

I am using momentjs to make managing dates easier. In the following code, I use the moment parsing functions ( moment(String)

and moment(String, String)

) isSame

, add

and format

. Note that tokens are different from PHP tokens.

Here's a complete working sample:

var fakeDisabledTimes = [
  '2017-07-25 09:30:00', '2017-07-26 10:00:00',
  '2017-08-01 09:00:00', '2017-08-02 09:30:00',
  '2017-08-08 10:30:00', '2017-08-09 10:00:00',
  '2017-07-15 09:30:00', '2017-07-16 10:00:00'
];

$(document).ready(function(){
  $( "#datepickerListAppointments" ).datepicker({
    minDate:'0',
    beforeShowDay:
    function(dt){
      // need to disable days other than tuesday and wednesday too.
      return [dt.getDay() === 2 || dt.getDay() === 3, ""];
    },
    onSelect : function(dateText){
      //should disable/enable timepicker times from here!
      // parse selected date into moment object
      var selDate = moment(dateText, 'MM/DD/YYYY');
      // init array of disabled times
      var disabledTimes = [];
      // for each appoinment returned by the server
      for(var i=0; i<fakeDisabledTimes.length; i++){
        // parse appoinment datetime into moment object
        var m = moment(fakeDisabledTimes[i]);
        // check if appointment is in the selected day
        if( selDate.isSame(m, 'day') ){
          // create a 30 minutes range of disabled time
          var entry = [
            m.format('h:mm a'),
            m.clone().add(30, 'm').format('h:mm a')
          ];
          // add the range to disabled times array
          disabledTimes.push(entry);
        }
      }
      // dinamically update disableTimeRanges option
      $('input.timepicker').timepicker('option', 'disableTimeRanges', disabledTimes);
    }
  });

  $('input.timepicker').timepicker({
    timeFormat: 'h:i a',
    interval: 90,
    minTime: '9',
    maxTime: '10:30am',
    defaultTime: '9',
    startTime: '9:00',
    dynamic: false,
    dropdown: true,
    scrollbar: false                
  });

});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.10.0/jquery.timepicker.js"></script>

<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.10.0/jquery.timepicker.css" rel="stylesheet"/>

<input id="datepickerListAppointments" type="text">
<input class="timepicker" type="text">
      

Run codeHide result


+1


source







All Articles