Flatpickr onDayCreate add class

I am struggling with the Flatpickr ( https://chmln.imtqy.com/flatpickr/ ) event onDayCreate. Anyone who knows better how to check if the select date object matches any date in my date array?

I have an array (or an array of objects, not quite sure what to call it) when the dates are like this:

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 } 

And I will need to check if the value is 0,> 3 or 5 and add a class to this date. Flatpickr has an example, but it uses a math function to randomize what dates the new span element should be ( example ). But I can not configure my if else on addClass.

+5
source share
3 answers

I created a class dictionary for convenience only. You can use the keys of your object as a way to get the number associated with the day when flatpickr launches the onCreateDay callback. With the value associated with the day, you can get the class from the dictionary and, if it is not empty, add it to the element.

I added some clarification to the code to highlight some things that I find relevant.

You can check it in the script on this page (full screen if it is not displayed), or you can check it in this fiddle .

Hope this helps.

 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.."> 

UPDATE

The idea of โ€‹โ€‹the dictionary was to simplify adding / removing classes and avoid ugly switches or long ifs. However, you can easily change the code to filter by value (only values โ€‹โ€‹greater than 3 get classes), and add any class you want when this condition is met.

For example ( violin ):

 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); } } }); 

As you can see in the solutions I offer, there is no need to cycle through the object to get the value associated with the date, you can get it in constant time by compiling the date key from the date that flatpickr provides when building the day (onCreateDay callback).

UPDATE

According to the documentation (or so it seems), to get the date of the current day inside the onDayCreate callback, you should use the fp (currentYear and currentMonth) and dayElem (textContent) properties.

However, currentMonth always returns the month that the chart writer shows, not the month of the day (the calendar can show November, but the day can be in October or December), so you need to mess around a bit to avoid marking incorrect dates.

In this fiddle, you can find a solution that does not use dateObj, and works more as the documentation says.

And here is the code:

 // 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 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); } } }); 
+2
source

Something like this should do it (intentionally verbose so you can see what is happening):

  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); } } } }); 

Then add style rules to your page to indicate the dates accordingly:

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

Thanks to nfreeze and acontell for helping me figure this out when I think the documentation for this plugin was very hard to understand (for me at least).

Both answers from nfreeze and acontell worked from the very beginning when I found out my error using dayElem.dateObj .

The error is due to my old version of the plugin. I had 2.0.5 (currently this is the version for bower) and dateObj started working when I manually upgraded to version 2.0.6.

My way of using this was to create a new object (for my own purposes for future use), and then use each element value for the 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); 

And then the onCreate event, I used this:

 flatpickr("#dayCreate", { onDayCreate: function(dObj, dStr, fp, dayElem) { var date = moment(dayElem.dateObj).format(), value = datesForPicker[date]; if( value ){ dayElem.className += ' ' + value; } } }); 

Using Moment.js is logical because I already have this in my project, the reason for the format of the moment is to get these dates in the same format. You could do other ways.

0
source

Source: https://habr.com/ru/post/1258991/


All Articles