Как использовать плагин easypick для выбора диапазона дат?

Я использую плагин Javascript easypick для создания средства выбора диапазона дат для бронирования определенного номера в отеле. Это выглядит так:

<script src = "https://cdn.jsdelivr.net/npm/@easepick/[email protected]/dist/index.umd.min.js"></script>
<input id = "datepicker"/>
<script>
  const DateTime = easepick.DateTime;
  const bookedDates = [
      ['2023-04-19', '2023-04-21'],
      ['2023-04-28', '2023-04-29'],
      ['2023-04-29', '2023-04-30']
  ].map(d => {
      if (d instanceof Array) {
        const start = new DateTime(d[0], 'YYYY-MM-DD');
        const end = new DateTime(d[1], 'YYYY-MM-DD');

        return [start, end];
      }

      return new DateTime(d, 'YYYY-MM-DD');
  });
  const picker = new easepick.create({
    element: document.getElementById('datepicker'),
    css: [
      'https://cdn.jsdelivr.net/npm/@easepick/[email protected]/dist/index.css',
      'https://easepick.com/css/demo_hotelcal.css',
    ],
    plugins: ['RangePlugin', 'LockPlugin'],
    RangePlugin: {
      tooltipNumber(num) {
        return num - 1;
      },
      locale: {
        one: 'night',
        other: 'nights',
      },
    },
    LockPlugin: {
      minDate: new Date(),
      minDays: 2,
      inseparable: true,
      filter(date, picked) {
        if (picked.length === 0) {
          return date.inArray(bookedDates, '[)');
        } else {
          const incl = date.isBefore(picked[0]) ? '[)' : '(]';
          return !picked[0].isSame(date, 'day') && date.inArray(bookedDates, incl);
        }
      },
    },
    autoApply: false
  });
</script>

Код делает почти то, что должен делать. Если вы выберете 2023-04-18 или любой день раньше в качестве даты начала, станет возможным выбрать 2023-04-19 в качестве даты окончания. Это имеет смысл, потому что, хотя не должно быть возможности выбрать зарезервированную кем-то еще дату заезда, должна быть возможность выбрать ее в качестве даты выезда.

Моя проблема с последующими датами. 2023-04-21 отображается как зарезервированное, и все более поздние интервалы дат также сдвигаются на 1 день вперед. Это только косметическая проблема, потому что все, что позже 2023-04-19, в любом случае невозможно выбрать. Но выглядит запутанно. Итак, как мне применить фильтр только к первой зарезервированной дате, которая идет после моего первого выбора? В данном случае это будет означать изменение состояния только 2023-04-19.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
190
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В этой конфигурации: после выбора даты начала он отключит и затенит оставшиеся дни после первого дня ближайшего, уже существующего бронирования.

const DateTime = easepick.DateTime;
const bookedDates = [
  ['2023-04-19', '2023-04-21'],
  ['2023-04-28', '2023-04-29'],
  ['2023-04-29', '2023-04-30']
].map(d => {
  if (d instanceof Array) {
    const start = new DateTime(d[0], 'YYYY-MM-DD');
    const end = new DateTime(d[1], 'YYYY-MM-DD');

    return [start, end];
  }

  return new DateTime(d, 'YYYY-MM-DD');
});
const picker = new easepick.create({
  element: document.getElementById('datepicker'),
  css: [
    'https://cdn.jsdelivr.net/npm/@easepick/[email protected]/dist/index.css',
    'https://easepick.com/css/demo_hotelcal.css',
  ],
  plugins: ['RangePlugin', 'LockPlugin'],
  RangePlugin: {
    tooltipNumber(num) {
      return num - 1;
    },
    locale: {
      one: 'night',
      other: 'nights',
    },
  },
  LockPlugin: {
    minDate: new Date(),
    minDays: 2,
    inseparable: true,
    filter(date, picked) {
      if (picked.length === 0) {
        return date.inArray(bookedDates, '[)');
      } else {
        const prevBooked = bookedDates.find(([start]) => start.isBefore(picked[0]));
        const nextBooked = bookedDates.find(([start]) => start.isAfter(picked[0]));

        if (!nextBooked) {
          return date.inArray(bookedDates, '[)');
        }

        const ms = nextBooked[0].getTime() + 86400000;
        const nextBookedDayAfter = new Date(ms);

        if (nextBooked && date.isSame(nextBooked[0], 'day')) {
          return false;
        }

        if (nextBooked && date.isSame(nextBookedDayAfter, 'day')) {
          return true;
        }
        if (prevBooked && date.isBetween(prevBooked[0], prevBooked[1], '()')) {
          return true;
        }

        if (nextBooked && date.isBetween(nextBooked[0], nextBooked[1], '()')) {
          return false;
        }

        if (bookedDates.filter(([start]) => date.isSame(start, 'day')).length > 0) {
          return true;
        }

        return false;
      }
    },
  },

  autoApply: false,
});
 <script src = "https://cdn.jsdelivr.net/npm/@easepick/[email protected]/dist/index.umd.min.js"></script>
 <input id = "datepicker"/>

Выглядит очень многообещающе, однако я обнаружил две ошибки. Попробуйте выбрать самую последнюю дату в качестве даты начала. Вы увидите, что возникает ошибка. Также попробуйте выбрать начальную дату из следующего месяца, а затем двигаться назад. Вы увидите, что вдруг становится возможным выбирать среди ранее забронированных дат.

Cjoerg 11.04.2023 09:03

Другие вопросы по теме