admin管理员组

文章数量:1404073

I have a datepicker input and a timepicker input that I'd like to use to schedule a person for appointments.

When the user clicks on the input to open the datepicker menu, I'd like to grey out specific datetimes. I've got a php function that returns this array of datetimes in in 'Y-m-d H:i:s' string format. But I dont' know how to use that function's return value to give the javascript function what it needs to disable a range of dates in datepicker.

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

  1. Datepicker uses beforeshowDay: to disable booked dates

  2. user selects date from datepicker

  3. Datepicker enables/disables times in the timepicker

I did find out how to disable timeranges in the timepicker Here. the code example is this:

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

But that's how I'd disable the time ranges from 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 the function that gives the datetimes, in case 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 appropriately. However, I don't know how to use the datetimes that I pulled in code below to disable/enable times in the timepicker.

Here is 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                
        });

    });

I have a datepicker input and a timepicker input that I'd like to use to schedule a person for appointments.

When the user clicks on the input to open the datepicker menu, I'd like to grey out specific datetimes. I've got a php function that returns this array of datetimes in in 'Y-m-d H:i:s' string format. But I dont' know how to use that function's return value to give the javascript function what it needs to disable a range of dates in datepicker.

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

  1. Datepicker uses beforeshowDay: to disable booked dates

  2. user selects date from datepicker

  3. Datepicker enables/disables times in the timepicker

I did find out how to disable timeranges in the timepicker Here. the code example is this:

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

But that's how I'd disable the time ranges from 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 the function that gives the datetimes, in case 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 appropriately. However, I don't know how to use the datetimes that I pulled in code below to disable/enable times in the timepicker.

Here is 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                
        });

    });
Share Improve this question edited Jul 15, 2017 at 0:02 ArmorCode asked Jul 5, 2017 at 22:56 ArmorCodeArmorCode 7494 gold badges15 silver badges34 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4 +50

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./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" />

Someone already answered this question here.

Anyway, the following code should give you an insight on 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've assumed that you're exchanging data with the server using some kind of API, hence the use of getJSON, if you want to handle server errors then I suggest you to use ajax bining with Promise.

Edit 1

You can extract everything from your date using the class DateTime, 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 timepicker based on date, you'll probably need to register a callback function in your datepicker to update the timepicker based on the chosen date or you'll have to override the timepicker with new settings.

Yes, you can dinamically update timepicker disableTimeRanges inside the onSelect function using the option method of the timepicker ponent.

I'm supposing that:

  • You are using jQuery UI datepicker (since you didn't tag your question with twitter-bootstrap and bootstrap-datepicker has no minDate option)
  • You are using the first version of get_next_open_appointments that returns an array of datetimes (like ['2017-07-25 09:30:00', ...] see fakeDisabledTimes in the snippet)

I'm using momentjs in order to simplify dates managment. In the following code, I've used moment parsing functions (moment(String) and moment(String, String)), isSame, add and format. Note that moment tokens are different from PHP tokens.

Here a plete 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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/jquery-timepicker/1.10.0/jquery.timepicker.js"></script>

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

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

本文标签: