1;(function(){ 2 3if (BX.date) 4 return; 5 6BX.date = BX.Main.Date; 7 8/************************************** calendar class **********************************/ 9 10var obCalendarSingleton = null; 11 12/* 13params: { 14 node: bind element || document.body 15 16 value - start value in site format (using 'field' param if 'value' does not exist) 17 callback - date check handler. can return false to prevent calendar closing. 18 callback_after - another handler, called after date picking 19 20 field - field to read/write data 21 22 bTime = true - whether to enable time control 23 bHideTime = false - whether to hide time control by default 24 25 currentTime - current UTC time() 26 27} 28*/ 29 30 31BX.calendar = function(params) 32{ 33 return BX.calendar.get().Show(params); 34}; 35 36BX.calendar.get = function() 37{ 38 if (!obCalendarSingleton) 39 obCalendarSingleton = new BX.JCCalendar(); 40 41 return obCalendarSingleton; 42}; 43 44// simple func for compatibility with the oldies 45BX.calendar.InsertDaysBack = function(input, days) 46{ 47 if (days != '') 48 { 49 var d = new Date(); 50 if(days > 0) 51 { 52 d.setTime(d.valueOf() - days*86400000); 53 } 54 55 input.value = BX.date.format(BX.date.convertBitrixFormat(BX.message('FORMAT_DATE')), d, null); 56 } 57 else 58 { 59 input.value = ''; 60 } 61}; 62 63BX.calendar.ValueToString = function(value, bTime, bUTC) 64{ 65 return BX.date.format( 66 BX.date.convertBitrixFormat(BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE')), 67 value, 68 null, 69 !!bUTC 70 ); 71}; 72 73BX.calendar.ValueToStringFormat = function(value, bitrixFormat, bUTC) 74{ 75 return BX.date.format( 76 BX.date.convertBitrixFormat(bitrixFormat), 77 value, 78 null, 79 !!bUTC 80 ); 81}; 82 83 84BX.CalendarPeriod = 85{ 86 Init: function(inputFrom, inputTo, selPeriod) 87 { 88 if((inputFrom.value != "" || inputTo.value != "") && selPeriod.value == "") 89 selPeriod.value = "interval"; 90 91 selPeriod.onchange(); 92 }, 93 94 ChangeDirectOpts: function(peroidValue, selPParent) // "week" || "others" 95 { 96 var selDirect = BX.findChild(selPParent, {'className':'adm-select adm-calendar-direction'}, true); 97 98 if(peroidValue == "week") 99 { 100 selDirect.options[0].text = BX.message('JSADM_CALEND_PREV_WEEK'); 101 selDirect.options[1].text = BX.message('JSADM_CALEND_CURR_WEEK'); 102 selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT_WEEK'); 103 } 104 else 105 { 106 selDirect.options[0].text = BX.message('JSADM_CALEND_PREV'); 107 selDirect.options[1].text = BX.message('JSADM_CALEND_CURR'); 108 selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT'); 109 } 110 }, 111 112 SaveAndClearInput: function(oInput) 113 { 114 if(!window.SavedPeriodValues) 115 window.SavedPeriodValues = {}; 116 117 window.SavedPeriodValues[oInput.id] = oInput.value; 118 oInput.value=""; 119 }, 120 121 RestoreInput: function(oInput) 122 { 123 if(!window.SavedPeriodValues || !window.SavedPeriodValues[oInput.id]) 124 return; 125 126 oInput.value = window.SavedPeriodValues[oInput.id]; 127 delete(window.SavedPeriodValues[oInput.id]); 128 }, 129 130 OnChangeP: function(sel) 131 { 132 var selPParent = sel.parentNode.parentNode; 133 var bShowFrom, bShowTo, bShowDirect, bShowSeparate; 134 bShowFrom = bShowTo = bShowDirect = bShowSeparate = false; 135 136 var inputFromWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-inp adm-calendar-first'}); 137 var inputToWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-second'}); 138 var selDirectWrap = BX.findChild(selPParent, {'className':'adm-select-wrap adm-calendar-direction'}); 139 var separator = BX.findChild(selPParent, {'className':'adm-calendar-separate'}); 140 var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true); 141 var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true); 142 143 // define who must be shown 144 switch (sel.value) 145 { 146 case "day": 147 case "week": 148 case "month": 149 case "quarter": 150 case "year": 151 bShowDirect=true; 152 BX.CalendarPeriod.OnChangeD(selDirectWrap.children[0]); 153 break; 154 155 case "before": 156 bShowTo = true; 157 break; 158 159 case "after": 160 bShowFrom = true; 161 break; 162 163 case "exact": 164 bShowFrom= true; 165 break; 166 167 case "interval": 168 bShowFrom = bShowTo = bShowSeparate = true; 169 BX.CalendarPeriod.RestoreInput(inputFrom); 170 BX.CalendarPeriod.RestoreInput(inputTo); 171 172 break; 173 174 case "": 175 BX.CalendarPeriod.SaveAndClearInput(inputFrom); 176 BX.CalendarPeriod.SaveAndClearInput(inputTo); 177 break; 178 179 default: 180 break; 181 182 } 183 184 BX.CalendarPeriod.ChangeDirectOpts(sel.value, selPParent); 185 186 inputFromWrap.style.display = (bShowFrom? 'inline-block':'none'); 187 inputToWrap.style.display = (bShowTo? 'inline-block':'none'); 188 selDirectWrap.style.display = (bShowDirect? 'inline-block':'none'); 189 separator.style.display = (bShowSeparate? 'inline-block':'none'); 190 }, 191 192 193 OnChangeD: function(sel) 194 { 195 var selPParent = sel.parentNode.parentNode; 196 var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true); 197 var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true); 198 var selPeriod = BX.findChild(selPParent, {'className':'adm-select adm-calendar-period'},true); 199 200 var offset=0; 201 202 switch (sel.value) 203 { 204 case "previous": 205 offset = -1; 206 break; 207 208 case "next": 209 offset = 1; 210 break; 211 212 case "current": 213 default: 214 break; 215 216 } 217 218 var from = false;
219 var to = false; 220 221 var today = new Date(); 222 var year = today.getFullYear(); 223 var month = today.getMonth(); 224 var day = today.getDate(); 225 var dayW = today.getDay(); 226 227 if (dayW == 0) 228 dayW = 7; 229 230 switch (selPeriod.value) 231 { 232 case "day": 233 from = new Date(year, month, day+offset, 0, 0, 0); 234 to = new Date(year, month, day+offset, 23, 59, 59); 235 break; 236 237 case "week": 238 from = new Date(year, month, day-dayW+1+offset*7, 0, 0, 0); 239 to = new Date(year, month, day+(7-dayW)+offset*7, 23, 59, 59); 240 break; 241 242 case "month": 243 from = new Date(year, month+offset, 1, 0, 0, 0); 244 to = new Date(year, month+1+offset, 0, 23, 59, 59); 245 break; 246 247 case "quarter": 248 var quarterNum = Math.floor((month/3))+offset; 249 from = new Date(year, 3*(quarterNum), 1, 0, 0, 0); 250 to = new Date(year, 3*(quarterNum+1), 0, 23, 59, 59); 251 break; 252 253 case "year": 254 from = new Date(year+offset, 0, 1, 0, 0, 0); 255 to = new Date(year+1+offset, 0, 0, 23, 59, 59); 256 break; 257 258 default: 259 break; 260 } 261 262 var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE'); 263 264 if(from) 265 { 266 inputFrom.value = BX.formatDate(from, format); 267 BX.addClass(inputFrom,"adm-calendar-inp-setted"); 268 } 269 270 if(to) 271 { 272 inputTo.value = BX.formatDate(to, format); 273 BX.addClass(inputTo,"adm-calendar-inp-setted"); 274 } 275 } 276}; 277 278 279BX.JCCalendar = function() 280{ 281 this.params = {}; 282 283 this.bAmPm = BX.isAmPmMode(); 284 285 this.popup = null; 286 this.popup_month = null; 287 this.popup_year = null; 288 this.month_popup_classname = ''; 289 this.year_popup_classname = ''; 290 this.value = null; 291 this._layers = {}; 292 this._current_layer = null; 293 294 this.DIV = null; 295 this.PARTS = {}; 296 297 this.weekStart = 0; 298 this.numRows = 6; 299 300 this._create = function(params) 301 { 302 const paramsForPopupWindow = { 303 closeByEsc: true, 304 autoHide: false, 305 content: this._get_content(), 306 bindOptions: { forceBindPosition: true }, 307 }; 308 if (Boolean(params.fixed) && params.fixed) 309 { 310 paramsForPopupWindow.fixed = params.fixed; 311 } 312 313 this.popup = new BX.PopupWindow( 314 'calendar_popup_' + Math.random(), 315 params.node, 316 paramsForPopupWindow, 317 ); 318 319 BX.bind(this.popup.popupContainer, 'click', function(event) { 320 event.stopPropagation(); 321 }); 322 }; 323 324 this._auto_hide_disable = function() 325 { 326 BX.unbind(document, 'click', BX.proxy(this._auto_hide, this)); 327 }; 328 329 this._auto_hide_enable = function() 330 { 331 BX.bind(document, 'click', BX.proxy(this._auto_hide, this)); 332 }; 333 334 this._auto_hide = function(e) 335 { 336 this._auto_hide_disable(); 337 this.popup.close(); 338 }; 339 340 this._get_content = function() 341 { 342 var _layer_onclick = BX.delegate(function(e) { 343 e = e||window.event; 344 this.SetDate( 345 new Date(parseInt(BX.proxy_context.getAttribute('data-date'))), 346 (e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility)) 347 ) 348 }, this); 349 350 this.DIV = BX.create('DIV', { 351 props: {className: 'bx-calendar'}, 352 children: [ 353 BX.create('DIV', { 354 props: { 355 className: 'bx-calendar-header' 356 }, 357 children: [ 358 BX.create('A', { 359 attrs: {href: 'javascript:void(0)'}, 360 props: {className: 'bx-calendar-left-arrow'}, 361 events: {click: BX.proxy(this._prev, this)} 362 }), 363 364 BX.create('SPAN', { 365 props: {className: 'bx-calendar-header-content'}, 366 children: [ 367 (this.PARTS.MONTH = BX.create('A', { 368 attrs: {href: 'javascript:void(0)'}, 369 props: {className: 'bx-calendar-top-month'}, 370 events: {click: BX.proxy(this._menu_month, this)} 371 })), 372 373 (this.PARTS.YEAR = BX.create('A', { 374 attrs: {href: 'javascript:void(0)'}, 375 props: {className: 'bx-calendar-top-year'}, 376 events: {click: BX.proxy(this._menu_year, this)} 377 })) 378 ] 379 }), 380 381 BX.create('A', { 382 attrs: {href: 'javascript:void(0)'}, 383 props: {className: 'bx-calendar-right-arrow'}, 384 events: {click: BX.proxy(this._next, this)} 385 }) 386 ] 387 }), 388 389 (this.PARTS.WEEK = BX.create('DIV', { 390 props: { 391 className: 'bx-calendar-name-day-wrap' 392 } 393 })), 394 395 (this.PARTS.LAYERS = BX.create('DIV', { 396 props: { 397 className: 'bx-calendar-cell-block' 398 }, 399 events: { 400 click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick), 401 dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick) 402 } 403 })), 404 405 (this.PARTS.TIME = BX.create('DIV', { 406 props: { 407 className: 'bx-calendar-set-time-wrap' 408 }, 409 events: { 410 click: BX.delegateEvent( 411 {attr: 'data-action'}, 412 BX.delegate(this._time_actions, this) 413 ) 414 }, 415 html: '<a href="javascript:void(0)" data-action="time_show" class="bx-calendar-set-time"><i></i>'+BX.message('CAL_TIME_SET')+'</a><div class="bx-calendar-form-block"><span class="bx-calendar-form-text">'+BX.message('CAL_TIME')+'</span><span class="bx-calendar-form"><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" /><span class="bx-calendar-form-separator"></span><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" />'+(this.bAmPm?'<span class="bx-calendar-AM-PM-block"><span class="bx-calendar-AM-PM-text" data-action="time_ampm"></span><span class="bx-calendar-form-arrow-r"><a href="javascript:void(0)" class="bx-calendar-form-arrow-top" data-action="time_ampm_up"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow-bottom" data-action="time_ampm_down"><i></i></a></span></span>':'')+'</span><a href="javascript:void(0)" data-action="time_hide" class="bx-calendar-form-close"><i></i></a></div>' 416 })), 417 418 (this.PARTS.BUTTONS = BX.create('DIV', { 419 props: {className: 'bx-calendar-button-block'}, 420 events: { 421 click: BX.delegateEvent( 422 {attr: 'data-action'}, 423 BX.delegate(this._button_actions, this) 424 ) 425 }, 426 html: '<a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-select" data-action="submit"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('CAL_BUTTON')+'</span><span class="bx-calendar-button-right"></span></a><a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-cancel" data-action="cancel"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('JS_CORE_WINDOW_CLOSE')+'</span><span class="bx-calendar-button-right"></span></a>' 427 })) 428 ] 429 }); 430 431 this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true); 432 this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling; 433 434 if (this.bAmPm) 435 this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild; 436 437 var spinner = (new BX.JCSpinner({
438 input: this.PARTS.TIME_INPUT_H, 439 callback_change: BX.proxy(this._check_time, this), 440 bSaveValue: false 441 })).Show(); 442 spinner.className = 'bx-calendar-form-arrow-l'; 443 this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H); 444 445 spinner = (new BX.JCSpinner({ 446 input: this.PARTS.TIME_INPUT_M, 447 callback_change: BX.proxy(this._check_time, this), 448 bSaveValue: true 449 })).Show(); 450 spinner.className = 'bx-calendar-form-arrow-r'; 451 if (!this.PARTS.TIME_INPUT_M.nextSibling) 452 this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner); 453 else 454 this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling); 455 456 for (var i = 0; i < 7; i++) 457 { 458 this.PARTS.WEEK.appendChild(BX.create('SPAN', { 459 props: { 460 className: 'bx-calendar-name-day' 461 }, 462 text: BX.message('DOW_' + ((i + this.weekStart) % 7)) 463 })); 464 } 465 466 return this.DIV; 467 }; 468 469 this._time_actions = function() 470 { 471 switch (BX.proxy_context.getAttribute('data-action')) 472 { 473 case 'time_show': 474 BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 475 if (this.params.bCompatibility) 476 { 477 BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled'); 478 } 479 this.popup.adjustPosition(); 480 break; 481 case 'time_hide': 482 BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 483 if (this.params.bCompatibility) 484 { 485 this._saveChoice('hide'); 486 BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled'); 487 } 488 this.popup.adjustPosition(); 489 break; 490 case 'time_ampm': 491 this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM'; 492 break; 493 case 'time_ampm_up': 494 this._check_time({bSaveValue: false}, null, 12); 495 return; 496 break; 497 case 'time_ampm_down': 498 this._check_time({bSaveValue: false}, null, -12); 499 return; 500 break; 501 } 502 503 this._check_time(); 504 }; 505 506 this._button_actions = function() 507 { 508 switch (BX.proxy_context.getAttribute('data-action')) 509 { 510 case 'submit': 511 if (this.params.bCompatibility) 512 { 513 this._saveChoice('show'); 514 } 515 this.SaveValue(); 516 break; 517 case 'cancel': 518 this.Close(); 519 break; 520 } 521 }; 522 523 this._saveChoice = function(state) 524 { 525 if (this.params.bCategoryTimeVisibilityOption) 526 { 527 BX.userOptions.save( 528 this.params.bCategoryTimeVisibilityOption, 529 this.params.bNameTimeVisibilityOption, 530 'visibility', 531 (state === 'show' ? 'Y' : 'N') 532 ); 533 } 534 535 this._bTimeVisibility = (state === 'show'); 536 this.params.bTimeVisibility = this._bTimeVisibility; 537 }; 538 539 this._check_time = function(params, value, direction) 540 { 541 var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0, 542 m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0, 543 bChanged = false; 544 545 if (!!params && !params.bSaveValue) 546 { 547 this.value.setUTCHours(this.value.getUTCHours() + direction); 548 } 549 else if (!isNaN(h)) 550 { 551 if (this.bAmPm) 552 { 553 if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM') 554 { 555 h += 12; 556 } 557 } 558 559 bChanged = true; 560 this.value.setUTCHours(h % 24); 561 } 562 563 if (!isNaN(m)) 564 { 565 bChanged = true; 566 this.value.setUTCMinutes(m % 60); 567 } 568 569 if (bChanged) 570 { 571 this.SetValue(this.value); 572 } 573 }; 574 575 this._set_layer = function() 576 { 577 var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0")); 578 579 if (!this._layers[layerId]) 580 { 581 this._layers[layerId] = this._create_layer(); 582 this._layers[layerId].BXLAYERID = layerId; 583 } 584 585 if (this._current_layer) 586 { 587 var v = new Date(this.value.valueOf()); 588 v.setUTCHours(0); v.setUTCMinutes(0); 589 590 var cur_value = BX.findChild(this._layers[layerId], { 591 tag: 'A', 592 className: 'bx-calendar-active' 593 }, true), 594 new_value = BX.findChild(this._layers[layerId], { 595 tag: 'A', 596 attr: { 597 'data-date' : v.valueOf() + '' 598 } 599 }, true); 600 601 if (cur_value) 602 { 603 BX.removeClass(cur_value, 'bx-calendar-active'); 604 } 605 606 if (new_value) 607 { 608 BX.addClass(new_value, 'bx-calendar-active'); 609 } 610 611 this._replace_layer(this._current_layer, this._layers[layerId]); 612 } 613 else 614 { 615 this.PARTS.LAYERS.appendChild(this._layers[layerId]); 616 } 617 618 this._current_layer = this._layers[layerId]; 619 }; 620 621 this._replace_layer = function(old_layer, new_layer) 622 { 623 if (old_layer != new_layer) 624 { 625 if (!BX.browser.IsIE() || BX.browser.IsDoctype()) 626 { 627 var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1; 628 629 var old_top = 0; 630 var new_top = -dir * old_layer.offsetHeight; 631 632 old_layer.style.position = 'relative'; 633 old_layer.style.top = "0px"; 634 old_layer.style.zIndex = 5; 635 636 new_layer.style.position = 'absolute'; 637 new_layer.style.top = new_top + 'px'; 638 new_layer.style.zIndex = 6; 639 640 this.PARTS.LAYERS.appendChild(new_layer); 641 642 var delta = 15; 643 644 var f; 645 (f = function() { 646 new_top += dir * delta; 647 old_top += dir * delta; 648 649 if (dir * new_top < 0) 650 { 651 old_layer.style.top = old_top + 'px'; 652 new_layer.style.top = new_top + 'px'; 653 setTimeout(f, 10); 654 } 655 else 656 { 657 old_layer.parentNode.removeChild(old_layer); 658 659 new_layer.style.top = "0px"; 660 new_layer.style.position = 'static'; 661 new_layer.style.zIndex = 0; 662 } 663 })(); 664 } 665 else 666 {
667 this.PARTS.LAYERS.replaceChild(new_layer, old_layer); 668 } 669 } 670 }; 671 672 this._create_layer = function() 673 { 674 var l = BX.create('DIV', { 675 props: { 676 className: 'bx-calendar-layer' 677 } 678 }); 679 680 var month_start = new Date(this.value); 681 month_start.setUTCHours(0); 682 month_start.setUTCMinutes(0); 683 684 month_start.setUTCDate(1); 685 686 if (month_start.getUTCDay() != this.weekStart) 687 { 688 var d = month_start.getUTCDay() - this.weekStart; 689 d += d < 0 ? 7 : 0; 690 month_start.setUTCDate(month_start.getUTCDate()-d); 691 } 692 693 var cur_month = this.value.getUTCMonth(), 694 cur_day = this.value.getUTCDate(), 695 s = ''; 696 for (var i = 0; i < this.numRows; i++) 697 { 698 s += '<div class="bx-calendar-range' 699 +(i == this.numRows-1 ? ' bx-calendar-range-noline' : '') 700 +'">'; 701 702 for (var j = 0; j < 7; j++) 703 { 704 d = month_start.getUTCDate(); 705 var wd = month_start.getUTCDay(); 706 var className = 'bx-calendar-cell'; 707 708 if (cur_month != month_start.getUTCMonth()) 709 className += ' bx-calendar-date-hidden'; 710 else if (cur_day == d) 711 className += ' bx-calendar-active'; 712 713 714 if (wd == 0 || wd == 6) 715 className += ' bx-calendar-weekend'; 716 717 s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>'; 718 719 month_start.setUTCDate(month_start.getUTCDate()+1); 720 } 721 s += '</div>'; 722 } 723 724 l.innerHTML = s; 725 726 return l; 727 }; 728 729 this._prev = function() 730 { 731 this.SetMonth(this.value.getUTCMonth()-1); 732 }; 733 734 this._next = function() 735 { 736 this.SetMonth(this.value.getUTCMonth()+1); 737 }; 738 739 this._menu_month_content = function() 740 { 741 var months = '', cur_month = this.value.getMonth(), i; 742 for (i = 0; i < 12; i++) 743 { 744 months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>'; 745 } 746 747 return '<div class="bx-calendar-month-popup"><div class="bx-calendar-month-title" data-bx-month="' + this.value.getUTCMonth() + '">' + BX.message('MONTH_' + (this.value.getUTCMonth() + 1)) + '</div><div class="bx-calendar-month-content">' + months + '</div></div>'; 748 }; 749 750 this._menu_month = function() 751 { 752 if (!this.popup_month) 753 { 754 this.popup_month = new BX.PopupWindow( 755 'calendar_popup_month_' + Math.random(), this.PARTS.MONTH, 756 { 757 content: this._menu_month_content(), 758 closeByEsc: true, 759 autoHide: true, 760 offsetTop: -29, 761 offsetLeft: -1, 762 className: this.month_popup_classname, 763 events: { 764 onPopupShow: BX.delegate(function() { 765 if (this.popup_year) 766 { 767 this.popup_year.close(); 768 } 769 }, this) 770 } 771 } 772 ); 773 774 BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this)); 775 this.popup_month.BXMONTH = this.value.getUTCMonth(); 776 } 777 else if (this.popup_month.BXMONTH != this.value.getUTCMonth()) 778 { 779 this.popup_month.setContent(this._menu_month_content()); 780 this.popup_month.BXMONTH = this.value.getUTCMonth(); 781 } 782 783 this.popup_month.show(); 784 }; 785 786 this.month_popup_click = function(e) 787 { 788 var target = e.target || e.srcElement; 789 if (target && target.getAttribute && target.getAttribute('data-bx-month')) 790 { 791 this.SetMonth(parseInt(target.getAttribute('data-bx-month'))); 792 this.popup_month.close(); 793 } 794 }; 795 796 this._menu_year_content = function() 797 { 798 var s = '<div class="bx-calendar-year-popup"><div class="bx-calendar-year-title" data-bx-year="' + this.value.getUTCFullYear() + '">' + this.value.getUTCFullYear() + '</div><div class="bx-calendar-year-content" id="bx-calendar-year-content">'; 799 800 for (var i=-3; i <= 3; i++) 801 { 802 s += '<span class="bx-calendar-year-number' + (i == 0?' bx-calendar-year-active' : '') + '" data-bx-year="' + (this.value.getUTCFullYear() - i) + '">' + (this.value.getUTCFullYear() - i)+'</span>'; 803 } 804 805 s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>'; 806 807 return s; 808 }; 809 810 this._menu_year = function() 811 { 812 if (!this.popup_year) 813 { 814 this.popup_year = new BX.PopupWindow( 815 'calendar_popup_year_' + Math.random(), this.PARTS.YEAR, 816 { 817 content: this._menu_year_content(), 818 closeByEsc: true, 819 autoHide: true, 820 offsetTop: -29, 821 offsetLeft: -1, 822 className: this.year_popup_classname, 823 events: { 824 onPopupShow: BX.delegate(function() { 825 if (this.popup_month) 826 { 827 this.popup_month.close(); 828 } 829 }, this) 830 } 831 } 832 ); 833 834 BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this)); 835 BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this)); 836 this.popup_year.BXYEAR = this.value.getUTCFullYear(); 837 } 838 else if (this.popup_year.BXYEAR != this.value.getUTCFullYear()) 839 { 840 this.popup_year.setContent(this._menu_year_content()); 841 this.popup_year.BXYEAR = this.value.getUTCFullYear(); 842 } 843 844 this.popup_year.show(); 845 }; 846 847 this.year_popup_click = function(e) 848 { 849 var target = e.target || e.srcElement; 850 if (target && target.getAttribute && target.getAttribute('data-bx-year')) 851 { 852 this.SetYear(parseInt(target.getAttribute('data-bx-year'))); 853 this.popup_year.close(); 854 } 855 }; 856 this.year_popup_keyup = function(e) 857 { 858 var target = e.target || e.srcElement; 859 if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y') 860 { 861 var value = parseInt(target.value); 862 if(value >= 1900 && value <= 2100) 863 { 864 this.SetYear(value); 865 this.popup_year.close(); 866 } 867 } 868 }; 869 870 this._check_date = function(v) 871 { 872 var res = v; 873 874 if (BX.type.isString(v)) 875 { 876 res = BX.parseDate(v, true); 877 } 878 879 if (!BX.type.isDate(res) || isNaN(res.valueOf())) 880 { 881 res = BX.date.convertToUTC(new Date()); 882 if (this.params.bHideTime) 883 { 884 res.setUTCHours(0); 885 res.setUTCMinutes(0); 886 } 887 } 888 889 res.setUTCMilliseconds(0); 890 res.setUTCSeconds(0); 891 892 res.BXCHECKED = true; 893 894 return res; 895 }; 896}; 897 898BX.JCCalendar.prototype.Show = function(params) 899{ 900 if (!BX.isReady) 901 { 902 BX.ready(BX.delegate(function() {this.Show(params)}, this)); 903 return; 904 } 905 906 params.node = params.node||document.body; 907 908 if (BX.type.isNotEmptyString(params.node)) 909 { 910 var n = BX(params.node); 911 if (!n) 912 { 913 n = document.getElementsByName(params.node); 914 if (n && n.length > 0) 915 { 916 n = n[0] 917 } 918 } 919 params.node = n; 920 } 921 922 if (!params.node) 923 return; 924 925 if (!!params.field) 926 { 927 if (BX.type.isString(params.field)) 928 { 929 n = BX(params.field); 930 if (!!n) 931 { 932 params.field = n; 933 } 934 else 935 {
936 if (params.form) 937 { 938 if (BX.type.isString(params.form)) 939 { 940 params.form = document.forms[params.form]; 941 } 942 } 943 944 if (BX.type.isDomNode(params.form) && !!params.form[params.field]) 945 { 946 params.field = params.form[params.field]; 947 } 948 else 949 { 950 n = document.getElementsByName(params.field); 951 if (n && n.length > 0) 952 { 953 n = n[0]; 954 params.field = n; 955 } 956 } 957 } 958 959 if (BX.type.isString(params.field)) 960 { 961 params.field = BX(params.field); 962 } 963 } 964 } 965 966 var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node; 967 968 this.params = params; 969 970 this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility); 971 this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility); 972 if (this.params.bCompatibility) 973 { 974 this.params.bCategoryTimeVisibilityOption = ( 975 this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : '' 976 ); 977 this.params.bNameTimeVisibilityOption = ( 978 this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility' 979 ); 980 981 if (typeof this._bTimeVisibility !== 'undefined') 982 { 983 this.params.bTimeVisibility = this._bTimeVisibility; 984 } 985 } 986 987 this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime; 988 this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime; 989 this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond; 990 991 this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START')); 992 if (isNaN(this.weekStart)) 993 this.weekStart = 1; 994 995 if (!this.popup) 996 { 997 this._create(this.params); 998 } 999 else 1000 { 1001 this.popup.setBindElement(this.params.node); 1002 } 1003 1004 var bHideTime = !!this.params.bHideTime; 1005 if (this.params.value) 1006 { 1007 this.SetValue(this.params.value); 1008 bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0; 1009 } 1010 else if (this.params.field) 1011 { 1012 this.SetValue(this.params.field.value); 1013 bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0; 1014 } 1015 else if (!!this.params.currentTime) 1016 { 1017 this.SetValue(this.params.currentTime); 1018 } 1019 else 1020 { 1021 this.SetValue(); 1022 } 1023 1024 if (!!this.params.bTime) 1025 { 1026 this.activateTimeStyle(bHideTime); 1027 } 1028 else 1029 { 1030 this.activateDateStyle(bHideTime); 1031 } 1032 1033 if (bShow) 1034 { 1035 this._auto_hide_disable(); 1036 this.popup.show(); 1037 setTimeout(BX.proxy(this._auto_hide_enable, this), 0); 1038 } 1039 1040 this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus; 1041 if(this.params.bSetFocus) 1042 { 1043 params.node.blur(); 1044 } 1045 else 1046 { 1047 BX.bind(params.node, 'keyup', BX.defer(function(){ 1048 this.SetValue(params.node.value); 1049 if(!!this.params.bTime) 1050 { 1051 if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0) 1052 BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1053 else 1054 BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1055 } 1056 }, this)); 1057 } 1058 1059 return this; 1060}; 1061 1062BX.JCCalendar.prototype.activateDateStyle = function(bHideTime) 1063{ 1064 BX.addClass(this.DIV, 'bx-calendar-time-disabled'); 1065 1066 if (!!bHideTime) 1067 BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1068 else 1069 BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1070}; 1071 1072BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime) 1073{ 1074 if (this.params.bCompatibility && !this.params.bTimeVisibility) 1075 { 1076 BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled'); 1077 BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple'); 1078 BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1079 } 1080 else 1081 { 1082 BX.removeClass(this.DIV, 'bx-calendar-time-disabled'); 1083 1084 if (!!bHideTime) 1085 BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1086 else 1087 BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1088 } 1089}; 1090 1091BX.JCCalendar.prototype.SetDay = function(d) 1092{ 1093 this.value.setUTCDate(d); 1094 return this.SetValue(this.value); 1095}; 1096 1097BX.JCCalendar.prototype.SetMonth = function(m) 1098{ 1099 if (this.popup_month) 1100 this.popup_month.close(); 1101 1102 this.value.setUTCMonth(m); 1103 1104 if(m < 0) 1105 m += 12; 1106 else if (m >= 12) 1107 m -= 12; 1108 1109 while(this.value.getUTCMonth() > m) 1110 { 1111 this.value.setUTCDate(this.value.getUTCDate()-1); 1112 } 1113 1114 return this.SetValue(this.value); 1115}; 1116 1117BX.JCCalendar.prototype.SetYear = function(y) 1118{ 1119 if (this.popup_year) 1120 this.popup_year.close(); 1121 this.value.setUTCFullYear(y); 1122 return this.SetValue(this.value); 1123}; 1124 1125BX.JCCalendar.prototype.SetDate = function(v, bSet) 1126{ 1127 v = this._check_date(v); 1128 v.setUTCHours(this.value.getUTCHours()); 1129 v.setUTCMinutes(this.value.getUTCMinutes()); 1130 v.setUTCSeconds(this.value.getUTCSeconds()); 1131 1132 if (this.params.bTime && !bSet) 1133 { 1134 return this.SetValue(v); 1135 } 1136 else 1137 { 1138 this.SetValue(v); 1139 this.SaveValue(); 1140 } 1141}; 1142 1143BX.JCCalendar.prototype.SetValue = function(v) 1144{ 1145 this.value = (v && v.BXCHECKED) ? v : this._check_date(v); 1146 1147 this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1)); 1148 this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear(); 1149 1150 if (!!this.params.bTime) 1151 {
1152 var h = this.value.getUTCHours(); 1153 if (this.bAmPm) 1154 { 1155 if (h >= 12) 1156 { 1157 this.PARTS.TIME_AMPM.innerHTML = 'PM'; 1158 1159 if (h != 12) 1160 h -= 12; 1161 } 1162 else 1163 { 1164 this.PARTS.TIME_AMPM.innerHTML = 'AM'; 1165 1166 if (h == 0) 1167 h = 12; 1168 } 1169 } 1170 1171 this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0"); 1172 this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0"); 1173 } 1174 1175 this._set_layer(); 1176 1177 return this; 1178}; 1179 1180BX.JCCalendar.prototype.SaveValue = function() 1181{ 1182 if (this.popup_month) 1183 this.popup_month.close(); 1184 if (this.popup_year) 1185 this.popup_year.close(); 1186 1187 var bSetValue = true; 1188 if (!!this.params.callback) 1189 { 1190 var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]); 1191 if (res === false) 1192 bSetValue = false; 1193 } 1194 1195 if (bSetValue) 1196 { 1197 var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened'); 1198 1199 if (this.params.field) 1200 { 1201 var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE'); 1202 1203 if(bTime && !this.params.bUseSecond) 1204 { 1205 format = format.replace(':SS', ''); 1206 } 1207 1208 this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true); 1209 BX.fireEvent(this.params.field, 'change'); 1210 } 1211 1212 this.popup.close(); 1213 1214 if (!!this.params.callback_after) 1215 { 1216 this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]); 1217 } 1218 } 1219 1220 return this; 1221}; 1222 1223BX.JCCalendar.prototype.Close = function() 1224{ 1225 if (!!this.popup) 1226 this.popup.close(); 1227 1228 return this; 1229}; 1230 1231BX.JCSpinner = function(params) 1232{ 1233 params = params || {}; 1234 this.params = { 1235 input: params.input || null, 1236 1237 delta: params.delta || 1, 1238 1239 timeout_start: params.timeout_start || 1000, 1240 timeout_cont: params.timeout_cont || 150, 1241 1242 callback_start: params.callback_start || null, 1243 callback_change: params.callback_change || null, 1244 callback_finish: params.callback_finish || null, 1245 1246 bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue 1247 }; 1248 1249 this.mousedown = false; 1250 this.direction = 1; 1251}; 1252 1253BX.JCSpinner.prototype.Show = function() 1254{ 1255 this.node = BX.create('span', { 1256 events: { 1257 mousedown: BX.delegateEvent( 1258 {attr: 'data-dir'}, 1259 BX.delegate(this.Start, this) 1260 ) 1261 }, 1262 html: '<a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-top" data-dir="1"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-bottom" data-dir="-1"><i></i></a>' 1263 }); 1264 return this.node; 1265}; 1266 1267BX.JCSpinner.prototype.Start = function() 1268{ 1269 this.mousedown = true; 1270 this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1; 1271 BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this)); 1272 this.ChangeValue(true); 1273}; 1274 1275BX.JCSpinner.prototype.ChangeValue = function(bFirst) 1276{ 1277 if(!this.mousedown) 1278 return; 1279 1280 if (this.params.input) 1281 { 1282 var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction; 1283 1284 if (this.params.bSaveValue) 1285 this.params.input.value = v; 1286 1287 if (!!bFirst && this.params.callback_start) 1288 this.params.callback_start(this.params, v, this.direction); 1289 1290 if (this.params.callback_change) 1291 this.params.callback_change(this.params, v, this.direction); 1292 1293 setTimeout( 1294 BX.proxy(this.ChangeValue, this), 1295 !!bFirst ? this.params.timeout_start : this.params.timeout_cont 1296 ); 1297 } 1298}; 1299 1300BX.JCSpinner.prototype.MouseUp = function() 1301{ 1302 this.mousedown = false; 1303 BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this)); 1304 1305 if (this.params.callback_finish) 1306 this.params.callback_finish(this.params, this.params.input.value); 1307}; 1308 1309/**************** compatibility hacks ***************************/ 1310 1311window.jsCalendar = { 1312 Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar) 1313 { 1314 return BX.calendar({ 1315 node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar 1316 }); 1317 }, 1318 1319 ValueToString: BX.calendar.ValueToString 1320}; 1321 1322 1323/************ clock popup transferred from timeman **************/ 1324 1325BX.CClockSelector = function(params) 1326{ 1327 this.params = params; 1328 1329 this.params.popup_buttons = this.params.popup_buttons || [ 1330 new BX.PopupWindowButton({ 1331 text : BX.message('CAL_BUTTON'), 1332 className : "popup-window-button-create", 1333 events : {click : BX.proxy(this.setValue, this)} 1334 }) 1335 ]; 1336 1337 this.isReady = false;
1338 1339 this.WND = new BX.PopupWindow( 1340 this.params.popup_id || 'clock_selector_popup', 1341 this.params.node, 1342 this.params.popup_config || { 1343 titleBar: BX.message('CAL_TIME'), 1344 offsetLeft: -45, 1345 offsetTop: -135, 1346 autoHide: true, 1347 closeIcon: true, 1348 closeByEsc: true 1349 } 1350 ); 1351 1352 this.SHOW = false; 1353 BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this)); 1354 1355 this.obClocks = {}; 1356 this.CLOCK_ID = this.params.clock_id || 'clock_selector'; 1357}; 1358 1359BX.CClockSelector.prototype.Show = function() 1360{ 1361 if (!this.isReady) 1362 { 1363 //BX.timeman.showWait(this.parent.DIV); 1364 1365 BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this)); 1366 return BX.ajax.get('/bitrix/tools/clock_selector.php', {start_time: this.params.start_time, clock_id: this.CLOCK_ID, sessid: BX.bitrix_sessid()}, BX.delegate(this.Ready, this)); 1367 } 1368 1369 this.WND.setButtons(this.params.popup_buttons); 1370 this.WND.show(); 1371 1372 this.SHOW = true; 1373 1374 if (window['bxClock_' + this.obClocks[this.CLOCK_ID]]) 1375 { 1376 setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40); 1377 } 1378 1379 return true; 1380}; 1381 1382BX.CClockSelector.prototype.onClockRegister = function(obClocks) 1383{ 1384 if (obClocks[this.CLOCK_ID]) 1385 { 1386 this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID]; 1387 BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this)); 1388 } 1389}; 1390 1391BX.CClockSelector.prototype.Ready = function(data) 1392{ 1393 this.content = this.CreateContent(data); 1394 this.WND.setContent(this.content); 1395 1396 this.isReady = true; 1397 //BX.timeman.closeWait(); 1398 1399 setTimeout(BX.proxy(this.Show, this), 30); 1400}; 1401 1402BX.CClockSelector.prototype.CreateContent = function(data) 1403{ 1404 return BX.create('DIV', { 1405 events: {click: BX.PreventDefault}, 1406 html: 1407 '<div class="bx-tm-popup-clock">' + data + '</div>' 1408 }); 1409}; 1410 1411BX.CClockSelector.prototype.setValue = function(e) 1412{ 1413 if (this.params.callback) 1414 { 1415 var input = BX.findChild(this.content, {tagName: 'INPUT'}, true); 1416 this.params.callback.apply(this.params.node, [input.value]); 1417 } 1418 1419 return BX.PreventDefault(e); 1420}; 1421 1422BX.CClockSelector.prototype.closeWnd = function(e) 1423{ 1424 this.WND.close(); 1425 return (e || window.event) ? BX.PreventDefault(e) : true; 1426}; 1427 1428BX.CClockSelector.prototype.setNode = function(node) 1429{ 1430 this.WND.setBindElement(node); 1431}; 1432 1433BX.CClockSelector.prototype.setTime = function(timestamp) 1434{ 1435 this.params.start_time = timestamp; 1436 if (window['bxClock_' + this.obClocks[this.CLOCK_ID]]) 1437 { 1438 window['bxClock_' + this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60)); 1439 } 1440}; 1441 1442BX.CClockSelector.prototype.setCallback = function(cb) 1443{ 1444 this.params.callback = cb; 1445}; 1446 1447BX.CClockSelector.prototype.onPopupClose = function() 1448{ 1449 this.SHOW = false;
1450}; 1451 1452})(); 1453
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.