dateRange.js 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. /**
  2. *=======================================================================
  3. *日期选择器js组件。
  4. *@author :johnnyzheng(johnnyzheng@tencent.com) 郑灿双
  5. *@version : 2012-07-11
  6. *@modification list:2012-08-16 规范样式名称
  7. * 2013-01-04 增加主题设置接口
  8. * 2013-01-31 增加自定义灰掉周末 周几的选项,增加自动初始化自动提交的功能
  9. * 2013-03-15 支持一个页面多个日期选择器,快捷日期选择
  10. * 2013-03-26 增加确认、取消按钮的隐藏,而直接自动提交
  11. * 2013-08-01 扩展接口,增加最近90天,增加自定义可选时间
  12. * 2013-08-12 日期选择器框体宽度超出视窗大小的时候制动鼓靠右对齐
  13. * 2014-02-25 增加业务接口:获取当前日期对象的的选中日期
  14. * 2014-10-13 扩展参数,支持日期下拉选择自定义年和月份,配合theme:ta来使用。
  15. *=======================================================================
  16. */
  17. /**
  18. * @description 整个日期选择器对象的构造函数入口,支持丰富的接口参数传递,大多数提供默认配置,可传入覆盖
  19. * @param {String} inputId 日期选择器ID
  20. * @param {object} options 配置数组
  21. */
  22. function pickerDateRange(inputId, options) {
  23. /**
  24. * 默认配置参数数据,每个参数涵义在后解释
  25. */
  26. var defaults = {
  27. aToday : 'aToday', //今天
  28. aYesterday : 'aYesterday', //昨天
  29. aRecent7Days : 'aRecent7Days', //最近7天
  30. aRecent14Days : 'aRecent14Days',//最近14天
  31. aRecent30Days : 'aRecent30Days', //最近30天
  32. aRecent90Days : 'aRecent90Days', //最近90天
  33. startDate : '', // 开始日期
  34. endDate : '', // 结束日期
  35. startCompareDate : '', // 对比开始日期
  36. endCompareDate : '', // 对比结束日期
  37. minValidDate : '315507600', //最小可用时间,控制日期选择器的可选力度
  38. maxValidDate : '', // 最大可用时间,与stopToday 配置互斥
  39. success : function(obj) {return true;}, //回调函数,选择日期之后执行何种操作
  40. startDateId : 'startDate', // 开始日期输入框ID
  41. startCompareDateId : 'startCompareDate', // 对比开始日期输入框ID
  42. endDateId : 'endDate', // 结束日期输入框ID
  43. endCompareDateId : 'endCompareDate', // 对比结束日期输入框ID
  44. target : '', // 日期选择框的目标,一般为 <form> 的ID值
  45. needCompare : false, // 是否需要进行日期对比
  46. suffix : '', //相应控件的后缀
  47. inputTrigger : 'input_trigger',
  48. compareTrigger : 'compare_trigger',
  49. compareCheckboxId : 'needCompare', // 比较选择框
  50. calendars : 2, // 展示的月份数,最大是2
  51. dayRangeMax : 0, // 日期最大范围(以天计算)
  52. monthRangeMax : 12, // 日期最大范围(以月计算)
  53. dateTable : 'dateRangeDateTable', // 日期表格的CSS类
  54. selectCss : 'dateRangeSelected', // 时间选择的样式
  55. compareCss : 'dateRangeCompare', // 比较时间选择的样式
  56. coincideCss : 'dateRangeCoincide', // 重合部分的样式
  57. firstCss : 'first', //起始样式
  58. lastCss : 'last', //结束样式
  59. clickCss : 'today', //点击样式
  60. disableGray : 'dateRangeGray', // 非当前月的日期样式
  61. isToday : 'dateRangeToday', // 今天日期的样式
  62. joinLineId : 'joinLine',
  63. isSingleDay : false,
  64. defaultText : ' 至 ',
  65. singleCompare : false,
  66. stopToday : true,
  67. isTodayValid : false,
  68. weekendDis : false, //灰掉周末不可选。
  69. disCertainDay : [], //不可用的周日期设置数组,如:[1,3]是要周一, 周三 两天不可选,每个周的周一,周三都不可选择。
  70. disCertainDate : [],//不可用的日期设置数组,如:[1,3]是要1号,3号 两天不可选,特别的,[true,1,3]则反之,只有1,3可选,其余不可选。
  71. shortOpr : false, //结合单天日期选择的短操作,不需要确定和取消的操作按钮。
  72. noCalendar : false, //日期输入框是否展示
  73. theme : 'gri', //日期选择器的主题,目前支持 'gri' / 'ta'
  74. magicSelect : false, //用户自定义选择年、月,与{theme:ta}配合使用。
  75. autoCommit : false, //加载后立马自动提交
  76. autoSubmit : false, //没有确定,取消按钮,直接提交
  77. replaceBtn : 'btn_compare'
  78. };
  79. //将对象赋给__method变量
  80. var __method = this;
  81. this.inputId = inputId;
  82. this.inputCompareId = inputId + 'Compare';
  83. this.compareInputDiv = 'div_compare_'+inputId;
  84. // 配置参数
  85. this.mOpts = $.extend({}, defaults, options);
  86. //默认日历参数最大是3
  87. this.mOpts.calendars = Math.min(this.mOpts.calendars, 3);
  88. //根据不同主题需要初始化的变量
  89. this.mOpts.compareCss = this.mOpts.theme == 'ta' ? this.mOpts.selectCss :this.mOpts.compareCss
  90. //昨天,今天,最近7天,最近14天,最近30天
  91. this.periodObj = {};
  92. this.periodObj[__method.mOpts.aToday] = 0;
  93. this.periodObj[__method.mOpts.aYesterday] = 1;
  94. this.periodObj[__method.mOpts.aRecent7Days] = 6;
  95. this.periodObj[__method.mOpts.aRecent14Days] = 13;
  96. this.periodObj[__method.mOpts.aRecent30Days] = 29;
  97. this.periodObj[__method.mOpts.aRecent90Days] = 89;
  98. // 记录初始默认时间
  99. this.startDefDate = '';
  100. // 随机ID后缀
  101. var suffix = '' == this.mOpts.suffix ? (new Date()).getTime() : this.mOpts.suffix;
  102. // 日期选择框DIV的ID
  103. this.calendarId = 'calendar_' + suffix;
  104. // 日期列表DIV的ID
  105. this.dateListId = 'dateRangePicker_' + suffix;
  106. // 日期比较层
  107. this.dateRangeCompareDiv = 'dateRangeCompareDiv_' + suffix;
  108. //日期选择层
  109. this.dateRangeDiv = 'dateRangeDiv_' + suffix;
  110. // 日期对比选择控制的checkbox
  111. this.compareCheckBoxDiv = 'dateRangeCompareCheckBoxDiv_' + suffix;
  112. // 时间选择的确认按钮
  113. this.submitBtn = 'submit_' + suffix;
  114. // 日期选择框关闭按钮
  115. this.closeBtn = 'closeBtn_' + suffix;
  116. // 上一个月的按钮
  117. this.preMonth = 'dateRangePreMonth_' + suffix;
  118. // 下一个月的按钮
  119. this.nextMonth = 'dateRangeNextMonth_' + suffix;
  120. // 表单中开始、结束、开始对比、结束对比时间
  121. this.startDateId = this.mOpts.startDateId + '_' + suffix;
  122. this.endDateId = this.mOpts.endDateId + '_' + suffix;
  123. this.compareCheckboxId = this.mOpts.compareCheckboxId + '_' + suffix;
  124. this.startCompareDateId = this.mOpts.startCompareDateId + '_' + suffix;
  125. this.endCompareDateId = this.mOpts.endCompareDateId + '_' + suffix;
  126. // 初始化日期选择器面板的HTML代码串
  127. var wrapper = {
  128. gri :[
  129. '<div id="' + this.calendarId + '" class="gri_dateRangeCalendar">',
  130. '<table class="gri_dateRangePicker"><tr id="' + this.dateListId + '"></tr></table>',
  131. '<div class="gri_dateRangeOptions" '+ (this.mOpts.autoSubmit ? ' style="display:none" ' : '') +'>',
  132. '<div class="gri_dateRangeInput" id="' + this.dateRangeDiv + '" >',
  133. '<input type="text" class="gri_dateRangeInput" name="' + this.startDateId + '" id="' + this.startDateId + '" value="' + this.mOpts.startDate + '" readonly />',
  134. '<span id="' + this.mOpts.joinLineId + '"> - </span>',
  135. '<input type="text" class="gri_dateRangeInput" name="' + this.endDateId + '" id="' + this.endDateId + '" value="' + this.mOpts.endDate + '" readonly /><br />',
  136. '</div>',
  137. '<div class="gri_dateRangeInput" id="' + this.dateRangeCompareDiv + '">',
  138. '<input type="text" class="gri_dateRangeInput" name="' + this.startCompareDateId + '" id="' + this.startCompareDateId + '" value="' + this.mOpts.startCompareDate + '" readonly />',
  139. '<span class="' + this.mOpts.joinLineId + '"> - </span>',
  140. '<input type="text" class="gri_dateRangeInput" name="' + this.endCompareDateId + '" id="' + this.endCompareDateId + '" value="' + this.mOpts.endCompareDate + '" readonly />',
  141. '</div>',
  142. '<div class="frm_btn">',
  143. '<input class="btn btn-primary btn-xs" type="button" name="' + this.submitBtn + '" id="' + this.submitBtn + '" value="确定" />',
  144. '&nbsp;<a class="btn btn-default btn-xs" id="' + this.closeBtn + '" href="javascript:;">关闭</a>',
  145. '</div>',
  146. '</div>',
  147. '</div>'
  148. ],
  149. ta:[
  150. '<div id="' + this.calendarId + '" class="ta_calendar ta_calendar2 cf">',
  151. '<div class="ta_calendar_cont cf" id="'+ this.dateListId +'">',
  152. //'<table class="dateRangePicker"><tr id="' + this.dateListId + '"></tr></table>',
  153. '</div>',
  154. '<div class="ta_calendar_footer cf" '+ (this.mOpts.autoSubmit ? ' style="display:none" ' : '') +'>',
  155. '<div class="frm_msg">',
  156. '<div id="' + this.dateRangeDiv + '">',
  157. '<input type="text" class="ta_ipt_text_s" name="' + this.startDateId + '" id="' + this.startDateId + '" value="' + this.mOpts.startDate + '" readonly />',
  158. '<span class="' + this.mOpts.joinLineId + '"> - </span>',
  159. '<input type="text" class="ta_ipt_text_s" name="' + this.endDateId + '" id="' + this.endDateId + '" value="' + this.mOpts.endDate + '" readonly /><br />',
  160. '</div>',
  161. '<div id="' + this.dateRangeCompareDiv + '">',
  162. '<input type="text" class="ta_ipt_text_s" name="' + this.startCompareDateId + '" id="' + this.startCompareDateId + '" value="' + this.mOpts.startCompareDate + '" readonly />',
  163. '<span class="' + this.mOpts.joinLineId + '"> - </span>',
  164. '<input type="text" class="ta_ipt_text_s" name="' + this.endCompareDateId + '" id="' + this.endCompareDateId + '" value="' + this.mOpts.endCompareDate + '" readonly />',
  165. '</div>',
  166. '</div>',
  167. '<div class="frm_btn">',
  168. '<input class="ta_btn ta_btn_primary" type="button" name="' + this.submitBtn + '" id="' + this.submitBtn + '" value="确定" />',
  169. '<input class="ta_btn" type="button" id="' + this.closeBtn + '" value="取消"/>',
  170. '</div>',
  171. '</div>',
  172. '</div>'
  173. ]
  174. };
  175. //对比日期框体的html串
  176. var checkBoxWrapper = {
  177. gri:[
  178. '<label class="gri_contrast" for ="' + this.compareCheckboxId + '">',
  179. '<input type="checkbox" class="gri_pc" name="' + this.compareCheckboxId + '" id="' + this.compareCheckboxId + '" value="1"/>对比',
  180. '</label>',
  181. '<input type="text" name="'+this.inputCompareId+'" id="'+this.inputCompareId+'" value="" class="gri_date"/>'
  182. ],
  183. ta:[
  184. '<label class="contrast" for ="' + this.compareCheckboxId + '">',
  185. '<input type="checkbox" class="pc" name="' + this.compareCheckboxId + '" id="' + this.compareCheckboxId + '" value="1"/>对比',
  186. '</label>',
  187. '<div class="ta_date" id="'+this.compareInputDiv+'">',
  188. ' <span name="dateCompare" id="'+this.inputCompareId+'" class="date_title"></span>',
  189. ' <a class="opt_sel" id="'+ this.mOpts.compareTrigger +'" href="#">',
  190. ' <i class="i_orderd"></i>',
  191. ' </a>',
  192. '</div>'
  193. ]
  194. };
  195. //把checkbox放到页面的相应位置,放置到inputid后面 added by johnnyzheng
  196. if(this.mOpts.theme == 'ta'){
  197. $(checkBoxWrapper[this.mOpts.theme].join('')).insertAfter($('#div_' + this.inputId));
  198. }else{
  199. $(checkBoxWrapper[this.mOpts.theme].join('')).insertAfter($('#' + this.inputId));
  200. }
  201. //根据传入参数决定是否展示日期输入框
  202. if(this.mOpts.noCalendar){
  203. $('#' + this.inputId).css('display', 'none');
  204. $('#' + this.compareCheckboxId).parent().css('display','none');
  205. }
  206. // 把时间选择框放到页面中
  207. $(0 < $('#appendParent').length ? '#appendParent' : document.body).append(wrapper[this.mOpts.theme].join(''));
  208. $('#' + this.calendarId).css('z-index', 9999);
  209. // 初始化目标地址的元素
  210. if(1 > $('#' + this.mOpts.startDateId).length) {
  211. $(''!=this.mOpts.target?'#'+this.mOpts.target:'body').append('<input type="hidden" id="' + this.mOpts.startDateId + '" name="' + this.mOpts.startDateId + '" value="' + this.mOpts.startDate + '" />');
  212. } else {
  213. $('#' + this.mOpts.startDateId).val(this.mOpts.startDate);
  214. }
  215. if(1 > $('#' + this.mOpts.endDateId).length) {
  216. $(''!=this.mOpts.target?'#'+this.mOpts.target:'body').append('<input type="hidden" id="' + this.mOpts.endDateId + '" name="' + this.mOpts.endDateId + '" value="' + this.mOpts.endDate + '" />');
  217. } else {
  218. $('#' + this.mOpts.endDateId).val(this.mOpts.endDate);
  219. }
  220. if(1 > $('#' + this.mOpts.compareCheckboxId).length) {
  221. $(''!=this.mOpts.target?'#'+this.mOpts.target:'body').append('<input type="checkbox" id="' + this.mOpts.compareCheckboxId + '" name="' + this.mOpts.compareCheckboxId + '" value="0" style="display:none;" />');
  222. }
  223. // 如果不需要比较日期,则需要隐藏比较部分的内容
  224. if(false == this.mOpts.needCompare) {
  225. $('#' + this.compareInputDiv).css('display', 'none');
  226. $('#' + this.compareCheckBoxDiv).css('display', 'none');
  227. $('#' + this.dateRangeCompareDiv).css('display', 'none');
  228. $('#' + this.compareCheckboxId).attr('disabled', true);
  229. $('#' + this.startCompareDateId).attr('disabled', true);
  230. $('#' + this.endCompareDateId).attr('disabled', true);
  231. //隐藏对比的checkbox
  232. $('#' + this.compareCheckboxId).parent().css('display','none');
  233. $('#'+ this.mOpts.replaceBtn).length > 0 && $('#'+ this.mOpts.replaceBtn).hide();
  234. } else {
  235. if(1 > $('#' + this.mOpts.startCompareDateId).length) {
  236. $(''!=this.mOpts.target?'#'+this.mOpts.target:'body').append('<input type="hidden" id="' + this.mOpts.startCompareDateId + '" name="' + this.mOpts.startCompareDateId + '" value="' + this.mOpts.startCompareDate + '" />');
  237. } else {
  238. $('#' + this.mOpts.startCompareDateId).val(this.mOpts.startCompareDate);
  239. }
  240. if(1 > $('#' + this.mOpts.endCompareDateId).length) {
  241. $(''!=this.mOpts.target?'#'+this.mOpts.target:'body').append('<input type="hidden" id="' + this.mOpts.endCompareDateId + '" name="' + this.mOpts.endCompareDateId + '" value="' + this.mOpts.endCompareDate + '" />');
  242. } else {
  243. $('#' + this.mOpts.endCompareDateId).val(this.mOpts.endCompareDate);
  244. }
  245. if('' == this.mOpts.startCompareDate || '' == this.mOpts.endCompareDate) {
  246. $('#' + this.compareCheckboxId).attr('checked', false);
  247. $('#' + this.mOpts.compareCheckboxId).attr('checked', false);
  248. } else {
  249. $('#' + this.compareCheckboxId).attr('checked', true);
  250. $('#' + this.mOpts.compareCheckboxId).attr('checked', true);
  251. }
  252. }
  253. // 输入框焦点定在第一个输入框
  254. this.dateInput = this.startDateId;
  255. // 为新的输入框加背景色
  256. this.changeInput(this.dateInput);
  257. // 开始时间 input 的 click 事件
  258. $('#' + this.startDateId).bind('click', function() {
  259. // 如果用户在选择基准结束时间时,换到对比时间了,则
  260. if(__method.endCompareDateId == __method.dateInput) {
  261. $('#' + __method.startCompareDateId).val(__method.startDefDate);
  262. }
  263. __method.startDefDate = '';
  264. __method.removeCSS(1);
  265. //__method.addCSS(1);
  266. __method.changeInput(__method.startDateId);
  267. return false;
  268. });
  269. $('#' + this.calendarId).bind('click', function(event) {
  270. //event.preventDefault();
  271. // 防止冒泡
  272. event.stopPropagation();
  273. });
  274. // 开始比较时间 input 的 click 事件
  275. $('#' + this.startCompareDateId).bind('click', function() {
  276. // 如果用户在选择基准结束时间时,换到对比时间了,则
  277. if(__method.endDateId == __method.dateInput) {
  278. $('#' + __method.startDateId).val(__method.startDefDate);
  279. }
  280. __method.startDefDate = '';
  281. __method.removeCSS(0);
  282. //__method.addCSS(0);
  283. __method.changeInput(__method.startCompareDateId);
  284. return false;
  285. });
  286. /**
  287. * 设置回调句柄,点击成功后,返回一个时间对象,包含开始结束时间
  288. * 和对比开始结束时间
  289. */
  290. $('#' + this.submitBtn).bind('click', function() {
  291. __method.close(1);
  292. __method.mOpts.success({'startDate': $('#' + __method.mOpts.startDateId).val(),
  293. 'endDate': $('#' + __method.mOpts.endDateId).val(),
  294. 'needCompare' : $('#' + __method.mOpts.compareCheckboxId).val(),
  295. 'startCompareDate':$('#' + __method.mOpts.startCompareDateId).val(),
  296. 'endCompareDate':$('#' + __method.mOpts.endCompareDateId).val()
  297. });
  298. return false;
  299. });
  300. // 日期选择关闭按钮的 click 事件
  301. $('#' + this.closeBtn).bind('click', function() {
  302. __method.close();
  303. return false;
  304. });
  305. // 为输入框添加click事件
  306. $('#' + this.inputId).bind('click', function() {
  307. __method.init();
  308. __method.show(false, __method);
  309. return false;
  310. });
  311. $('#' + this.mOpts.inputTrigger).bind('click', function() {
  312. __method.init();
  313. __method.show(false, __method);
  314. return false;
  315. });
  316. $('#' + this.mOpts.compareTrigger).bind('click', function() {
  317. __method.init(true);
  318. __method.show(true, __method);
  319. return false;
  320. });
  321. // 为输入框添加click事件
  322. $('#' + this.inputCompareId).bind('click', function() {
  323. __method.init(true);
  324. __method.show(true, __method);
  325. return false;
  326. });
  327. //判断是否是实时数据,如果是将时间默认填充进去 added by johnnyzheng 12-06
  328. if(this.mOpts.singleCompare){
  329. if(this.mOpts.theme === 'ta'){
  330. $('#' + __method.startDateId).val(__method.mOpts.startDate);
  331. $('#' + __method.endDateId).val(__method.mOpts.startDate);
  332. $('#' + __method.startCompareDateId).val(__method.mOpts.startCompareDate);
  333. $('#' + __method.endCompareDateId).val(__method.mOpts.startCompareDate);
  334. }
  335. else{
  336. $('#' + __method.startDateId).val(__method.mOpts.startDate);
  337. $('#' + __method.endDateId).val(__method.mOpts.startDate);
  338. $('#' + __method.startCompareDateId).val(__method.mOpts.startCompareDate);
  339. $('#' + __method.endCompareDateId).val(__method.mOpts.startCompareDate);
  340. $('#' + this.compareCheckboxId).attr('checked',true);
  341. $('#' + this.mOpts.compareCheckboxId).attr('checked',true);
  342. }
  343. }
  344. // 时间对比
  345. $('#' + this.dateRangeCompareDiv).css('display', $('#' + this.compareCheckboxId).attr('checked') ? '' : 'none');
  346. $('#' + this.compareInputDiv).css('display', $('#' + this.compareCheckboxId).attr('checked') ? '' : 'none');
  347. $('#' + this.compareCheckboxId).bind('click', function() {
  348. $('#' + __method.inputCompareId).css('display', this.checked ? '' : 'none');
  349. // 隐藏对比时间选择
  350. $('#' + __method.dateRangeCompareDiv).css('display', this.checked ? '' : 'none');
  351. $('#' + __method.compareInputDiv).css('display', this.checked ? '' : 'none');
  352. // 把两个对比时间框置为不可用
  353. $('#' + __method.startCompareDateId).css('disabled', this.checked ? false : true);
  354. $('#' + __method.endCompareDateId).css('disabled', this.checked ? false : true);
  355. // 修改表单的 checkbox 状态
  356. $('#' + __method.mOpts.compareCheckboxId).attr('checked', $('#' + __method.compareCheckboxId).attr('checked'));
  357. // 修改表单的值
  358. $('#' + __method.mOpts.compareCheckboxId).val($('#' + __method.compareCheckboxId).attr('checked')?1:0);
  359. // 初始化选框背景
  360. if($('#' + __method.compareCheckboxId).attr('checked')) {
  361. sDate = __method.str2date($('#' + __method.startDateId).val());
  362. sTime = sDate.getTime();
  363. eDate = __method.str2date($('#' + __method.endDateId).val());
  364. eTime = eDate.getTime();
  365. scDate = $('#' + __method.startCompareDateId).val();
  366. ecDate = $('#' + __method.endCompareDateId).val();
  367. if('' == scDate || '' == ecDate) {
  368. ecDate = __method.str2date(__method.date2ymd(sDate).join('-'));
  369. ecDate.setDate(ecDate.getDate() - 1);
  370. scDate = __method.str2date(__method.date2ymd(sDate).join('-'));
  371. scDate.setDate(scDate.getDate() - ((eTime - sTime) / 86400000) - 1);
  372. //这里要和STATS_START_TIME的时间进行对比,如果默认填充的对比时间在这个时间之前 added by johnnyzheng
  373. if(ecDate.getTime() < __method.mOpts.minValidDate * 1000){
  374. scDate = sDate;
  375. ecDate = eDate;
  376. }
  377. if(ecDate.getTime() >= __method.mOpts.minValidDate * 1000 && scDate.getTime() < __method.mOpts.minValidDate * 1000){
  378. scDate.setTime(__method.mOpts.minValidDate * 1000)
  379. scDate = __method.str2date(__method.date2ymd(scDate).join('-'));
  380. ecDate.setDate(scDate.getDate() + ((eTime - sTime) / 86400000) - 1);
  381. }
  382. $('#' + __method.startCompareDateId).val(__method.formatDate(__method.date2ymd(scDate).join('-')));
  383. $('#' + __method.endCompareDateId).val(__method.formatDate(__method.date2ymd(ecDate).join('-')));
  384. }
  385. __method.addCSS(1);
  386. // 输入框焦点切换到比较开始时间
  387. __method.changeInput(__method.startCompareDateId);
  388. } else {
  389. __method.removeCSS(1);
  390. // 输入框焦点切换到开始时间
  391. __method.changeInput(__method.startDateId);
  392. }
  393. //用户点击默认自动提交 added by johnnyzheng 12-08
  394. __method.close(1);
  395. __method.mOpts.success({'startDate': $('#' + __method.mOpts.startDateId).val(),
  396. 'endDate': $('#' + __method.mOpts.endDateId).val(),
  397. 'needCompare' : $('#' + __method.mOpts.compareCheckboxId).val(),
  398. 'startCompareDate':$('#' + __method.mOpts.startCompareDateId).val(),
  399. 'endCompareDate':$('#' + __method.mOpts.endCompareDateId).val()
  400. });
  401. });
  402. // 初始化开始
  403. this.init();
  404. // 关闭日期选择框,并把结果反显到输入框
  405. this.close(1);
  406. if(this.mOpts.replaceBtn && $('#'+this.mOpts.replaceBtn).length > 0){
  407. $('#'+ __method.compareCheckboxId).hide();
  408. $('.contrast').hide();
  409. $('#'+this.mOpts.replaceBtn).bind('click', function(){
  410. var self = this;
  411. $('#'+ __method.compareCheckboxId).attr('checked')
  412. ? $('#'+ __method.compareCheckboxId).removeAttr('checked')
  413. : $('#'+ __method.compareCheckboxId).attr('checked', 'checked');
  414. $('#'+ __method.compareCheckboxId).click();
  415. $('#'+ __method.compareCheckboxId).attr('checked')
  416. ? function(){
  417. $('#'+ __method.compareCheckboxId).removeAttr('checked');
  418. $('.contrast').hide();
  419. $(self).text('按时间对比');
  420. }()
  421. : function(){
  422. $('#'+ __method.compareCheckboxId).attr('checked', 'checked');
  423. $('.contrast').show();
  424. $(self).text('取消对比');
  425. }();
  426. });
  427. }
  428. if(this.mOpts.autoCommit){
  429. this.mOpts.success({'startDate': $('#' + __method.mOpts.startDateId).val(),
  430. 'endDate': $('#' + __method.mOpts.endDateId).val(),
  431. 'needCompare' : $('#' + __method.mOpts.compareCheckboxId).val(),
  432. 'startCompareDate':$('#' + __method.mOpts.startCompareDateId).val(),
  433. 'endCompareDate':$('#' + __method.mOpts.endCompareDateId).val()
  434. });
  435. }
  436. //让用户点击页面即可关闭弹窗
  437. $(document).bind('click', function () {
  438. __method.close();
  439. });
  440. };
  441. /**
  442. * @description 日期选择器的初始化方法,对象原型扩展
  443. * @param {Boolean} isCompare 标识当前初始化选择面板是否是对比日期
  444. */
  445. pickerDateRange.prototype.init = function(isCompare) {
  446. var __method = this;
  447. var minDate, maxDate;
  448. var isNeedCompare = typeof(isCompare) != 'undefined'? isCompare && $("#" + __method.compareCheckboxId).attr('checked') : $("#" + __method.compareCheckboxId).attr('checked');
  449. // 清空日期列表的内容
  450. $("#" + this.dateListId).empty();
  451. // 如果开始日期为空,则取当天的日期为开始日期
  452. var endDate = '' == this.mOpts.endDate ? (new Date()) : this.str2date(this.mOpts.endDate);
  453. // 日历结束时间
  454. this.calendar_endDate = new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0);
  455. //如果是magicSelect 自定义年和月份,则自定义填充日期
  456. if(this.mOpts.magicSelect && this.mOpts.theme == 'ta'){
  457. var i = 0;
  458. do{
  459. var td = null;
  460. if(i==0){
  461. td = this.fillDate(this.str2date($('#'+this.endDateId).val()).getFullYear(), this.str2date($('#'+this.endDateId).val()).getMonth(), i);
  462. $("#" + this.dateListId).append(td);
  463. }
  464. else{
  465. td = this.fillDate(this.str2date($('#'+this.startDateId).val()).getFullYear(), this.str2date($('#'+this.startDateId).val()).getMonth(), i);
  466. var firstTd = (this.mOpts.theme == 'ta' ? $("#" + this.dateListId).find('table').get(0) : $("#" + this.dateListId).find('td').get(0));
  467. $(firstTd).before(td);
  468. }
  469. i++;
  470. }while(i<2);
  471. // 日历开始时间
  472. this.calendar_startDate = new Date(this.str2date($('#'+this.startDateId).val()).getFullYear(), this.str2date($('#'+this.startDateId).val()).getMonth(), 1);
  473. }else{
  474. // 计算并显示以 endDate 为结尾的最近几个月的日期列表
  475. for(var i = 0; i < this.mOpts.calendars; i ++) {
  476. var td = null;
  477. if(this.mOpts.theme == 'ta'){
  478. td = this.fillDate(endDate.getFullYear(), endDate.getMonth(), i);
  479. }
  480. else{
  481. td = document.createElement('td');
  482. $(td).append(this.fillDate(endDate.getFullYear(), endDate.getMonth(), i));
  483. $(td).css('vertical-align', 'top');
  484. }
  485. if(0 == i) {
  486. $("#" + this.dateListId).append(td);
  487. } else {
  488. var firstTd = (this.mOpts.theme == 'ta' ? $("#" + this.dateListId).find('table').get(0) : $("#" + this.dateListId).find('td').get(0));
  489. $(firstTd).before(td);
  490. }
  491. endDate.setMonth(endDate.getMonth() - 1, 1);
  492. }
  493. // 日历开始时间
  494. this.calendar_startDate = new Date(endDate.getFullYear(), endDate.getMonth() + 1, 1);
  495. }
  496. // 上一个月
  497. $('#' + this.preMonth).bind('click', function() {
  498. __method.calendar_endDate.setMonth(__method.calendar_endDate.getMonth() - 1, 1);
  499. __method.mOpts.endDate = __method.date2ymd(__method.calendar_endDate).join('-');
  500. __method.init(isCompare);
  501. //如果是单月选择的时候,要控制input输入框 added by johnnyzheng 2011-12-19
  502. if(1 == __method.mOpts.calendars){
  503. if('' == $('#' + __method.startDateId).val()){
  504. __method.changeInput(__method.startDateId);
  505. }
  506. else{
  507. __method.changeInput(__method.endDateId);
  508. }
  509. }
  510. return false;
  511. });
  512. // 下一个月
  513. $('#' + this.nextMonth).bind('click', function() {
  514. __method.calendar_endDate.setMonth(__method.calendar_endDate.getMonth() + 1, 1);
  515. __method.mOpts.endDate = __method.date2ymd(__method.calendar_endDate).join('-');
  516. __method.init(isCompare);
  517. //如果是单月选择的时候,要控制input输入框 added by johnnyzheng 2011-12-19
  518. if(1 == __method.mOpts.calendars){
  519. if('' == $('#' + __method.startDateId).val()){
  520. __method.changeInput(__method.startDateId);
  521. }
  522. else{
  523. __method.changeInput(__method.endDateId);
  524. }
  525. }
  526. return false;
  527. });
  528. //如果有用户自定义选择月份,则为其绑定事件
  529. if(this.mOpts.magicSelect) this.bindChangeForSelect();
  530. // 初始化时间选区背景
  531. if(this.endDateId != this.dateInput && this.endCompareDateId != this.dateInput) {
  532. (isNeedCompare && typeof(isCompare) !='undefined') ? this.addCSS(1) : this.addCSS(0);
  533. }
  534. if(isNeedCompare && typeof(isCompare) !='undefined'){
  535. __method.addCSS(1);
  536. }
  537. else{
  538. __method.addCSS(0);
  539. }
  540. // 隐藏对比日期框
  541. $('#' + __method.inputCompareId).css('display', isNeedCompare ? '' : 'none');
  542. $('#' + this.compareInputDiv).css('display', $('#' + this.compareCheckboxId).attr('checked') ? '' : 'none');
  543. //昨天,今天,最近7天,最近30天快捷的点击,样式要自己定义,id可以传递默认,也可覆盖
  544. for(var property in __method.periodObj){
  545. if($('#'+ property).length > 0){
  546. $('#' + property).unbind('click');
  547. $('#' + property).bind('click' , function(){
  548. //处理点击样式
  549. var cla = __method.mOpts.theme == 'ta' ? 'active' : 'a';
  550. $(this).parent().nextAll().removeClass(cla);
  551. $(this).parent().prevAll().removeClass(cla);
  552. $(this).parent().addClass(cla);
  553. //拼接提交时间串
  554. var timeObj = __method.getSpecialPeriod(__method.periodObj[$(this).attr('id')]);
  555. $('#' + __method.startDateId).val(__method.formatDate(timeObj.otherday));
  556. $('#' + __method.endDateId).val(__method.formatDate(timeObj.today));
  557. $('#' + __method.mOpts.startDateId).val($('#' + __method.startDateId).val());
  558. $('#' + __method.mOpts.endDateId).val($('#' + __method.endDateId).val());
  559. __method.mOpts.theme == 'ta' ? $('#'+__method.compareInputDiv).hide() : $('#' + __method.inputCompareId).css('display','none');
  560. $('#' + __method.compareCheckboxId).attr('checked', false);
  561. $('#' + __method.mOpts.compareCheckboxId).attr('checked', false);
  562. $('#' + this.compareInputDiv).css('display', $('#' + this.compareCheckboxId).attr('checked') ? '' : 'none');
  563. __method.close(1);
  564. //于此同时清空对比时间框的时间
  565. $('#' + __method.startCompareDateId).val('');
  566. $('#' + __method.endCompareDateId).val('');
  567. $('#' + __method.mOpts.startCompareDateId).val('');
  568. $('#' + __method.mOpts.endCompareDateId).val('');
  569. $('#' + __method.mOpts.compareCheckboxId).val(0);
  570. if($('#'+ __method.mOpts.replaceBtn).length > 0){
  571. $('.contrast').hide();
  572. $('#'+ __method.mOpts.replaceBtn).text('按时间对比');
  573. }
  574. //点击提交
  575. __method.mOpts.success({'startDate': $('#' + __method.mOpts.startDateId).val(),
  576. 'endDate': $('#' + __method.mOpts.endDateId).val(),
  577. 'needCompare' : $('#' + __method.mOpts.compareCheckboxId).val(),
  578. 'startCompareDate':$('#' + __method.mOpts.startCompareDateId).val(),
  579. 'endCompareDate':$('#' + __method.mOpts.endCompareDateId).val()
  580. });
  581. });
  582. }
  583. }
  584. // 让用户手动关闭或提交日历,每次初始化的时候绑定,关闭的时候解绑 by zacharycai
  585. $(document).bind('click', function () {
  586. __method.close();
  587. });
  588. //完全清空日期控件的值 by zacharycai
  589. $('#' + this.inputId).bind('change', function(){
  590. if ($(this).val() === ''){
  591. $('#' + __method.startDateId).val('');
  592. $('#' + __method.endDateId).val('');
  593. $('#' + __method.startCompareDateId).val('');
  594. $('#' + __method.endCompareDateId).val('');
  595. }
  596. })
  597. };
  598. pickerDateRange.prototype.bindChangeForSelect = function(){
  599. var __method = this;
  600. //气泡弹窗
  601. var _popup = function(btn, ctn, wrap, css) {
  602. css = css || 'open';
  603. var ITEMS_TIMEOUT = null, time_out = 500;
  604. function hidePop() {
  605. $('#' + ctn).removeClass(css);
  606. }
  607. function showPop() {
  608. $('#' + ctn).addClass(css);
  609. }
  610. function isPopShow() {
  611. return $('#' + ctn).attr('class') == css;
  612. }
  613. $("#" + btn).click(function() {
  614. isPopShow() ? hidePop() : showPop();
  615. }).mouseover(function() {
  616. clearTimeout(ITEMS_TIMEOUT);
  617. }).mouseout(function() {
  618. ITEMS_TIMEOUT = setTimeout(hidePop, time_out);
  619. });
  620. $('#' + wrap).mouseover(function() {
  621. clearTimeout(ITEMS_TIMEOUT);
  622. }).mouseout(function() {
  623. ITEMS_TIMEOUT = setTimeout(hidePop, time_out);
  624. });
  625. };
  626. //自定义选择的触发动作
  627. try{
  628. $("#" + this.dateListId).find('div[id*="selected"]').each(function(){
  629. //绑定pop
  630. var _match = $(this).attr('id').match(/(\w+)_(\d)/i);
  631. if(_match){
  632. var _name = _match[1];//名称
  633. var _idx = _match[2];//下标
  634. if(_name=='yselected'){
  635. _popup('_ybtn_'+_idx, $(this).attr('id'), '_yctn_'+_idx);
  636. }
  637. else if(_name=='mselected'){
  638. _popup('_mbtn_'+_idx, $(this).attr('id'), '_mctn_'+_idx);
  639. }
  640. $(this).find('li a').each(function(){
  641. $(this).click(function() {
  642. var match = $(this).parents('.select_wrap').attr('id').match(/(\w+)_(\d)/i);
  643. //if(match){
  644. var name = match[1];//名称
  645. var idx = match[2];//下标
  646. var nt = null;
  647. if(idx^1 == 0){
  648. //开始
  649. if(name == 'yselected'){
  650. __method.calendar_startDate.setYear($(this).text()*1 , 1);
  651. //__method.calendar_startDate.setMonth(__method.str2date($('#'+__method.startDateId).val()).getMonth(), 1);
  652. }
  653. else if(name='mselected'){
  654. //__method.calendar_startDate.setYear(__method.str2date($('#'+__method.startDateId).val()).getFullYear(), 1);
  655. __method.calendar_startDate.setMonth($(this).text()*1-1, 1);
  656. }
  657. __method.mOpts.startDate = __method.date2ymd(__method.calendar_startDate).join('-');
  658. nt = __method.fillDate(__method.calendar_startDate.getFullYear(), __method.calendar_startDate.getMonth(), idx);
  659. }
  660. else{
  661. //结束
  662. if(name == 'yselected'){
  663. __method.calendar_endDate.setYear($(this).text()*1 , 1);
  664. //__method.calendar_endDate.setMonth(__method.str2date($('#'+__method.endDateId).val()).getMonth(), 1);
  665. }
  666. else if(name='mselected'){
  667. //__method.calendar_endDate.setYear(__method.str2date($('#'+__method.endDateId).val()).getFullYear(), 1);
  668. __method.calendar_endDate.setMonth($(this).text()*1-1, 1);
  669. }
  670. __method.mOpts.endDate = __method.date2ymd(__method.calendar_endDate).join('-');
  671. nt = __method.fillDate(__method.calendar_endDate.getFullYear(), __method.calendar_endDate.getMonth(), idx);
  672. }
  673. var tb = $("#" + __method.dateListId).find('table').get(idx^1);
  674. $(tb).replaceWith(nt);
  675. //}
  676. __method.removeCSS(0);
  677. __method.bindChangeForSelect();
  678. });
  679. });
  680. }
  681. });
  682. }catch(e){
  683. window.console && console.log(e);
  684. }
  685. }
  686. /**
  687. * @description 计算今天,昨天,最近7天,最近30天返回的时间范围
  688. * @param {Num} period 快捷选择的时间段,今天、昨天、最近7天、最近30天
  689. */
  690. pickerDateRange.prototype.getSpecialPeriod = function(period){
  691. var __method = this;
  692. var date = new Date();
  693. //如果今天不可用,则从昨天向前推 added by johnnyzheng 12-07
  694. (true == __method.mOpts.isTodayValid && ('' != __method.mOpts.isTodayValid) || 2 > period)? '' : date.setTime(date.getTime() - ( 1 * 24 * 60 * 60 * 1000));
  695. var timeStamp = ((date.getTime()- ( period * 24 * 60 * 60 * 1000)) < (__method.mOpts.minValidDate * 1000)) ? (__method.mOpts.minValidDate * 1000) : (date.getTime()- ( period * 24 * 60 * 60 * 1000)) ;
  696. var todayStr = date.getFullYear() + '-' + (date.getMonth()+ 1 ) + '-' + date.getDate();
  697. date.setTime(timeStamp);
  698. var otherdayStr = date.getFullYear() + '-' + (date.getMonth()+ 1 ) + '-' + date.getDate();
  699. if(period == __method.periodObj.aYesterday){
  700. todayStr = otherdayStr;
  701. }
  702. return {today: todayStr , otherday : otherdayStr};
  703. }
  704. pickerDateRange.prototype.getCurrentDate = function(){
  705. return {
  706. 'startDate': $('#' + this.mOpts.startDateId).val(),
  707. 'endDate': $('#' + this.mOpts.endDateId).val(),
  708. 'needCompare' : $('#' + this.mOpts.compareCheckboxId).val(),
  709. 'startCompareDate':$('#' + this.mOpts.startCompareDateId).val(),
  710. 'endCompareDate':$('#' + this.mOpts.endCompareDateId).val()
  711. };
  712. };
  713. /**
  714. * @description 移除选择日期面板的样式
  715. * @param {Boolean} isCompare 是否是对比日期面板
  716. * @param {String} specialClass 特殊的样式,这里默认是常规和对比日期两种样式的重合样式
  717. */
  718. pickerDateRange.prototype.removeCSS = function(isCompare, specialClass) {
  719. // 初始化对比时间重合部分的样式类
  720. if('undefined' == typeof(specialClass)) {
  721. specialClass = this.mOpts.theme + '_' + this.mOpts.coincideCss;
  722. }
  723. // 是否移除对比部分的样式:0 日期选择;1 对比日期选择
  724. if('undefined' == typeof(isCompare)) {
  725. isCompare = 0;
  726. }
  727. // 整个日期列表的开始日期
  728. var s_date = this.calendar_startDate;
  729. var e_date = this.calendar_endDate;
  730. //如果是用户自定义选择的话,需要充值样式边界日期
  731. if(this.mOpts.magicSelect){
  732. s_date = this.str2date($('#'+this.startDateId).val());
  733. e_date = this.str2date($('#'+this.endDateId).val());
  734. }
  735. var bDate = new Date(s_date.getFullYear(), s_date.getMonth(), s_date.getDate());
  736. var cla = '';
  737. // 从开始日期循环到结束日期
  738. for(var d = new Date(bDate); d.getTime() <= e_date.getTime(); d.setDate(d.getDate() + 1)) {
  739. if(0 == isCompare) {
  740. // 移除日期样式
  741. cla = this.mOpts.theme + '_' + this.mOpts.selectCss;
  742. } else {
  743. // 移除对比日期样式
  744. cla = this.mOpts.theme + '_' + this.mOpts.compareCss;
  745. }
  746. // 移除指定样式
  747. $('#'+ this.calendarId + '_' + this.date2ymd(d).join('-')).removeClass(cla);
  748. $('#'+ this.calendarId + '_' + this.date2ymd(d).join('-')).removeClass(this.mOpts.firstCss).removeClass(this.mOpts.lastCss).removeClass(this.mOpts.clickCss);
  749. }
  750. };
  751. /**
  752. * @description 为选中的日期加上样式:1=比较时间;0=时间范围
  753. * @param {Boolean} isCompare 是否是对比日期面板
  754. * @param {String} specialClass 特殊的样式,这里默认是常规和对比日期两种样式的重合样式
  755. */
  756. pickerDateRange.prototype.addCSS = function(isCompare, specialClass) {
  757. // 初始化对比时间重合部分的样式类
  758. if('undefined' == typeof(specialClass)) {
  759. specialClass = this.mOpts.theme + '_' + this.mOpts.coincideCss;
  760. }
  761. // 是否移除对比部分的样式:0 日期选择;1 对比日期选择
  762. if('undefined' == typeof(isCompare)) {
  763. isCompare = 0;
  764. }
  765. // 获取4个日期
  766. var startDate = this.str2date($('#' + this.startDateId).val());
  767. var endDate = this.str2date($('#' + this.endDateId).val());
  768. var startCompareDate = this.str2date($('#' + this.startCompareDateId).val());
  769. var endCompareDate = this.str2date($('#' + this.endCompareDateId).val());
  770. // 循环开始日期
  771. var sDate = 0 == isCompare ? startDate : startCompareDate;
  772. // 循环结束日期
  773. var eDate = 0 == isCompare ? endDate : endCompareDate;
  774. var cla = '';
  775. for(var d = new Date(sDate); d.getTime() <= eDate.getTime(); d.setDate(d.getDate() + 1)) {
  776. if(0 == isCompare) {
  777. // 添加日期样式
  778. cla = this.mOpts.theme + '_' + this.mOpts.selectCss;
  779. $('#' + this.calendarId + '_' + this.date2ymd(d).join('-')).removeClass(this.mOpts.firstCss).removeClass(this.mOpts.lastCss).removeClass(this.mOpts.clickCss);
  780. $('#' + this.calendarId + '_' + this.date2ymd(d).join('-')).removeClass(cla);
  781. } else {
  782. // 添加对比日期样式
  783. cla = this.mOpts.theme + '_' + this.mOpts.compareCss;
  784. }
  785. $('#' + this.calendarId + '_' + this.date2ymd(d).join('-')).attr('class', cla);
  786. }
  787. if(this.mOpts.theme == 'ta'){
  788. //为开始结束添加特殊样式
  789. $('#' + this.calendarId + '_' + this.date2ymd(new Date(sDate)).join('-')).removeClass().addClass(this.mOpts.firstCss);
  790. $('#' + this.calendarId + '_' + this.date2ymd(new Date(eDate)).join('-')).removeClass().addClass(this.mOpts.lastCss);
  791. //如果开始结束时间相同
  792. sDate.getTime() == eDate.getTime() && $('#'+ this.calendarId + '_' + this.date2ymd(new Date(eDate)).join('-')).removeClass().addClass(this.mOpts.clickCss);
  793. }
  794. };
  795. /**
  796. * @description 判断开始、结束日期是否处在允许的范围内
  797. * @param {String} startYmd 开始时间字符串
  798. * @param {String} endYmd 结束时间字符串
  799. */
  800. pickerDateRange.prototype.checkDateRange = function(startYmd, endYmd) {
  801. var sDate = this.str2date(startYmd);
  802. var eDate = this.str2date(endYmd);
  803. var sTime = sDate.getTime();
  804. var eTime = eDate.getTime();
  805. var minEDate, maxEDate;
  806. if(eTime >= sTime) {
  807. // 判断是否超过最大日期外
  808. maxEDate = this.str2date(startYmd);
  809. maxEDate.setMonth(maxEDate.getMonth() + this.mOpts.monthRangeMax);
  810. maxEDate.setDate(maxEDate.getDate() + this.mOpts.dayRangeMax - 1);
  811. if(maxEDate.getTime() < eTime) {
  812. alert('结束日期不能大于:' + this.date2ymd(maxEDate).join('-'));
  813. return false;
  814. }
  815. } else {
  816. // 判断是否超过最大日期外
  817. //maxEDate = this.str2date(stPartYmd);
  818. maxEDate = this.str2date(endYmd);
  819. maxEDate.setMonth(maxEDate.getMonth() - this.mOpts.monthRangeMax);
  820. maxEDate.setDate(maxEDate.getDate() - this.mOpts.dayRangeMax + 1);
  821. if(maxEDate.getTime() > eTime) {
  822. alert('开始日期不能小于:' + this.date2ymd(maxEDate).join('-'));
  823. return false;
  824. }
  825. }
  826. return true;
  827. }
  828. /**
  829. * @description 选择日期
  830. * @param {String} ymd 时间字符串
  831. */
  832. pickerDateRange.prototype.selectDate = function(ymd) {
  833. //点击日期点的时候添加对应输入框的样式,而不是之前的 聚焦到输入框时显示样式 by zacharycai
  834. this.changeInput(this.dateInput);
  835. // 格式化日期
  836. var ymdFormat = this.formatDate(ymd);
  837. // start <-> end 切换
  838. if(this.startDateId == this.dateInput) {
  839. // 移除样式
  840. this.removeCSS(0);
  841. this.removeCSS(1);
  842. // 为当前点加样式
  843. $('#'+ this.calendarId + '_' + ymd).attr('class', (this.mOpts.theme == 'ta' ? this.mOpts.clickCss : this.mOpts.theme + '_' + this.mOpts.selectCss));
  844. // 获取开始时间的初始值
  845. this.startDefDate = $('#' + this.dateInput).val();
  846. // 更改对应输入框的值
  847. $('#' + this.dateInput).val(ymdFormat);
  848. // 切换输入框焦点,如果是实时数据那么选择一天的数据
  849. if (true == this.mOpts.singleCompare || true == this.mOpts.isSingleDay) {
  850. this.dateInput = this.startDateId;
  851. $('#' + this.endDateId).val(ymdFormat);
  852. (this.mOpts.shortOpr || this.mOpts.autoSubmit) && this.close(1);
  853. this.mOpts.success({'startDate': $('#' + this.mOpts.startDateId).val(),
  854. 'endDate': $('#' + this.mOpts.endDateId).val(),
  855. 'needCompare' : $('#' + this.mOpts.compareCheckboxId).val(),
  856. 'startCompareDate':$('#' + this.mOpts.startCompareDateId).val(),
  857. 'endCompareDate':$('#' + this.mOpts.endCompareDateId).val()
  858. });
  859. } else {
  860. this.dateInput = this.endDateId;
  861. }
  862. } else if(this.endDateId == this.dateInput) {
  863. // 如果开始时间未选
  864. if('' == $('#' + this.startDateId).val()) {
  865. this.dateInput = this.startDateId;
  866. this.selectDate(ymd);
  867. return false;
  868. }
  869. // 判断用户选择的时间范围
  870. if(false == this.checkDateRange($('#' + this.startDateId).val(), ymd)) {
  871. return false;
  872. }
  873. // 如果结束时间小于开始时间
  874. if(-1 == this.compareStrDate(ymd, $('#' + this.startDateId).val())) {
  875. // 更改对应输入框的值(结束时间)
  876. $('#' + this.dateInput).val($('#' + this.startDateId).val());
  877. // 更改对应输入框的值(开始时间)
  878. $('#' + this.startDateId).val(ymdFormat);
  879. ymdFormat = $('#' + this.dateInput).val();
  880. }
  881. // 更改对应输入框的值
  882. $('#' + this.dateInput).val(ymdFormat);
  883. // 切换输入框焦点
  884. this.dateInput = this.startDateId;
  885. this.removeCSS(0);
  886. this.addCSS(0);
  887. //this.addCSS(0, this.mOpts.coincideCss);
  888. this.startDefDate = '';
  889. if(this.mOpts.autoSubmit){
  890. this.close(1);
  891. this.mOpts.success({'startDate': $('#' + this.mOpts.startDateId).val(),
  892. 'endDate': $('#' + this.mOpts.endDateId).val(),
  893. 'needCompare' : $('#' + this.mOpts.compareCheckboxId).val(),
  894. 'startCompareDate':$('#' + this.mOpts.startCompareDateId).val(),
  895. 'endCompareDate':$('#' + this.mOpts.endCompareDateId).val()
  896. });
  897. }
  898. } else if(this.startCompareDateId == this.dateInput) {
  899. // 移除样式
  900. this.removeCSS(1);
  901. this.removeCSS(0);
  902. // 为当前点加样式
  903. $('#'+ this.calendarId + '_' + ymd).attr('class', (this.mOpts.theme == 'ta' ? this.mOpts.clickCss : this.mOpts.theme + '_' + this.mOpts.compareCss));
  904. // 获取开始时间的初始值
  905. this.startDefDate = $('#' + this.dateInput).val();
  906. // 更改对应输入框的值
  907. $('#' + this.dateInput).val(ymdFormat);
  908. // 切换输入框焦点
  909. if (true == this.mOpts.singleCompare || true == this.mOpts.isSingleDay) {
  910. this.dateInput = this.startCompareDateId;
  911. $('#' + this.endCompareDateId).val(ymdFormat);
  912. (this.mOpts.shortOpr || this.mOpts.autoSubmit) && this.close(1);
  913. this.mOpts.success({'startDate': $('#' + this.mOpts.startDateId).val(),
  914. 'endDate': $('#' + this.mOpts.endDateId).val(),
  915. 'needCompare' : $('#' + this.mOpts.compareCheckboxId).val(),
  916. 'startCompareDate':$('#' + this.mOpts.startCompareDateId).val(),
  917. 'endCompareDate':$('#' + this.mOpts.endCompareDateId).val()
  918. });
  919. }
  920. else{
  921. this.dateInput = this.endCompareDateId;
  922. }
  923. } else if(this.endCompareDateId == this.dateInput) {
  924. // 如果开始时间未选
  925. if('' == $('#' + this.startCompareDateId).val()) {
  926. this.dateInput = this.startCompareDateId;
  927. this.selectDate(ymd);
  928. return false;
  929. }
  930. // 判断用户选择的时间范围
  931. if(false == this.checkDateRange($('#' + this.startCompareDateId).val(), ymd)) {
  932. return false;
  933. }
  934. // 如果结束时间小于开始时间
  935. if(-1 == this.compareStrDate(ymd, $('#' + this.startCompareDateId).val())) {
  936. // 更改对应输入框的值(结束时间)
  937. $('#' + this.dateInput).val($('#' + this.startCompareDateId).val());
  938. // 更改对应输入框的值(开始时间)
  939. $('#' + this.startCompareDateId).val(ymdFormat);
  940. ymdFormat = $('#' + this.dateInput).val();
  941. }
  942. // 更改对应输入框的值
  943. $('#' + this.dateInput).val(ymdFormat);
  944. // 切换输入框焦点
  945. this.dateInput = this.startCompareDateId;
  946. //this.addCSS(1, this.mOpts.coincideCss);
  947. this.removeCSS(1);
  948. this.addCSS(1);
  949. this.startDefDate = '';
  950. if(this.mOpts.autoSubmit){
  951. this.close(1);
  952. this.mOpts.success({'startDate': $('#' + this.mOpts.startDateId).val(),
  953. 'endDate': $('#' + this.mOpts.endDateId).val(),
  954. 'needCompare' : $('#' + this.mOpts.compareCheckboxId).val(),
  955. 'startCompareDate':$('#' + this.mOpts.startCompareDateId).val(),
  956. 'endCompareDate':$('#' + this.mOpts.endCompareDateId).val()
  957. });
  958. }
  959. }
  960. // 切换到下一个输入框
  961. // this.changeInput(this.dateInput);
  962. };
  963. /**
  964. * @description显示日期选择框
  965. * @param {Boolean} isCompare 是否是对比日期选择框
  966. * @param {Object} __method 时期选择器超级对象
  967. */
  968. pickerDateRange.prototype.show = function(isCompare, __method) {
  969. $('#' + __method.dateRangeDiv).css('display', isCompare ? 'none' : '');
  970. $('#' + __method.dateRangeCompareDiv).css('display', isCompare ? '' : 'none');
  971. var pos = isCompare ? $('#' + this.inputCompareId).offset() : $('#' + this.inputId).offset();
  972. var offsetHeight = isCompare ? $('#' + this.inputCompareId).height() : $('#' + this.inputId).height();
  973. var clientWidth = parseInt($(document.body)[0].clientWidth);
  974. var left = pos.left;
  975. $("#" + this.calendarId).css('display', 'block');
  976. if (true == this.mOpts.singleCompare || true == this.mOpts.isSingleDay) {
  977. $('#' + this.endDateId).css('display', 'none');
  978. $('#' + this.endCompareDateId).css('display','none');
  979. $('#' + this.mOpts.joinLineId).css('display', 'none');
  980. $('.' + this.mOpts.joinLineId).css('display', 'none');
  981. }
  982. // 如果和输入框左对齐时超出了宽度范围,则右对齐
  983. if(0 < clientWidth && $("#" + this.calendarId).width() + pos.left > clientWidth) {
  984. left = pos.left + $('#' + this.inputId).width() - $("#" + this.calendarId).width() + ((/msie/i.test(navigator.userAgent) && !(/opera/i.test(navigator.userAgent)))? 5 : 0) ;
  985. __method.mOpts.theme=='ta' && (left += 50);
  986. }
  987. $("#" + this.calendarId).css('left', left + 'px');
  988. //$("#" + this.calendarId).css('top', pos.top + (offsetHeight ? offsetHeight- 1 : (__method.mOpts.theme=='ta'?35:22)) + 'px');
  989. $("#" + this.calendarId).css('top', pos.top + (__method.mOpts.theme=='ta'?35:30) + 'px');
  990. //第一次显示的时候,一定要初始化输入框
  991. isCompare ? this.changeInput(this.startCompareDateId) : this.changeInput(this.startDateId);
  992. return false;
  993. };
  994. /**
  995. * @description 关闭日期选择框
  996. * @param {Boolean} btnSubmit 是否是点击确定按钮关闭的
  997. */
  998. pickerDateRange.prototype.close = function(btnSubmit) {
  999. var __method = this;
  1000. //by zacharycai 关闭后就解绑了
  1001. //$(document).unbind('click');
  1002. // 把开始、结束时间显示到输入框 (PS:如果选择的今日,昨日,则只填入一个日期)
  1003. // 如果开始和结束同个时间也照样分段by zacharycai
  1004. //$('#' + this.inputId).val($('#' + this.startDateId).val() + ($('#' + this.startDateId).val() == $('#' + this.endDateId).val() ? '' : this.mOpts.defaultText + $('#' + this.endDateId).val()));
  1005. if(btnSubmit){
  1006. //如果是单日快捷选择
  1007. if (this.mOpts.shortOpr === true){
  1008. $('#' + this.inputId).val($('#' + this.startDateId).val());
  1009. $('#' + this.inputCompareId).val($('#' + this.startCompareDateId).val());
  1010. }else{
  1011. $('#' + this.inputId).val($('#' + this.startDateId).val() + ('' == $('#' + this.endDateId).val() ? '' : this.mOpts.defaultText + $('#' + this.endDateId).val()));
  1012. }
  1013. //判断当前天是否可选,来决定从后往前推修改日期是从哪一点开始
  1014. var nDateTime = ((true == this.mOpts.isTodayValid && '' != this.mOpts.isTodayValid)) ? new Date().getTime() : new Date().getTime() - (1 * 24 * 60 * 60 * 1000);
  1015. var bDateTime = this.str2date($('#' + this.startDateId).val()).getTime();
  1016. var eDateTime = this.str2date($('#' + this.endDateId).val()).getTime();
  1017. //如果endDateTime小于bDateTime 相互交换
  1018. if(eDateTime < bDateTime){
  1019. var tmp = $('#' + this.startDateId).val();
  1020. $('#' + this.startDateId).val($('#' + this.endDateId).val());
  1021. $('#' + this.endDateId).val(tmp);
  1022. }
  1023. var _val = this.mOpts.shortOpr == true ? $('#' + this.startDateId).val() : ($('#' + this.startDateId).val() + ('' == $('#' + this.endDateId).val() ? '' : this.mOpts.defaultText + $('#' + this.endDateId).val()));
  1024. // 把开始、结束时间显示到输入框 (PS:如果选择的今日,昨日,则只填入一个日期)
  1025. var input = document.getElementById(this.inputId);
  1026. if(input && input.tagName == 'INPUT'){
  1027. $('#' + this.inputId).val(_val);
  1028. $('#'+this.inputCompareId).is(':visible') && $('#'+this.inputCompareId).val(_compareVal);
  1029. }else{
  1030. $('#' + this.inputId).html(_val);
  1031. $('#'+this.inputCompareId).is(':visible') && $('#'+this.inputCompareId).html(_compareVal);
  1032. }
  1033. // //在js侧就做好日期校准,以前面的日期选择的跨度为准,如果后面的跨度超过了当前可用时间,则以当前可用时间向前推 added by johnnyzheng 11-29
  1034. if(this.mOpts.theme != 'ta'){
  1035. if('' != $('#' + this.startCompareDateId).val() && '' != $('#' + this.endCompareDateId).val()){
  1036. var bcDateTime = this.str2date($('#' + this.startCompareDateId).val()).getTime();
  1037. var ecDateTime = this.str2date($('#' + this.endCompareDateId).val()).getTime();
  1038. var _ecDateTime = bcDateTime + eDateTime - bDateTime;
  1039. if(_ecDateTime > nDateTime){
  1040. //如果计算得到的时间超过了当前可用时间,那么就和服务器端保持一致,将当前可用的天数向前推日期选择器的跨度 added by johnnyzheng 11-29
  1041. _ecDateTime = nDateTime;
  1042. $('#' + this.startCompareDateId).val(this.formatDate(this.date2ymd(new Date(_ecDateTime + bDateTime - eDateTime)).join('-')));
  1043. }
  1044. $('#' + this.endCompareDateId).val(this.formatDate(this.date2ymd(new Date(_ecDateTime)).join('-')));
  1045. //把开始结束对比时间大小重新矫正一下
  1046. var bcDateTime = this.str2date($('#' + this.startCompareDateId).val()).getTime();
  1047. var ecDateTime = this.str2date($('#' + this.endCompareDateId).val()).getTime();
  1048. if(ecDateTime < bcDateTime){
  1049. var tmp = $('#' + this.startCompareDateId).val();
  1050. $('#' + this.startCompareDateId).val($('#' + this.endCompareDateId).val());
  1051. $('#' + this.endCompareDateId).val(tmp);
  1052. }
  1053. }
  1054. }
  1055. //把对比时间填入输入框 (PS:如果选择今日,昨日,则只填入一个日期)
  1056. //$('#' + this.inputCompareId).val($('#' + this.startCompareDateId).val() + this.mOpts.defaultText + $('#' + this.endCompareDateId).val());
  1057. var _compareVal = this.mOpts.shortOpr == true ? $('#' + this.startCompareDateId).val() : ($('#' + this.startCompareDateId).val() + ('' == $('#' + this.endCompareDateId).val() ? '' : this.mOpts.defaultText + $('#' + this.endCompareDateId).val()));
  1058. if(input && input.tagName == 'INPUT'){
  1059. $('#' + this.inputCompareId).val(_compareVal);
  1060. }else{
  1061. $('#' + this.inputCompareId).html(_compareVal);
  1062. }
  1063. // 计算相隔天数
  1064. var step = (bDateTime - eDateTime) / 86400000;
  1065. // 更改目标元素值
  1066. $('#' + this.mOpts.startDateId).val($('#' + this.startDateId).val());
  1067. $('#' + this.mOpts.endDateId).val($('#' + this.endDateId).val());
  1068. $('#' + this.mOpts.startCompareDateId).val($('#' + this.startCompareDateId).val());
  1069. $('#' + this.mOpts.endCompareDateId).val($('#' + this.endCompareDateId).val());
  1070. //点击确定按钮进行查询后将取消所有的今天 昨天 最近7天的快捷链接 added by johnnyzheng 11-29
  1071. for(var property in this.periodObj){
  1072. if($('#' + this.mOpts[property])){
  1073. $('#' + this.mOpts[property]).parent().removeClass('a');
  1074. }
  1075. }
  1076. }
  1077. // 隐藏日期选择框 延迟200ms 关闭日期选择框
  1078. $("#" + __method.calendarId).css('display', 'none');
  1079. return false;
  1080. };
  1081. /**
  1082. * @description 日期填充函数
  1083. * @param {Num} year 年
  1084. * @param {Num} month 月
  1085. */
  1086. pickerDateRange.prototype.fillDate = function(year, month, index) {
  1087. var __method = this;
  1088. var isTaTheme = this.mOpts.theme == 'ta';
  1089. // 当月第一天
  1090. var firstDayOfMonth = new Date(year, month, 1);
  1091. var dateBegin = new Date(year, month, 1);
  1092. var w = dateBegin.getDay();
  1093. // 计算应该开始的日期
  1094. dateBegin.setDate(1 - w);
  1095. // 当月最后一天
  1096. var lastDayOfMonth = new Date(year, month + 1, 0);
  1097. var dateEnd = new Date(year, month + 1, 0);
  1098. w = dateEnd.getDay();
  1099. // 计算应该结束的日期
  1100. dateEnd.setDate(dateEnd.getDate() + 6 - w);
  1101. var today = new Date();
  1102. var dToday = today.getDate();
  1103. var mToday = today.getMonth();
  1104. var yToday = today.getFullYear();
  1105. var table = document.createElement('table');
  1106. if(isTaTheme){
  1107. table.className = this.mOpts.dateTable;
  1108. cap = document.createElement('caption');
  1109. //如果是magicSelect,用户自定义的选择年和月份
  1110. if(this.mOpts.magicSelect){
  1111. var yh = ['<div class="select_wrap" id="yselected_'+index+'"><div class="select" id="_ybtn_'+index+'">'+year+'</div><div class="dropdown" id="_yctn_'+index+'"><ul class="list_menu">']
  1112. var mh = ['<div class="select_wrap" id="mselected_'+index+'"><div class="select" id="_mbtn_'+index+'">'+(month+1)+'</div><div class="dropdown" id="_mctn_'+index+'"><ul class="list_menu">']
  1113. //var yh = ['<select name="yselected_'+index+'" class="xxxs">'];
  1114. //var mh = ['<select name="mselected_'+index+'" class="xxxs">'];
  1115. i=1;
  1116. yt = yToday;
  1117. do{
  1118. //yh.push('<option value="'+yt+'" '+(yt == year? 'selected' : '')+'>'+(yt--)+'</option>');
  1119. //mh.push('<option value="'+i+'" '+(i == (month+1)? 'selected' : '')+'>'+(i++)+'</option>');
  1120. yh.push('<li><a href="javascript:;">'+(yt--)+'</a></li>');
  1121. mh.push('<li><a href="javascript:;">'+(i++)+'</a></li>');
  1122. }while(i <= 12);
  1123. //yh.push('</select>');
  1124. //mh.push('</select>');
  1125. yh.push('</ul></div></div>');
  1126. mh.push('</ul></div></div>');
  1127. $(cap).append(yh.join('') +'<span class="joinLine"> 年 </span>'+mh.join('')+'<span class="joinLine"> 月 </span>');
  1128. }
  1129. else{
  1130. $(cap).append(year + '年' + (month + 1) + '月');
  1131. }
  1132. $(table).append(cap);
  1133. thead = document.createElement('thead');
  1134. tr = document.createElement('tr');
  1135. var days = ['日', '一', '二', '三', '四', '五', '六'];
  1136. for(var i = 0; i < 7; i ++) {
  1137. th = document.createElement('th');
  1138. $(th).append(days[i]);
  1139. $(tr).append(th);
  1140. }
  1141. $(thead).append(tr);
  1142. $(table).append(thead);
  1143. tr = document.createElement('tr');
  1144. td = document.createElement('td');
  1145. // 如果是最后一个月的日期,则加上下一个月的链接
  1146. if(!this.mOpts.magicSelect){
  1147. if(0 == index) {
  1148. $(td).append('<a href="javascript:void(0);" id="' + this.nextMonth + '"><i class="i_next"></i></a>');
  1149. }
  1150. // 如果是第一个月的日期,则加上上一个月的链接
  1151. if(index + 1 == this.mOpts.calendars) {
  1152. $(td).append('<a href="javascript:void(0);" id="' + this.preMonth + '"><i class="i_pre"></i></a>');
  1153. }
  1154. }
  1155. // $(td).append('<span style="font-size:16px">' + year + '年' + (month + 1) + '月' + '</span>');
  1156. $(td).attr('colSpan', 7);
  1157. $(td).css('text-align', 'center');
  1158. $(tr).append(td);
  1159. $(table).append(tr);
  1160. }
  1161. else{
  1162. table.className = this.mOpts.theme + '_' + this.mOpts.dateTable;
  1163. tr = document.createElement('tr');
  1164. td = document.createElement('td');
  1165. // 如果是最后一个月的日期,则加上下一个月的链接
  1166. if(0 == index) {
  1167. $(td).append('<a href="javascript:void(0);" id="' + this.nextMonth + '" class="gri_dateRangeNextMonth"><span>next</span></a>');
  1168. }
  1169. // 如果是第一个月的日期,则加上上一个月的链接
  1170. if(index + 1 == this.mOpts.calendars) {
  1171. $(td).append('<a href="javascript:void(0);" id="' + this.preMonth + '" class="gri_dateRangePreMonth"><span>pre</span></a>');
  1172. }
  1173. $(td).append(year + '年' + (month + 1) + '月');
  1174. $(td).attr('colSpan', 7);
  1175. $(td).css('text-align', 'center');
  1176. $(td).css('background-color', '#F9F9F9');
  1177. $(tr).append(td);
  1178. $(table).append(tr);
  1179. var days = ['日', '一', '二', '三', '四', '五', '六'];
  1180. tr = document.createElement('tr');
  1181. for(var i = 0; i < 7; i ++) {
  1182. td = document.createElement('td');
  1183. $(td).append(days[i]);
  1184. $(tr).append(td);
  1185. }
  1186. $(table).append(tr);
  1187. }
  1188. // 当前月的所有日期(包括空白位置填充的日期)
  1189. var tdClass = '', deviation = 0, ymd = '';
  1190. for(var d = dateBegin; d.getTime() <= dateEnd.getTime(); d.setDate(d.getDate() + 1)) {
  1191. if(d.getTime() < firstDayOfMonth.getTime()) { // 当前月之前的日期
  1192. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1193. deviation = '-1';
  1194. } else if(d.getTime() > lastDayOfMonth.getTime()) { // 当前月之后的日期
  1195. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1196. deviation = '1';
  1197. } else if((this.mOpts.stopToday == true && d.getTime() > today.getTime()) || d.getTime() < __method.mOpts.minValidDate * 1000 || ('' !== __method.mOpts.maxValidDate && d.getTime() > __method.mOpts.maxValidDate * 1000)) { // 当前时间之后的日期,或者开启统计之前的日期
  1198. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1199. deviation = '2';
  1200. } else { // 当前月日期
  1201. deviation = '0';
  1202. if(d.getDate() == dToday && d.getMonth() == mToday && d.getFullYear() == yToday) {
  1203. if (true == this.mOpts.isTodayValid) {
  1204. tdClass = this.mOpts.theme + '_' + this.mOpts.isToday;
  1205. } else {
  1206. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1207. deviation = '2';
  1208. }
  1209. }
  1210. else {
  1211. tdClass = '';
  1212. }
  1213. //让周末不可选不可选
  1214. if(this.mOpts.weekendDis && (d.getDay()==6 || d.getDay()==0)){
  1215. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1216. deviation = '3';
  1217. }
  1218. //让周几不可选
  1219. if(this.mOpts.disCertainDay && this.mOpts.disCertainDay.length > 0 ){
  1220. for(var p in this.mOpts.disCertainDay){
  1221. if(!isNaN(this.mOpts.disCertainDay[p]) && d.getDay() === this.mOpts.disCertainDay[p]){
  1222. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1223. deviation = '4';
  1224. }
  1225. }
  1226. }
  1227. //让几号不可选
  1228. if(this.mOpts.disCertainDate && this.mOpts.disCertainDate.length > 0 ){
  1229. var isDisabled = false;
  1230. for(var p in this.mOpts.disCertainDate){
  1231. if(!isNaN(this.mOpts.disCertainDate[p]) || isNaN(parseInt(this.mOpts.disCertainDate[p]))){
  1232. if ( this.mOpts.disCertainDate[0] === true ){
  1233. isDisabled = !!(d.getDate() !== this.mOpts.disCertainDate[p]);
  1234. if ( !isDisabled ){
  1235. break;
  1236. }
  1237. }else {
  1238. isDisabled = !!(d.getDate() === this.mOpts.disCertainDate[p]);
  1239. if ( isDisabled ){
  1240. break;
  1241. }
  1242. }
  1243. }
  1244. }
  1245. if ( isDisabled ){
  1246. tdClass = this.mOpts.theme + '_' + this.mOpts.disableGray;
  1247. deviation = '4';
  1248. }
  1249. }
  1250. }
  1251. // 如果是周日
  1252. if(0 == d.getDay()) {
  1253. tr = document.createElement('tr');
  1254. }
  1255. td = document.createElement('td');
  1256. td.innerHTML = d.getDate();
  1257. if('' != tdClass) {
  1258. $(td).attr('class', tdClass);
  1259. }
  1260. // 只有当前月可以点击
  1261. if(0 == deviation) {
  1262. ymd = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate();
  1263. $(td).attr('id', __method.calendarId + '_' + ymd);
  1264. $(td).css('cursor','pointer');
  1265. (function(ymd) {
  1266. $(td).bind("click", ymd, function() {
  1267. __method.selectDate(ymd);
  1268. return false;
  1269. });
  1270. })(ymd);
  1271. }
  1272. $(tr).append(td);
  1273. // 如果是周六
  1274. if(6 == d.getDay()) {
  1275. $(table).append(tr);
  1276. }
  1277. }
  1278. return table;
  1279. };
  1280. /**
  1281. * @description 把时间字串转成时间格式
  1282. * @param {String} str 时间字符串
  1283. */
  1284. pickerDateRange.prototype.str2date = function(str) {
  1285. var ar = str.split('-');
  1286. // 返回日期格式
  1287. return new Date(ar[0], ar[1] - 1, ar[2]);
  1288. };
  1289. /**
  1290. * @description 比较两个时间字串的大小:1 大于; 0 等于; -1 小于
  1291. * @param {String} b 待比较时间串1
  1292. * @param {String} e 待比较时间串2
  1293. */
  1294. pickerDateRange.prototype.compareStrDate = function(b, e) {
  1295. var bDate = this.str2date(b);
  1296. var eDate = this.str2date(e);
  1297. // 1 大于; 0 等于; -1 小于
  1298. if(bDate.getTime() > eDate.getTime()) {
  1299. return 1;
  1300. } else if(bDate.getTime() == eDate.getTime()) {
  1301. return 0;
  1302. } else {
  1303. return -1;
  1304. }
  1305. };
  1306. /**
  1307. * @description 把时间格式转成对象
  1308. * @param {Date} d 时间
  1309. */
  1310. pickerDateRange.prototype.date2ymd = function(d) {
  1311. return [d.getFullYear(), (d.getMonth() + 1), d.getDate()];
  1312. };
  1313. /**
  1314. * @description 切换焦点到当前输入框
  1315. * @param {String} 日期框体ID
  1316. */
  1317. pickerDateRange.prototype.changeInput = function(ipt) {
  1318. // 强制修改为开始输入框
  1319. if (true == this.mOpts.isSingleDay) {
  1320. ipt = this.startDateId;
  1321. }
  1322. // 所有4个输入框
  1323. var allInputs = [this.startDateId, this.startCompareDateId, this.endDateId, this.endCompareDateId];
  1324. // 如果 ipt 是日期输入框,则为日期样式,否则为对比日期样式
  1325. var cla = '';
  1326. if(ipt == this.startDateId || ipt == this.endDateId) {
  1327. cla = this.mOpts.theme + '_' + this.mOpts.selectCss;
  1328. } else {
  1329. cla = this.mOpts.theme + '_' + this.mOpts.compareCss;
  1330. }
  1331. if(ipt == this.endDateId && this.mOpts.singleCompare) {
  1332. cla = this.mOpts.theme + '_' + this.mOpts.compareCss;
  1333. }
  1334. // 移除所有输入框的附加样式
  1335. for(var i in allInputs) {
  1336. $('#' + allInputs[i]).removeClass(this.mOpts.theme + '_' + this.mOpts.selectCss);
  1337. $('#' + allInputs[i]).removeClass(this.mOpts.theme + '_' + this.mOpts.compareCss);
  1338. }
  1339. // 为指定输入框添加样式
  1340. $('#' + ipt).addClass(cla);
  1341. //背景图repeat
  1342. $('#' + ipt).css('background-repeat', 'repeat');
  1343. // 把输入焦点移到指定输入框
  1344. this.dateInput = ipt;
  1345. };
  1346. /**
  1347. * @description 日期格式化,加前导零
  1348. */
  1349. pickerDateRange.prototype.formatDate = function(ymd) {
  1350. return ymd.replace(/(\d{4})\-(\d{1,2})\-(\d{1,2})/g, function(ymdFormatDate, y, m, d){
  1351. if(m < 10){
  1352. m = '0' + m;
  1353. }
  1354. if(d < 10){
  1355. d = '0' + d;
  1356. }
  1357. return y + '-' + m + '-' + d;
  1358. });
  1359. };