iT邦幫忙

1

[實戰之jQuery] flatpickr的年份輸入(number input)無痛轉換成下拉(select)

  • 分享至 

  • xImage
  •  

話說在使用falcon admin template時,裡面有搭配到flatpickr v4做為日期/時間的選取器

雖然相較jQuery的datetimepicker或datepicker比較不好使用
但在外觀上的確比較好一些,因此就加了一些共用函式來操作flatpickr

    function setFlatpickrOption(_this, option, value) {
       $(_this).get(0)._flatpickr.set(option, value);
   }
   function getFlatpickrDates(_this) {
       return $(_this).get(0)._flatpickr.selectedDates;
       //return _.map($(_this).get(0)._flatpickr.selectedDates, (date) => date != '' ? new Date(date).toISOString() : '');
   }
   function setFlatpickrDates(_this, dateVal, withTime = false) {
       if ( dateVal == null && $(_this).get(0)._flatpickr ) {
           clearFlatpickrDates(_this);
           return;
       }
       dateVal = moment(withTime ? _layout.formatDateTime(dateVal) : _layout.formatDate(dateVal)).valueOf();
       if (moment(dateVal).isValid())
           $(_this).get(0)._flatpickr.setDate(dateVal);
   }
   function clearFlatpickrDates(_this) {
       // $(_this).get(0)._flatpickr.clear();
       $(_this).get(0)._flatpickr.destroy();
       flatpickr(_this, $(_this).data('options'));
   }
   function setFlatpickrYear(_this, year) {
       let _d = new Date(year, $(_this).get(0)._flatpickr.currentMonth, 1);
       // console.log($(_this).get(0)._flatpickr);
       $(_this).get(0)._flatpickr.jumpToDate(_d, false);
   }

保持使用jQuery的selector做為識別參數

setFlatpickrDates(`{selector}`, {dateValue});

這樣初步就可以使用起來了
但凡事總有一個BUT
因為在flatpickr的日期選擇是number input+內建會產生年份加減的按鈕
但不夠直接及明顯,比如不曉得的人要設定出生年就要按超多下
或者還要點入input自行輸入
考量到這類的使用者大多習慣下拉切換年份(如同datepicker)
因此就加了以下hack

  1. 首先把month select複製一份給year使用,並取一個識別的class name
    .flatpickr-current-month .flatpickr-yearDropdown-years {
       appearance: menulist;
       background: transparent;
       border: none;
       border-radius: 0;
       box-sizing: border-box;
       color: inherit;
       cursor: pointer;
       font-size: inherit;
       font-family: inherit;
       font-weight: 300;
       height: auto;
       line-height: inherit;
       margin: -1px 0 0 0;
       outline: none;
       padding: 0 0 0 0.5ch;
       position: relative;
       vertical-align: initial;
       -webkit-box-sizing: border-box;
       -webkit-appearance: menulist;
       -moz-appearance: menulist;
       width: auto;
   }
  1. 再來就把下面js加到document.ready裡面
    $('.datetimepickerV1').each(function() {
       let id = $(this).attr('id');
       let dateOption = Object.assign({
           onMonthChange: function(selectedDates, dateStr, instance) {
               $(instance.calendarContainer).find('.flatpickr-yearDropdown-years').val(instance.currentYear);
           },
           onOpen: function(selectedDates, dateStr, instance){
               let minYear = 1900, maxYear = new Date().getFullYear();
               let years = Array.apply(null, Array(maxYear - minYear + 1))
                   .map(function (y, i) { return minYear + i; });
               let currentYear = selectedDates.length > 0 ? selectedDates[0].getFullYear() : instance.currentYear;
               $(instance.calendarContainer).find('.numInputWrapper').replaceWith(`
                   <div class="numInputWrapper">
                       <select class="flatpickr-yearDropdown-years pe-1" onchange="setFlatpickrYear('#${id}', $(this).val());">
                           ${years.map(x => `<option ${x == currentYear ? 'selected' : ''}>${x}</option>`)}
                       </select>
                       <input class="numInput cur-year d-none" type="number" tabindex="-1" aria-label="Year">
                   </div>
               `);
           }
       }, $(this).data('options') || {});
       flatpickr($(this).get(0), dateOption);
   });

除了裡面的minYear, maxYear可以各自依需求調整之外
其它部份就可以如下跑動了:


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言