使用Ajax调用将数组传递给Javascript代码

I am using a datepicker and I want to query a MySQL database when it is clicked to make certain dates unavailable. How to I pass this array into my JavaScript code where it says "AJAX CALL CODE NEEDS TO GO HERE"?

Here is my code for the Javascript date picker

$(function() {

  $('input[name="start_date"]').daterangepicker({
      autoUpdateInput: false,
      locale: {
          cancelLabel: 'Clear'
      },
      isInvalidDate: function(date) {
      var dateRanges = [
AJAX CALL CODE NEEDS TO GO HERE
            ];
            return dateRanges.reduce(function(bool, range) {
                return bool || (date >= range.start && date <= range.end);
            }, false);
        }
  });

  $('input[name="start_date"]').on('apply.daterangepicker', function(ev, picker) {
      document.getElementById("start_date").value = picker.startDate.format('MM/DD/YYYY');
      document.getElementById("end_date").value = picker.endDate.format('MM/DD/YYYY');

  });

  $('input[name="datefilter"]').on('cancel.daterangepicker', function(ev, picker) {
      $(this).val('');
  });

});

Here is the code that needs to be inserted into that code in the PHP file for the ajax call:

<?php
include 'dbconfig.php';

$sql="SELECT start_date, end_date FROM date_ranges ";
$result = mysqli_query($conn,$sql);

while($row = mysqli_fetch_array($result)) {

echo  "{ 'start': moment('" . $row['start_date'] . "'), 'end': moment('" . $row['end_date'] . "') },";
mysqli_close($conn);
} 
?>

edit: new code with the help of Emiel Zuurbier

$(function() {

var dateRanges = null;

$.ajax({
    url: 'getdaterangepicker.php', 
    method: 'GET',
    dataType: 'json',
    success: function(response) {  
        if (response) {            
            dateRanges = $.parseJSON(response); 
        }
    }
});

  $('input[name="start_date"]').daterangepicker({
      autoUpdateInput: false,
      locale: {
          cancelLabel: 'Clear'
      },
      isInvalidDate: function(date) {
            return dateRanges.reduce(function(bool, range) {
                return bool || (date >= range.start && date <= range.end);
            }, false);
        }
  });

  $('input[name="start_date"]').on('apply.daterangepicker', function(ev, picker) {
      document.getElementById("start_date").value = picker.startDate.format('MM/DD/YYYY');
      document.getElementById("end_date").value = picker.endDate.format('MM/DD/YYYY');

  });

  $('input[name="datefilter"]').on('cancel.daterangepicker', function(ev, picker) {
      $(this).val('');
  });

});

Returns error "TypeError: null is not an object (evaluating 'dateRanges.reduce')"

Since you are using jQuery we'll use the $.ajax function of jQuery.

In your PHP file change the contents of the while loop to the code below. It will create an associative array to store the start and end value in, without moment because that is JavaScript, and send the array as JSON. Because it is an associative array it will be turned into an object which we can use in JavaScript.

// Create empty array.
$date_ranges = array();

// Add every row to array;
while($row = mysqli_fetch_array($result)) {

    // Create an associative array to store the values in.
    // This will later be a JavaScript Object.
    array_push($date_ranges, array(
        'start'   => $row['start_date'],
        'end'     => $row['end_date']
    ));

    mysqli_close($conn);

} 

// Send the $date_ranges as JSON.
$json = json_encode($date_ranges); // '[{"start": "2019-08-18", "end": "2019-08-19"}]'
echo $json;

In the JavaScript prepare for storing the dateRanges. Create a variable before your AJAX call which will hold the result.

Now you can make your AJAX request. This has to be sent to the PHP file in which you defined your logic for getting the result. We want to get something from the server, so use the GET method. Instruct the AJAX request to expect JSON and handle it accordingly. Set the dataType to 'json'.

When the request is send do something with your response. This can be done by setting the success property to a function. This function will receive the response and opens it up for us to use. Decode the response from JSON to JavaScript and voila, you have your result.

Edit: Put the AJAX call inside a wrapper function. This way you can use this function multiple times when you deem necessary. Also it creates a way to fire a callback function from which we can access our data.

// AJAX request wrapper function.
// Call this function to get the dates from the server.
function getDateRanges(callback) {
    $.ajax({
        url: '/yourphpfile.php',       // Change this to the uri of your file
        method: 'GET',                 // Use the GET method
        dataType: 'json',              // Expect a JSON response
        success: function(response) {  // What will happen when the request succeeds
            if (response) {            // Check if there is a response
                callback(response);    // Pass the response into the callback
            }
        },
        error: function(jqXHR, textStatus, errorThrown) {
            console.log(textStatus + ': ' + errorThrown);
        }
    });
}

So now you can call the server any time you like.

You need your dates before you call the daterangepicker function. Before the edit the code would call the AJAX function, but before any value was returned, because it can take a second, the daterangepicker was already called and used the null value before it had any time to update that null value.

This is because of the A in AJAX, which stands for Asynchronous. That means that when the $.ajax function is fired it does not wait for it to complete, but goes on executing the rest of the script. Whenever the $.ajax function gives a response the success function is triggered. But we weren't waiting for it to finish. So we'll adjust that.

Put the code where you set the datepicker into the callback of the now created getDateRanges function. This causes the daterangepicker to wait until the AJAX call is finished and has a value.

See code below:

// Get the dates from the server.
// Fire the callback function when the AJAX call has returned a value.
// And use it as the dates variable.
getDateRanges(function(dates) {

    $('input[name="start_date"]').daterangepicker({
        autoUpdateInput: false,
        locale: {
            cancelLabel: 'Clear'
        },
        isInvalidDate: function(date) {
            // Here use your dates that you've got from the server.
            var dateRanges = dates;
            return dateRanges.reduce(function(bool, range) {
                return bool || (date >= moment(range.start) && date <= moment(range.end));
            }, false);
        }
    });

    $('input[name="start_date"]').on('apply.daterangepicker', function(ev, picker) {
        document.getElementById("start_date").value = picker.startDate.format('MM/DD/YYYY');
        document.getElementById("end_date").value = picker.endDate.format('MM/DD/YYYY');
    });

    $('input[name="datefilter"]').on('cancel.daterangepicker', function(ev, picker) {
        $(this).val('');
    });

});

More on how to use the ajax function of jQuery, check out these docs.

Now the start and end values are still strings. I did see you were using moment in your PHP, but since we removed that from the PHP you'll have to call them in your JS.
You could do that in your reduce function:

return bool || (date >= moment(range.start) && date <= moment(range.end));

I hope this is of any help!