2017年4月19日 星期三

民國年選擇器 DatePicker

要搭配Jquery Datepicker

  1. /**
  2. * Created by EIJI on 2014/1/3.
  3. */
  4. (function(){
  5. var dateNative = new Date();
  6.  
  7. // 補0函式
  8. var padLeft = function(str, len){
  9.  
  10. if(str.length >= len){
  11. return str;
  12. }else{
  13. return padLeft(("0" + str), len);
  14. }
  15. };
  16.  
  17. var funcColle = function(){
  18. this.onSelect = {
  19. basic: function(dateText, inst){
  20. /*
  21. var yearNative = inst.selectedYear < 1911 ? inst.selectedYear + 1911 : inst.selectedYear;
  22. */
  23. dateNative = new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay);
  24.  
  25. // 年分小於100會被補成19**, 要做例外處理
  26. var yearTW;
  27. if (twSettings.yearPadZero) {
  28. if(inst.selectedYear > 1911){
  29. yearTW = padLeft((inst.selectedYear - 1911).toString(), 3);
  30. }else{
  31. yearTW = padLeft(inst.selectedYear.toString(), 3)
  32. }
  33. }else{
  34. if(inst.selectedYear > 1911){
  35. yearTW = inst.selectedYear - 1911;
  36. }else{
  37. yearTW = inst.selectedYear;
  38. }
  39. }
  40. var monthTW = padLeft((inst.selectedMonth + 1).toString(), 2);
  41. var dayTW = padLeft(inst.selectedDay, 2);
  42.  
  43. return yearTW + twSettings.splitMark + monthTW + twSettings.splitMark + dayTW;
  44. }
  45. };
  46. };
  47.  
  48. var twSettings = {
  49. closeText: '關閉',
  50. prevText: '上個月',
  51. nextText: '下個月',
  52. currentText: '今天',
  53. changeYear: true, //手動修改年
  54. changeMonth: true, //手動修改月
  55. yearRange: '1912:' + dateNative.getFullYear(),
  56. monthNames: [
  57. '一月','二月','三月','四月','五月',
  58. '六月','七月','八月','九月','十月',
  59. '十一月','十二月'
  60. ],
  61. monthNamesShort: [
  62. '一月','二月','三月','四月','五月',
  63. '六月','七月','八月','九月','十月',
  64. '十一月','十二月'
  65. ],
  66. dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
  67. dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
  68. dayNamesMin: ['日','一','二','三','四','五','六'],
  69. weekHeader: '周',
  70. dateFormat: 'yy/mm/dd',
  71. splitMark: '/', // 分割年月日的標誌
  72. firstDay: 1,
  73. isRTL: false,
  74. showMonthAfterYear: false,
  75. yearSuffix: '',
  76. yearPadZero: false,
  77. beforeShow: function() {
  78. setTimeout(function(){
  79. $('.ui-datepicker').css('z-index', 1000);
  80. }, 0);
  81. }
  82. // ,defaultLastYear: false
  83. /*
  84. 當沒有設defaultDate時,先用yearRange做defaultDate
  85. 此時defaultLastYear設定預設為最後一年or第一年
  86. */
  87. };
  88.  
  89. // 把yearText換成民國
  90. var replaceYearText = function(){
  91. var $yearText = $('.ui-datepicker-year');
  92.  
  93. if(twSettings.changeYear !== true){
  94. $yearText.text('民國' + dateNative.getFullYear() - 1911);
  95. }else{
  96. // 下拉選單
  97. /*
  98. if($yearText.prev('span.datepickerTW-yearPrefix').length === 0){
  99. $yearText.before("民國 ");
  100. }
  101. */
  102. $yearText.children().each(function(){
  103. if(parseInt($(this).text(), 10) > 1911){
  104. $(this).text(parseInt($(this).text(), 10) - 1911);
  105. }
  106. });
  107. }
  108. };
  109.  
  110. $.fn.datepickerTW = function(options){
  111. if(typeof options === "undefined"){
  112. options = {};
  113. }
  114.  
  115. var fn = new funcColle();
  116. // setting on init,
  117. if(typeof options == 'object'){
  118. //onSelect例外處理, 避免覆蓋
  119. if(typeof options.onSelect == 'function'){
  120. fn.onSelect.newFunc = options.onSelect;
  121. }
  122.  
  123. options.onSelect = function(dateText, inst){
  124. var outputValue = fn.onSelect.basic(dateText, inst);
  125.  
  126. if(twSettings.yearPadZero){
  127. outputValue = padLeft(outputValue, 9);
  128. }
  129. $(this).val(outputValue);
  130.  
  131. if(typeof fn.onSelect.newFunc === 'function'){
  132. fn.onSelect.newFunc(outputValue, inst);
  133. }
  134. };
  135.  
  136. // year range正規化成西元, 小於1911的數字都會被當成民國年
  137. if(options.yearRange){
  138. var temp = options.yearRange.split(':');
  139. for(var i = 0; i < temp.length; i += 1){
  140. //民國前處理
  141. if(parseInt(temp[i], 10) < 1 ){
  142. temp[i] = parseInt(temp[i], 10) + 1911;
  143. }else{
  144. if(parseInt(temp[i], 10) < 1911){
  145. temp[i] = parseInt(temp[i], 10) + 1911;
  146. }else{
  147. temp[i] = temp[i];
  148. }
  149. }
  150. }
  151. options.yearRange = temp[0] + ':' + temp[1];
  152. }
  153.  
  154. // 預設default Date
  155. if(options.defaultDate){
  156.  
  157. }else if(options.yearRange){
  158. var temp = options.yearRange.split(':');
  159.  
  160. if(options.defaultLastYear){
  161. options.defaultDate = temp[1] - new Date().getFullYear() + 'y';
  162. }else{
  163. options.defaultDate = temp[0] - new Date().getFullYear() + 'y';
  164. }
  165. }else if($.trim($(this).val()) != '' && $(this).val() != undefined){
  166. var tempDate = $(this).val().split(twSettings.splitMark);
  167. var tempYear = tempDate[0];
  168.  
  169. var year;
  170. if(parseInt(tempYear, 10) < 1911){
  171. year = padLeft((parseInt(tempYear, 10) + 1911).toString(), 4);
  172. }else{
  173. year = parseInt(tempYear, 10);
  174. }
  175.  
  176. options.defaultDate = year - new Date().getFullYear() + 'y';
  177. }
  178. }
  179.  
  180. // setting after init
  181. if(arguments.length > 1){
  182. // 目前還沒想到正常的解法, 先用轉換成init setting obj的形式
  183. if(arguments[0] === 'option'){
  184. options = {};
  185. options[arguments[1]] = arguments[2];
  186. }
  187. }
  188.  
  189. // override settings
  190. $.extend(twSettings, options);
  191.  
  192. // init
  193. $(this).datepicker(twSettings);
  194.  
  195. // beforeRender
  196. $(this).click(function(){
  197. var isFirstTime = ($(this).val() == '');
  198. // year range and default date
  199. if((twSettings.defaultDate || twSettings.yearRange) && isFirstTime){
  200. /* 當有year range時, select初始化設成range的最末年
  201. 已調整到上面"預設default Date"中
  202. if(twSettings.defaultDate){
  203. $(this).datepicker('setDate', twSettings.defaultDate);
  204. }
  205.  
  206. // 這段處理不好,因為「年」只改了外觀,但javascript實際值還是原本那年
  207. // 當有year range時, select初始化設成range的最末年
  208. if(twSettings.yearRange){
  209. var $yearSelect = $('.ui-datepicker-year'),
  210. nowYear = twSettings.defaultDate
  211. ? $(this).datepicker('getDate').getFullYear()
  212. : dateNative.getFullYear();
  213.  
  214. $yearSelect.children(':selected').removeAttr('selected');
  215. if($yearSelect.children('[value=' + nowYear + ']').length > 0){
  216. $yearSelect.children('[value=' + nowYear + ']').attr('selected', 'selected');
  217. }else{
  218. $yearSelect.children().last().attr('selected', 'selected');
  219. }
  220. }
  221. */
  222. } else {
  223. var tempDate = $(this).val().split(twSettings.splitMark);
  224.  
  225. if(tempDate.length != 3){
  226. $(this).datepicker('setDate', new Date());
  227. }else{
  228. var tempYear = tempDate[0];
  229. var tempMonth = tempDate[1] - 1;
  230. var tempDay = padLeft(tempDate[2], 2);
  231.  
  232. var year;
  233. if(parseInt(tempYear, 10) < 1911){
  234. year = padLeft((parseInt(tempYear, 10) + 1911).toString(), 4);
  235. }else{
  236. year = parseInt(tempYear, 10);
  237. }
  238.  
  239. dateNative = new Date(year, tempMonth, tempDay);
  240.  
  241. $(this).datepicker('setDate', dateNative);
  242. }
  243. }
  244.  
  245. var yearTW;
  246. if (twSettings.yearPadZero) {
  247. if(dateNative.getFullYear() > 1911){
  248. yearTW = padLeft((dateNative.getFullYear() - 1911).toString(), 3);
  249. }else{
  250. yearTW = padLeft(dateNative.getFullYear().toString(), 3);
  251. }
  252. }else{
  253. if(dateNative.getFullYear() > 1911){
  254. yearTW = dateNative.getFullYear() - 1911;
  255. }else{
  256. yearTW = dateNative.getFullYear();
  257. }
  258. }
  259. var monthTW = padLeft((dateNative.getMonth() + 1).toString(), 2);
  260. var dayTW = padLeft(dateNative.getDate().toString(), 2);
  261.  
  262. $(this).val(yearTW + twSettings.splitMark + monthTW + twSettings.splitMark + dayTW);
  263.  
  264. replaceYearText();
  265.  
  266. if(isFirstTime){
  267. $(this).val('');
  268. }
  269. });
  270.  
  271. // afterRender
  272. $(this).focus(function(){
  273. replaceYearText();
  274. });
  275.  
  276. return this;
  277. };
  278. })();

用法跟Jquery Datepicker一樣
    $element.datepickerTW();

在這邊有客製小功能:

    splitMark: '/' // 分割年月日的標誌
可自由設定年月日中間的分隔符號

    yearPadZero: false
年的部分(民國年)補滿3碼

3 則留言:

  1. 感謝您
    讓我總是 GOOGLE 到答案

    回覆刪除
  2. 大感謝!!!拯救上路qq
    經測試,jQuery 3.7.1 作用成功

    回覆刪除
    回覆
    1. 補記:
      測試後發現有時兩位數日期會在前方被補0
      不確定是只有我這裡的問題或是大大那裏也有發生問題
      總之研究了您的程式碼後修改如下:
      於 補0函式 內調整判斷
      if (str.length == len) {
      return str;
      } else if (str.length > len) {
      return str.substr(1, len);
      } (else 維持不變)

      刪除