Search code examples
jquerydatepickerflatpickr

Flatpickr - Limit the amount of dates that can be selected


I am using 'flatpickr' as a datetime picker on my app. This date picker allows for multiple dates to be selected but after reading the docs I can't find any way to limit the maximum amount of selected dates.

Jquery:

$('#gig_date_multi').flatpickr({
  "mode": "multiple",
  "locale": "<%= I18n.locale %>",
  minDate: new Date(),
  enableTime: true,
  time_24hr: true,
  minuteIncrement: 15,

    onChange: function(selectedDates, dateStr, instance) {

      var array = selectedDates;
      if (array.length >= 3) {
        console.log("YOU HAVE REACHED YOUR LIMIT")
      } else {
        console.log("YOU CAN STILL SELECT MORE DATES")
      }

      var newHTML = [];
      $.each(array, function(index, value) {
        var formatted = moment(value).format("HH:mm - dddd Do MMMM YYYY");
        newHTML.push('<span>' + formatted + '</span>');
      });

      $(".multi-dates").html(newHTML.join(""));

    }
});

Here when 3 dates are selected the console outputs "YOU HAVE REACHED YOUR LIMIT" and I was thinking maybe I could disable all dates (apart from previously selected ones) when this occurs.

Flatpickr has a disable and enable function but I am unsure how I can integrate this into the code... I am a jquery beginner.

The docs show these two methods;

{
    "disable": [
        function(date) {
            // return true to disable
            return (date.getDay() === 5 || date.getDay() === 6);

        }
    ],
    "locale": {
        "firstDayOfWeek": 1 // start week on Monday
    }
}

and

{
    enable: ["2017-03-30", "2017-05-21", "2017-06-08", new Date(2017, 8, 9) ]
}

Solution

  • You can use:

    set(option, value): Sets a config option optionto value, redrawing the calendar and updating the current view, if necessary

    In order to disable all dates except the 3 selected you can write:

    instance.set('enable', selectedDates);
    

    and, in order to reset you can:

    instance.set('enable', []);
    

    A different approach can be based on Enabling dates by a function:

    instance.set('enable', [function(date) {
        if (selectedDates.length >= 3) {
            var currDateStr = FlatpickrInstance.prototype.formatDate(date, "d/m/Y")
            var x = selectedDatesStr.indexOf(currDateStr);
            return x != -1;
        } else {
            return true;
        }
    }]);
    

    The snippet:

    $('#gig_date_multi').flatpickr({
        "mode": "multiple",
        "locale": 'en',
        minDate: new Date(),
        enableTime: true,
        time_24hr: true,
        minuteIncrement: 15,
        onChange: function(selectedDates, dateStr, instance) {
            var selectedDatesStr = selectedDates.reduce(function(acc, ele) {
                var str = instance.formatDate(ele, "d/m/Y");
                acc = (acc == '') ? str : acc + ';' + str;
                return acc;
            }, '');
            instance.set('enable', [function(date) {
                if (selectedDates.length >= 3) {
                    var currDateStr = instance.formatDate(date, "d/m/Y")
                    var x = selectedDatesStr.indexOf(currDateStr);
                    return x != -1;
                } else {
                    return true;
                }
            }]);
        }
    });
    input[type="text"] {
        width: 100%;
        box-sizing: border-box;
        -webkit-box-sizing:border-box;
        -moz-box-sizing: border-box;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/flatpickr/dist/flatpickr.min.css">
    <script src="https://unpkg.com/flatpickr"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
    
    
    <input type="text" id="gig_date_multi">