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

问题描述 投票:0回答:1

我在我的一个项目中使用 flatpickr。我的情况是我有从 flatpcikr 中选择的范围日期选择器。选择日期范围后,我有另一个日期选择器,其中所有选定的日期都被选中并变成绿色。否 每当我想从所选日期中取消选择日期时,它就会变成红色。如果我按选择取消选择它会再次变成绿色。

这是日期选择器的 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>

这是Js代码:

<script>
    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');
            //     }
            // }
        });
}
    
});

</script>

因此,正如您所看到的绿色日期,当我取消选择它们时,它们将变成红色。这就是我想要的,到目前为止我已经弄清楚了。

javascript html css datepicker flatpickr
1个回答
0
投票

似乎 flatpickr 没有提供 API 来将自定义类添加到日历中的日期元素,但我们可以使用其

aria-label
值来选择和设置取消选择的日期的样式。

  1. 创建一个构造样式表。我们将在此处保存红色取消选择日期的 CSS 规则:
    const disableStyles = new CSSStyleSheet();
    document.adoptedStyleSheets.push(disableStyles);
    
  2. 获取我们感兴趣的日期
    aria-labels
    的列表
    updateMultiDatePicker()
    function updateMultiDatePicker(selectedDates) {
      // …
      let ariaLabels = [];
      // …
      while (currentDate <= endDate) {
        // …
        ariaLabels = ariaLabels.concat(
          picker2.formatDate(
            new Date(currentDate),
            picker2.config.ariaDateFormat,
          ),
        );
        // …
      }
    
  3. 将此
    aria-label
    值列表转换为 CSS 选择器:
    const selectors = ariaLabels
      .map((label) => `[aria-label="${label}"]`)
      .join(",");
    
  4. 添加 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>

© www.soinside.com 2019 - 2024. All rights reserved.