css 如何在flatpickr中更改取消选择的日期的颜色

mum43rcc  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(120)

我在我的一个项目中使用flatpickr。我的场景是,我有一个使用flatpickr的范围日期选择器。在我选择一个日期范围后,我有另一个日期选择器,所有选定的日期都被选中并变成绿色。现在,每当我想从选定的日期中删除一个日期时,日期应该变成红色。如果我选择取消选择的日期,它应该再次变成绿色。


的数据
下面是日期选择器的html代码:

<div class="column-2 w-100 w-100 d-flex justify-content-between">
  <p class="w-25 fs-6 fw-bold">Operational calendar</p>
  <div class="w-75 d-flex gap-3">
    <input type="text" name="" class="form-control bg-light" id="dateRangePicker" placeholder="Select date" />
    {{-- <input type="date" class="form-control" /> --}}
  </div>
</div>

<div class="column-2 w-100 w-100 d-flex justify-content-between">
  <p class="w-25 fs-6 fw-bold">Opening and closing dates</p>
  <div class="w-75 d-flex gap-3">
    <input type="hidden" name="" />
    <div id="dateRangePicker2" class="w-100"></div>
    {{-- <input type="date" class="form-control" /> --}}
  </div>
</div>

字符串
下面是JavaScript代码:

document.addEventListener("DOMContentLoaded", function () {
  var dateRangePicker = document.getElementById("dateRangePicker");
  var dateRangePicker2 = document.getElementById("dateRangePicker2");

  var picker = flatpickr(dateRangePicker, {
    mode: "range",
    dateFormat: "d-m-Y",
    onChange: function (selectedDates) {
      updateMultiDatePicker(selectedDates);
    },
  });

  var picker2 = flatpickr(dateRangePicker2, {
    mode: "multiple",
    dateFormat: "Y-m-d",
    open: true,
    inline: true,
    allowInput: true,
    onChange: function (selectedDates) {
      updateDeselectedDates(selectedDates);
    },
  });

  function updateMultiDatePicker(selectedDates) {
    const allDates = document.querySelectorAll("#dateRangePicker2 .flatpickr-day");
    allDates.forEach(function (el) {
      el.classList.add("blabla");
    });
    // console.log(allDates)
    if (selectedDates.length === 2) {
      var startDate = selectedDates[0];
      var endDate = selectedDates[1];
      var datesToUpdate = [];

      var currentDate = new Date(startDate);
      while (currentDate <= endDate) {
        datesToUpdate.push(new Date(currentDate));
        currentDate.setDate(currentDate.getDate() + 1);
      }

      picker2.setDate(datesToUpdate);
    }
  }

  function updateDeselectedDates(selectedDates) {
    const allSelectedDates = document.querySelectorAll(".flatpickr-day.selected");
    // allSelectedDates.addClass

    allSelectedDates.forEach(function (dateElement) {
      dateElement.classList.add("blabla");

      if (!dateElement.classList.contains("blabla")) {
        dateElement.addEventListener("click", function () {
          dateElement.classList.add("deselected");
        });
      }
      const dateString = dateElement.getAttribute("aria-label");
      const isSelected = selectedDates.includes(dateString);

      // if (isSelected) {
      //     if (!dateElement.classList.contains('selected')) {
      //         dateElement.classList.add('deselected');
      //     } else {
      //         dateElement.classList.remove('deselected');
      //     }
      // }
    });
  }
});


所以你可以看到,对于绿色的日期,当他们被取消选择,应该变成红色。这就是我想要的,到目前为止,我已经得到了。

ui7jx7zq

ui7jx7zq1#

似乎flatpickr没有提供API来向日历中的日期元素添加自定义类,但是我们可以使用它们的aria-label值来选择和样式化取消选择的日期。
1.创建一个constructed stylesheet。这是我们将保存的红色取消选择日期的CSS规则:

const disableStyles = new CSSStyleSheet();
document.adoptedStyleSheets.push(disableStyles);

1.获取我们对updateMultiDatePicker()感兴趣的日期的aria-labels列表:

function updateMultiDatePicker(selectedDates) {
  // …
  let ariaLabels = [];
  // …
  while (currentDate <= endDate) {
    // …
    ariaLabels = ariaLabels.concat(
      picker2.formatDate(
        new Date(currentDate),
        picker2.config.ariaDateFormat,
      ),
    );
    // …
  }

1.将aria-label值列表转换为CSS选择器:

const selectors = ariaLabels
  .map((label) => `[aria-label="${label}"]`)
  .join(",");

1.添加CSS规则以使日历中的这些日期单元格为红色:

disableStyles.replace(
  `#dateRangePicker2 + .flatpickr-calendar :is(${selectors}):not(.selected) { background-color: red }`,
);
const disableStyles = new CSSStyleSheet();
document.adoptedStyleSheets.push(disableStyles);

document.addEventListener("DOMContentLoaded", function () {
  var dateRangePicker = document.getElementById("dateRangePicker");
  var dateRangePicker2 = document.getElementById("dateRangePicker2");

  var picker = flatpickr(dateRangePicker, {
    mode: "range",
    dateFormat: "d-m-Y",
    onChange: function (selectedDates) {
      updateMultiDatePicker(selectedDates);
    },
  });

  var picker2 = flatpickr(dateRangePicker2, {
    mode: "multiple",
    dateFormat: "Y-m-d",
    open: true,
    inline: true,
    allowInput: true,
    onChange: function (selectedDates) {
      updateDeselectedDates(selectedDates);
    },
  });

  function updateMultiDatePicker(selectedDates) {
    const allDates = document.querySelectorAll(
      "#dateRangePicker2 .flatpickr-day",
    );
    allDates.forEach(function (el) {
      el.classList.add("blabla");
    });

    // console.log(allDates)
    if (selectedDates.length === 2) {
      var startDate = selectedDates[0];
      var endDate = selectedDates[1];
      var datesToUpdate = [];
      let ariaLabels = [];

      var currentDate = new Date(startDate);
      while (currentDate <= endDate) {
        datesToUpdate.push(new Date(currentDate));
        ariaLabels = ariaLabels.concat(
          picker2.formatDate(
            new Date(currentDate),
            picker2.config.ariaDateFormat,
          ),
        );
        currentDate.setDate(currentDate.getDate() + 1);
      }

      picker2.setDate(datesToUpdate);

      const selectors = ariaLabels
        .map((label) => `[aria-label="${label}"]`)
        .join(",");
      disableStyles.replace(
        `#dateRangePicker2 + .flatpickr-calendar :is(${selectors}):not(.selected) { background-color: red }`,
      );
    }
  }

  function updateDeselectedDates(selectedDates) {
    const allSelectedDates = document.querySelectorAll(
      ".flatpickr-day.selected",
    );
    // allSelectedDates.addClass

    allSelectedDates.forEach(function (dateElement) {
      dateElement.classList.add("blabla");

      if (!dateElement.classList.contains("blabla")) {
        dateElement.addEventListener("click", function () {
          dateElement.classList.add("deselected");
        });
      }
      const dateString = dateElement.getAttribute("aria-label");
      const isSelected = selectedDates.includes(dateString);

      // if (isSelected) {
      //     if (!dateElement.classList.contains('selected')) {
      //         dateElement.classList.add('deselected');
      //     } else {
      //         dateElement.classList.remove('deselected');
      //     }
      // }
    });
  }
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" integrity="sha512-b2QcS5SsA8tZodcDtGRELiGv5SaKSk1vDHDaQRda0htPYWZ6046lr3kJ5bAAQdpV2mmA/4v0wQF9MyU6/pDIAg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.css" integrity="sha512-MQXduO8IQnJVq1qmySpN87QQkiR1bZHtorbJBD0tzy7/0U9+YIC93QWHeGTEoojMVHWWNkoCp8V6OzVSYrX0oQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.13/flatpickr.min.js" integrity="sha512-K/oyQtMXpxI4+K0W7H25UopjM8pzq0yrVdFdG21Fh5dBe91I40pDd9A4lzNlHPHBIP2cwZuoxaUSX0GJSObvGA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div class="column-2 w-100 w-100 d-flex justify-content-between">
  <p class="w-25 fs-6 fw-bold">Operational calendar</p>
  <div class="w-75 d-flex gap-3">
    <input
      type="text"
      name=""
      class="form-control bg-light"
      id="dateRangePicker"
      placeholder="Select date"
    />
  </div>
</div>

<div class="column-2 w-100 w-100 d-flex justify-content-between">
  <p class="w-25 fs-6 fw-bold">Opening and closing dates</p>
  <div class="w-75 d-flex gap-3">
    <input type="hidden" name="" />
    <div id="dateRangePicker2" class="w-100"></div>
  </div>
</div>

的字符串

相关问题