I am using Flatpickr for my calendar needs. It provides an input field with arrows to change the year.
I need to have a dropdown inside the calendar so that I can select a year from that dropdown and the calendar points to that year subsequently.
I have given a special class .birthDate
to the calendar element dynamically. I have added a dropdown to the calendar dynamically, like so:
var currYear = new Date().getFullYear()
var yearOptions = "";
for(var i = 1960; i <= currYear; i++) {
var option = "<option value = " + i + ">" + i + "</option>";
yearOptions += option;
}
var yearDropdown = "<select class=\"year-dropdown\">" + yearOptions + "</select>";
$(".birthDate .flatpickr-current-month").append(yearDropdown);
The problem is, nothing happens when I click it. My guess is there's some preventDefault
method that prevents any click from causing any action. Yet when I add a console statement on click of the dropdown, it appears on the console.
So my question is how do i open the dropdown on click of it. Please find an example of the issue here.
if anyone is interested in adding a year dropdown select option to Flatpickr, here is my solution
// plugin js file
/**
* Flatpickr Year Select Plugin.
* @author Labi Romabravo
*/
/**
*
* @returns {Function}
*/
const yearDropdownPlugin = function (pluginConfig) {
var defaultConfig = {
text: '',
theme: "light",
date: new Date(),
yearStart: 100,
yearEnd: 2,
};
var config = {};
for (var key in defaultConfig) {
config[key] = pluginConfig && pluginConfig[key] !== undefined ? pluginConfig[key] : defaultConfig[key];
}
var getYear = function (value) {
var date = value.split("/");
return parseInt(date[2], 10);
}
var currYear = new Date().getFullYear();
var selectedYear = getYear(config.date);
var yearDropdown = document.createElement("select");
var createSelectElement = function (year) {
var start = new Date().getFullYear() - config.yearStart;
var end = currYear + config.yearEnd;
for (var i = end; i >= start; i--) {
var option = document.createElement("option");
option.value = i;
option.text = i;
yearDropdown.appendChild(option);
}
yearDropdown.value = selectedYear;
};
return function (fp) {
fp.yearSelectContainer = fp._createElement(
"div",
"flatpickr-year-select " + config.theme + "Theme",
config.text
);
fp.yearSelectContainer.tabIndex = -1;
createSelectElement(selectedYear);
yearDropdown.addEventListener('change', function (evt) {
var year = evt.target.options[evt.target.selectedIndex].value;
fp.changeYear(year);
});
fp.yearSelectContainer.append(yearDropdown);
return {
onReady: function onReady() {
var name = fp.monthNav.className;
const yearInputCollection = fp.calendarContainer.getElementsByClassName(name);
const el = yearInputCollection[0];
el.parentNode.insertBefore(fp.yearSelectContainer, el.parentNode.firstChild);
}
};
};
}
export default yearDropdownPlugin
// if (typeof module !== "undefined")
// module.exports = yearDropdownPlugin;
Usage
import yearDropdownPlugin from "@/utils/year_flatpickr_plugin";
var input = document.querySelector("#" + this.containerId);
this.datepicker = flatpickr(input, {
plugins: [
new yearDropdownPlugin({
date: this.value,
yearStart: this.yearStart,
yearEnd: this.yearEnd
})
],
wrap: true,
enableTime: false,
dateFormat: "d/m/Y",
minDate: this.min
//mode: "range"
});
Css
.flatpickr-current-month .numInputWrapper {
display: none;
}
.flatpickr-current-month span.cur-month {
margin-right: 10px;
width: 85px;
font-size: 0.75em;
top: 0px;
padding-top: 10px;
padding-right: 2px;
position: absolute;
left: 0px;
font-weight: 600;
text-align: right;
}
.flatpickr-current-month {
width: 100px;
}
.flatpickr-year-select {
background-color:#052f66;
z-index: 100;
position: absolute;
top: 5px;
right: 70px;
width: 100px;
}
.flatpickr-year-select select{
width: 100%;
height: 24px;
font-weight: 600;
outline: 0;
overflow: hidden;
background: #ffffff;
color: #747a80;
border: #ffffff;
padding: 0;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 6px;
}
Final output
Got here after our client request to change year picker to something more comfortable. Thanks to a guy above providing with some links to flatpickr plugin options.
Here is my solution if anybody still needs it. First off all, we have a setting script in html page (later called using wicket). It creates a flatpickr instance and binds it to an html element:
<script type="text/javascript">
const FLATPICKR_CUSTOM_YEAR_SELECT = 'flatpickr-custom-year-select';
const initDatePicker = function (inputId) {
$("#" + inputId).flatpickr({
dateFormat: "d/m/Y",
minDate: "01.01.1900",
maxDate: "01.01.2100",
allowInput: true,
onChange: function () {
$("#" + inputId).blur();
}
})
};
</script>
What I did is just added some additional code in order to insert a select tag instead of the existing element and provide with event processing in order to follow value change in the custom select and pass it to a native element. In orReady event native year picker gets hidden, select element gets created and onChange event implemented where selected value is passed to a native year element. onMonthChange is needed in order to change year value when clicking on side arrows (changing month). So now it looks like this:
<script type="text/javascript">
const FLATPICKR_CUSTOM_YEAR_SELECT = 'flatpickr-custom-year-select';
const initDatePicker = function (inputId) {
$("#" + inputId).flatpickr({
dateFormat: "d/m/Y",
minDate: "01.01.1900",
maxDate: "01.01.2100",
allowInput: true,
onChange: function () {
$("#" + inputId).blur();
},
//here what was added
onReady: function (selectedDates, dateStr, instance) {
const flatpickrYearElement = instance.currentYearElement;
const children = flatpickrYearElement.parentElement.children;
for (let i in children) {
if (children.hasOwnProperty(i)) {
children[i].style.display = 'none';
}
}
const yearSelect = document.createElement('select');
const minYear = new Date(instance.config._minDate).getFullYear();
const maxYear = new Date(instance.config._maxDate).getFullYear();
for (let i = minYear; i < maxYear; i++) {
const option = document.createElement('option');
option.value = '' + i;
option.text = '' + i;
yearSelect.appendChild(option);
}
yearSelect.addEventListener('change', function (event) {
flatpickrYearElement.value = event.target['value'];
instance.currentYear = parseInt(event.target['value']);
instance.redraw();
});
yearSelect.className = 'flatpickr-monthDropdown-months';
yearSelect.id = FLATPICKR_CUSTOM_YEAR_SELECT;
yearSelect.value = instance.currentYearElement.value;
flatpickrYearElement.parentElement.appendChild(yearSelect);
},
onMonthChange: function (selectedDates, dateStr, instance) {
document.getElementById(FLATPICKR_CUSTOM_YEAR_SELECT).value = '' + instance.currentYear;
}
})
};
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With