需求:
  1. 客戶指定要從Bootsrtap的Datepicker元件,轉為使用JQuery的Datepicker元件。
  2. 必須顯示民國年。
  3. 點選input不顯示元件,點選日曆圖示才顯示元件。

想法:

金融業的客戶堅持使用網站前台,使用民國年顯示,其實使用西元年顯示,與舊有系統串接資料再轉日期格式即可,未來與其他系統資料串接也會比較容易,結論必須寫plugin改寫現有元件,因為客戶最大。

改寫項目:

  1. 複寫顯示西元年,改為顯示民國年。
  2. 因為字數過長,使用css將元件寬度加長。
  3. binding資料到input時,轉換為民國年。
  4. JQuery元件預設input跟button觸發元件兩種模式,為了要綁定在原本Bootstrap的日曆圖示,使用css將該button隱藏。
  5. 使用JQuery selector綁定icon的click事件觸發顯示Datepicker元件。

引用js與css

<link href="/Content/jquery-ui-1.10.3/jquery-ui-1.10.3.custom.css" rel="stylesheet">
<script src="/Scripts/jquery-ui-1.10.3/jquery-ui-1.10.3.custom.min.js"></script>
<script src="/Scripts/share/locales/datepicker-zh-TW.js"></script>
<style>.ui-datepicker { width: 20em } .ui-datepicker-trigger { display:none }</style> 

JS plugin
(function (factory) {
    if (typeof define === "function" && define.amd) {

        // AMD. Register as an anonymous module.
        define(["../widgets/datepicker"], factory);
    } else {

        // Browser globals
        factory(jQuery.datepicker);
    }

}(function (datepicker) {
    var old_generateMonthYearHeader = $.datepicker._generateMonthYearHeader;
    var old_get = $.datepicker._get;
    var old_CloseFn = $.datepicker._updateDatepicker;
    $.extend($.datepicker, {
        _generateMonthYearHeader: function (inst, drawMonth, drawYear, minDate, maxDate, secondary, monthNames, monthNamesShort) {
            var htmlYearMonth = old_generateMonthYearHeader.apply(this, [inst, drawMonth, drawYear, minDate, maxDate, secondary, monthNames, monthNamesShort]);
            if ($(htmlYearMonth).find(".ui-datepicker-year").length > 0) {
                htmlYearMonth = $(htmlYearMonth).find(".ui-datepicker-year").find("option").each(function (i, e) {
                    if (Number(e.value) - 1911 > 0) $(e).text("民國" + (Number(e.innerText) - 1911) + "年");
                }).end().end().get(0).outerHTML;
            }
            return htmlYearMonth;
        },
        _get: function (a, b) {
            a.selectedYear = a.selectedYear - 1911 < 0 ? a.selectedYear + 1911 : a.selectedYear;
            a.drawYear = a.drawYear - 1911 < 0 ? a.drawYear + 1911 : a.drawYear;
            a.curreatYear = a.curreatYear - 1911 < 0 ? a.curreatYear + 1911 : a.curreatYear;
            return old_get.apply(this, [a, b]);
        },
        _updateDatepicker: function (inst) {
            old_CloseFn.call(this, inst);
            $(this).datepicker("widget").find(".ui-datepicker-buttonpane").children(":last")
                   .click(function (e) {
                       inst.input.val("");
                   });
        },
        _setDateDatepicker: function (a, b) {
            if (a = this._getInst(a)) { this._setDate(a, b); this._updateDatepicker(a); this._updateAlternate(a) }
        },
        _widgetDatepicker: function () {
            return this.dpDiv
        }

    });

    datepicker.regional["zh-TW"] = {
        closeText: "關閉",
        prevText: "<上個月",
        nextText: "下個月>",
        currentText: "今天",
        monthNames: ["一月", "二月", "三月", "四月", "五月", "六月",
        "七月", "八月", "九月", "十月", "十一月", "十二月"],
        monthNamesShort: ["一月", "二月", "三月", "四月", "五月", "六月",
        "七月", "八月", "九月", "十月", "十一月", "十二月"],
        dayNames: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
        dayNamesShort: ["週日", "週一", "週二", "週三", "週四", "週五", "週六"],
        dayNamesMin: ["日", "一", "二", "三", "四", "五", "六"],
        weekHeader: "週",
        dateFormat: "yymmdd",
        firstDay: 1,
        isRTL: false,
        showOn: "button",
        changeYear: true,
        changeMonth: true,
        showMonthAfterYear: true,
        onSelect: function (dateText, inst) {
            var dateFormate = inst.settings.dateFormat == null ? "yymmdd" : inst.settings.dateFormat; //取出格式文字
            var reM = /m+/g;
            var reD = /d+/g;
            var objDate = {
                y: inst.selectedYear - 1911 < 0 ? inst.selectedYear : padLeft((inst.selectedYear - 1911).toString(),3,"0"),
                m: padLeft(String(inst.selectedMonth + 1),2,"0"),
                d: padLeft(String(inst.selectedDay),2,"0")
            };
            $.each(objDate, function (k, v) {
                var re = new RegExp(k + "+");
                dateFormate = dateFormate.replace(re, v);
            });
            inst.input.val(dateFormate);
        }
    };
    datepicker.setDefaults(datepicker.regional["zh-TW"]);

    return datepicker.regional["zh-TW"];

}));

function padLeft(str, length, sign) {
    if (str.length >= length) return str;
    else return padLeft(sign + str, length, sign);
}


前端JS code
        //初始化Datepicker
        $("#BIRTHDAY").datepicker({
            yearRange: "-100:+0",
            dateFormat: "yy/mm/dd"
        });

        //綁定bootstrap日曆圖示觸發Datepicker
        $(".glyphicon-calendar").click(function () {
            $("#BIRTHDAY").datepicker('show');
        });


參考來源:JQueryUI datepicer輸出民國年

2 則留言:

  1. 不好意思, 冒昧請教一下.
    我試著套用了您的Code, 可出現了一個問題- 在textbox有值的情況下點選日曆圖示, 元件不會預設到那一個日期, 而是顯示今天的日期, 必須將textbox中的值改為西元年時才會正確顯示. 由於對這部分技術不熟, 可否直接請教一下應如何修改才能解決這一問題? 非常感謝!

    回覆刪除
    回覆
    1. 抱歉...平常沒在顧這個地方= =。後來自己暫時的解法,有值的狀況下把民國年轉成西元年set日曆跳出的日期,然後再把民國年的值蓋回textbox中。若您有不錯的方法也歡迎指教。

      刪除