Flatpickr onDayCreate 添加 class

Flatpickr onDayCreate add class

我正在努力处理 Flatpickr (https://chmln.github.io/flatpickr/) 的 onDayCreate 事件。有谁更了解如何检查选择器的日期对象是否与我的日期数组中的任何日期匹配?

我有一个数组(或对象数组,不太确定如何称呼它),日期如下:

dates: {
"20161029": 3,
"20161030": 0,
"20161031": 0,
"20161101": 4,
"20161102": 4,
"20161103": 4,
"20161104": 5,
"20161105": 1,
"20161106": 0,
"20161107": 4,
"20161108": 3,
"20161109": 3,
"20161110": 4
}

我需要检查值是否为 0、>3 或 5,然后将 class 添加到该日期。 Flatpickr 有一个例子,但它使用数学函数来随机化哪些日期应该有新的跨度元素(example)。但是我无法将 if else 配置为 addClass。

应该这样做(故意冗长,以便您可以看到发生了什么):

   var dates =  {
       20161029: 3,
       20161030: 0,
       20161031: 0,
       20161101: 4,
       20161102: 4,
       20161103: 4,
       20161104: 5,
       20161105: 1,
       20161106: 0,
       20161107: 4,
       20161108: 3,
       20161109: 3,
       20161110: 4
   };

    flatpickr("#dayCreate", {
      onDayCreate: function (dObj, dStr, fp, dayElem) {
        //because you're working with an object and not an array, 
        //we'll iterate using its keys
        var myDateKeys = Object.keys(dates);
        for (var i = 0; i < myDateKeys.length; i++) {
            var myDateKey = myDateKeys[i]; // "20161029 
            var myDateVal = dates[myDateKey]; // 3       
            var myYear = parseInt(myDateKey.substr(0, 4));
            var myMonth = parseInt(myDateKey.substr(4, 2));
            var myDay = parseInt(myDateKey.substr(6, 2));

            var myDateObj = new Date(myYear + '-' + myMonth + '-' + myDay + ' 00:00:00');
            var fDateObj = dayElem.dateObj;

            //compare with event date 

             if (myDateObj.getTime() == fDateObj.getTime()) {
                    $(dayElem).addClass('myFancyDateClass' + myDateVal);
             }
        }
    }
});

然后将样式规则添加到您的页面以相应地突出显示日期:

.myFancyDateClass0{
   color: red;
}
.myFancyDateClass1{
   color: green;
}
.myFancyDateClass3{
   color: blue;
}
.myFancyDateClass4{
   color: yellow;
}
.myFancyDateClass5{
   color: pink;
}

为了方便起见,我创建了 classes 字典。当 flatpickr 触发 onCreateDay 回调时,您可以使用对象的键来检索与某一天关联的数字。使用与一天关联的值,您可以从字典中获取 class,如果它不为空,则将其添加到元素中。

我在代码中添加了一些解释,以突出显示我认为相关的一些内容。

您可以查看运行此页面中的脚本(如果看不到则全屏显示)或者您可以在此fiddle.

中查看

希望对您有所帮助。

var dates = {
    20161029: 3,
    20161030: 0,
    20161031: 0,
    20161101: 4,
    20161102: 4,
    20161103: 4,
    20161104: 5,
    20161105: 1,
    20161106: 0,
    20161107: 4,
    20161108: 3,
    20161109: 3,
    20161110: 4
  },
  classDict = {
    0: 'redClass',
    1: 'greenClass',
    3: 'blueClass',
    4: 'greyClass',
    5: 'orangeClass'
  };

// Better always use a two digit format in your dates obj
function get2DigitFmt(val) {
  return ('0' + val).slice(-2);
}

// onDayCreate event, add class to day if date has a class
flatpickr("#dayCreate", {
  onDayCreate: function(dObj, dStr, fp, dayElem) {
    var date = dayElem.dateObj,
      // Note the + 1 in the month.
      key = date.getFullYear() + get2DigitFmt(date.getMonth() + 1) + get2DigitFmt(date.getDate()),
      value = classDict[dates[key]];
    if (value) {
      dayElem.className += ' ' + value;
    }
  }
});
.redClass {
  background-color: red !important;
}
.greenClass {
  background-color: green !important;
}
.blueClass {
  background-color: blue !important;
}
.greyClass {
  background-color: grey !important;
}
.orangeClass {
  background-color: orange !important;
}
<link rel="stylesheet" href="https://unpkg.com/flatpickr/dist/flatpickr.min.css">
<script src="https://unpkg.com/flatpickr"></script>
<input id="dayCreate" type="text" placeholder="Select Date..">

更新

字典的想法是简化 adding/removing classes 并避免难看的开关或长 ifs。但是,您可以轻松修改代码以按值过滤(只有大于 3 的值会得到 class)并在满足条件时添加您想要的任何 class。

例如(fiddle):

function getClass(value) {
  // Here you could put any logic you want. Ifs, add the value to a string, whatever...
    return value === 4 ? 'redClass' : 'blueClass';
}
// onDayCreate event, add class to day if date has a class
flatpickr("#dayCreate", {
  onDayCreate: function(dObj, dStr, fp, dayElem) {
    var date = dayElem.dateObj,
      // Note the + 1 in the month.
      key = date.getFullYear() + get2DigitFmt(date.getMonth() + 1) + get2DigitFmt(date.getDate()),
      value = dates[key];
    if (value > 3) {
      dayElem.className += ' ' + getClass(value);
    }
  }
});

正如您在我提供的解决方案中看到的那样,无需一直遍历对象来获取与日期关联的值,您可以在恒定时间内获取它,组成日期的键从 flatpickr 在构建日期时提供的日期开始(onCreateDay 回调)。

更新

根据文档(或看起来如此),为了在 onDayCreate 回调中获取当前日期,您必须使用 fp(currentYear 和 currentMonth)和 dayElem(textContent)的属性。

然而,currentMonth returns 始终是 flatpicker 当前显示的月份,而不是当天的月份(日历可以显示 11 月,但日期可以是 10 月或 12 月)所以有点需要进行大量修改以避免标记不正确的日期。

在这个 fiddle 中,您可以找到一个不使用 dateObj 的解决方案,并且更像文档中所说的那样工作。

代码如下:

// Better always use a two digit format in your dates obj
function get2DigitFmt(val) {
  return ('0' + val).slice(-2);
}

function getClass(value) {
  // Here you could put any logic you want. Ifs, add the value to a string, whatever...
  return value === 4 ? 'redClass' : 'blueClass';
}

// Adjust month depending on the month's day
function getMonth(currentMonth, dayClass) {
  return currentMonth + (dayClass.contains('prevMonthDay') ? 0 : (1 + Number(dayClass.contains('nextMonthDay'))));
}

function getDateKey(year, month, day) {
  return year + get2DigitFmt(month) + get2DigitFmt(day);
}

// onDayCreate event, add class to day if date has a class
flatpickr("#dayCreate", {
  onDayCreate: function(dObj, dStr, fp, dayElem) {
    var key = getDateKey(fp.currentYear, getMonth(fp.currentMonth, dayElem.className), dayElem.textContent),
      value = dates[key];
    if (value > 3) {
      dayElem.className += ' ' + getClass(value);
    }
  }
});

感谢 nfreeze 和 acontell 在我认为该插件的文档有点难以理解(至少对我而言)时帮助我解决了这个问题。

nfreeze 和 acontell 的两个答案从一开始就有效,当我发现 dayElem.dateObj 的错误时。

错误是由于我的插件版本较旧。我有 2.0.5(目前是 bower 的版本),当我手动更新到版本 2.0.6 时 dateObj 开始工作。

我实际使用它的方法是制作新对象(为了我自己的目的以供将来使用)然后使用每个项目值 class:

var obj = dates,
    keys = Object.keys(obj),
    notAvailable = {},
    fewAvailable = {},
    available = {},
    value,
    date;

    var formattedDates = keys.filter(function(key) {
        if ( !obj[key]) {
          date = moment( key, 'YYYYMMDD' ).format();
          value = 'full';
          return notAvailable[date] = value;
        } else if( obj[key] < 3 ) {
          date = moment( key, 'YYYYMMDD' ).format();
          value = 'fewAvailable';
          return fewAvailable[date] = value;
        } else if( obj[key] >= 3 ) {
          date = moment( key, 'YYYYMMDD' ).format();
          value = 'available';
          return available[date] = value;
        }
 });

 var datesForPicker = Object.assign(notAvailable, fewAvailable, available);

然后是我使用的 onCreate 事件:

flatpickr("#dayCreate", {
 onDayCreate: function(dObj, dStr, fp, dayElem) {

   var date = moment(dayElem.dateObj).format(),
       value = datesForPicker[date];

   if( value ){
    dayElem.className += ' ' + value;
   }

 }
});

使用Moment.js是合乎逻辑的,因为我已经在我的项目中使用了它,时刻格式的原因是为了以相同的格式获取这些日期。你也可以用其他方式做到这一点。