uxsolutions / bootstrap-datepicker

A datepicker for twitter bootstrap (@twbs)
Apache License 2.0
12.66k stars 6.06k forks source link

Display only available options for years mode #2694

Closed billyz313 closed 5 months ago

billyz313 commented 5 months ago

Expected behaviour

I am using the datepicker for years only in this instance. I have available years from 2016 to 2022 only. When the picker opens it should display 2016 in the top left corner as the first option and end with 2022 as the last option. I would not like to see the seven disabled years prior to the first available year (as seen in the image below), which also causes years 2021 and 2022 to have to be paged to. Is there a way to do this so that the seven pickable years are displayed and the users don't have to page to find the last two?

image

Actual behaviour

As mentioned above the picker displays seven undesired (yet disabled) years prior to the minDate, it also displays past the maxDate, but this is less of a concern, altho if we could remove both that would be optimal. I have experimented with css

.year.disabled{display:none;}

which does remove the disabled, however instead of 2021 and 2022 showing on the initial picker view we still have to page to the next to be able to select them.

image

Datepicker version used

1.10.0

Example code

Because I have many and the positioning was not working I initialize the pickers in the each loop where i can set the container to the parent.

$('.yearpicker').each(function () {
                var container = $(this).parent();

                $(this).datepicker({
                    format: "yyyy",
                    viewMode: "years",
                    startView: "years",
                    yearStart: 1,
                    startDate: new Date(2016, 0, 1),
                    minViewMode: "years",
                    autoclose: true,
                    container: container,
                    orientation: 'auto',
                    minDate: new Date(2016, 0, 1), // January 1, 2016
                    maxDate: new Date(2022, 11, 31), // December 31, 2022
                });

            });

Thank you, i appreciate your assistance.

billyz313 commented 5 months ago

Update

I have been able to find a workaround where i basically build the calendar on show. This seems to solve my issue, I'll leave it here in case anyone else needs similar functionality.

image

            $('.yearpicker').each(function () {
                var container = $(this).parent();

                $(this).datepicker({
                    format: "yyyy",
                    viewMode: "years",
                    startView: "years",
                    minViewMode: "years",
                    maxViewMode: "years",
                    autoclose: true,
                    container: container,
                    orientation: 'auto',
                }).on('show', function (event) {
                    var currentYear = new Date().getFullYear();
                    var startYear = 2016;
                    var endYear = 2022;
                    var numYears = endYear - startYear + 1;

                    // Set the initial view to startYear
                    $(this).datepicker('update', new Date(startYear, 0, 1));

                    // Clear out all existing years
                    $('.datepicker-years .datepicker-switch').text(startYear);

                    // Generate and append years
                    var yearsHtml = '';
                    for (var i = 0; i < numYears; i++) {
                        var year = startYear + i;
                        yearsHtml += '<span class="year' + (year === currentYear ? ' active' : '') + '">' + year + '</span>';
                    }
                    $('.datepicker-years tbody').html('<tr><td colspan="7">' + yearsHtml + '</td></tr>');
                });

            });