window.dhtmlXScheduler=window.scheduler={version:2.2}; dhtmlxEventable(scheduler); scheduler.init=function(id,date,mode){ date=date||(new Date()); mode=mode||"week"; this._obj=(typeof id == "string")?document.getElementById(id):id; this._els=[]; this._scroll=true; this._quirks=(_isIE && document.compatMode == "BackCompat"); this._quirks7=(_isIE && navigator.appVersion.indexOf("MSIE 8")==-1); this.get_elements(); this.init_templates(); this.set_actions(); dhtmlxEvent(window,"resize",function(){ window.clearTimeout(scheduler._resize_timer); scheduler._resize_timer=window.setTimeout(function(){ if (scheduler.callEvent("onSchedulerResize",[])) scheduler.update_view(); }, 100); }) this.set_sizes(); this.setCurrentView(date,mode); }; scheduler.xy={ nav_height:22, min_event_height:40, scale_width:50, bar_height:20, scroll_width:18, scale_height:20, month_scale_height:20, menu_width:25, margin_top:0, margin_left:0, editor_width:140 }; scheduler.keys={ edit_save:13, edit_cancel:27 }; scheduler.set_sizes=function(){ var w = this._x = this._obj.clientWidth-this.xy.margin_left; var h = this._y = this._obj.clientHeight-this.xy.margin_top; //not-table mode always has scroll - need to be fixed in future var scale_x=this._table_view?0:(this.xy.scale_width+this.xy.scroll_width); var scale_s=this._table_view?-1:this.xy.scale_width; this.set_xy(this._els["dhx_cal_navline"][0],w,this.xy.nav_height,0,0); this.set_xy(this._els["dhx_cal_header"][0],w-scale_x,this.xy.scale_height,scale_s,this.xy.nav_height+(this._quirks?-1:1)); //to support alter-skin, we need a way to alter height directly from css var actual_height = this._els["dhx_cal_navline"][0].offsetHeight; if (actual_height > 0) this.xy.nav_height = actual_height; var data_y=this.xy.scale_height+this.xy.nav_height+(this._quirks?-2:0); this.set_xy(this._els["dhx_cal_data"][0],w,h-(data_y+2),0,data_y+2); } scheduler.set_xy=function(node,w,h,x,y){ node.style.width=Math.max(0,w)+"px"; node.style.height=Math.max(0,h)+"px"; if (arguments.length>3){ node.style.left=x+"px"; node.style.top=y+"px"; } } scheduler.get_elements=function(){ //get all child elements as named hash var els=this._obj.getElementsByTagName("DIV"); for (var i=0; i < els.length; i++){ var name=els[i].className; if (!this._els[name]) this._els[name]=[]; this._els[name].push(els[i]); //check if name need to be changed var t=scheduler.locale.labels[els[i].getAttribute("name")||name]; if (t) els[i].innerHTML=t; } } scheduler.set_actions=function(){ for (var a in this._els) if (this._click[a]) for (var i=0; i < this._els[a].length; i++) this._els[a][i].onclick=scheduler._click[a]; this._obj.onselectstart=function(e){ return false; } this._obj.onmousemove=function(e){ scheduler._on_mouse_move(e||event); } this._obj.onmousedown=function(e){ scheduler._on_mouse_down(e||event); } this._obj.onmouseup=function(e){ scheduler._on_mouse_up(e||event); } this._obj.ondblclick=function(e){ scheduler._on_dbl_click(e||event); } } scheduler.select=function(id){ if (this._table_view || !this.getEvent(id)._timed) return; //temporary block if (this._select_id==id) return; this.editStop(false); this.unselect(); this._select_id = id; this.updateEvent(id); } scheduler.unselect=function(id){ if (id && id!=this._select_id) return; var t=this._select_id; this._select_id = null; if (t) this.updateEvent(t); } scheduler.getState=function(){ return { mode: this._mode, date: this._date, min_date: this._min_date, max_date: this._max_date, editor_id: this._edit_id, lightbox_id: this._lightbox_id }; } scheduler._click={ dhx_cal_data:function(e){ var trg = e?e.target:event.srcElement; var id = scheduler._locate_event(trg); e = e || event; if ((id && !scheduler.callEvent("onClick",[id,e])) ||scheduler.config.readonly) return; if (id) { scheduler.select(id); var mask = trg.className; if (mask.indexOf("_icon")!=-1) scheduler._click.buttons[mask.split(" ")[1].replace("icon_","")](id); } else scheduler._close_not_saved(); }, dhx_cal_prev_button:function(){ scheduler._click.dhx_cal_next_button(0,-1); }, dhx_cal_next_button:function(dummy,step){ scheduler.setCurrentView(scheduler.date.add( //next line changes scheduler._date , but seems it has not side-effects scheduler.date[scheduler._mode+"_start"](scheduler._date),(step||1),scheduler._mode)); }, dhx_cal_today_button:function(){ scheduler.setCurrentView(new Date()); }, dhx_cal_tab:function(){ var mode = this.getAttribute("name").split("_")[0]; scheduler.setCurrentView(scheduler._date,mode); }, buttons:{ "delete":function(id){ var c=scheduler.locale.labels.confirm_deleting; if (!c||confirm(c)) scheduler.deleteEvent(id); }, edit:function(id){ scheduler.edit(id); }, save:function(id){ scheduler.editStop(true); }, details:function(id){ scheduler.showLightbox(id); }, cancel:function(id){ scheduler.editStop(false); } } } scheduler.addEventNow=function(start,end,e){ var base = {}; if (typeof start == "object"){ base = start; start = null; } var d = (this.config.event_duration||this.config.time_step)*60000; if (!start) start = Math.round((new Date()).valueOf()/d)*d; var start_date = new Date(start); if (!end){ var start_hour = this.config.first_hour; if (start_hour > start_date.getHours()){ start_date.setHours(start_hour); start = start_date.valueOf(); } end = start+d; } base.start_date = base.start_date||start_date; base.end_date = base.end_date||new Date(end); base.text = base.text||this.locale.labels.new_event; base.id = this._drag_id = this.uid(); this._drag_mode="new-size"; this._loading=true; this.addEvent(base); this.callEvent("onEventCreated",[this._drag_id,e]); this._loading=false; this._drag_event={}; //dummy , to trigger correct event updating logic this._on_mouse_up(e); } scheduler._on_dbl_click=function(e,src){ src = src||(e.target||e.srcElement); if (this.config.readonly) return; var name = src.className.split(" ")[0]; switch(name){ case "dhx_scale_holder": case "dhx_scale_holder_now": case "dhx_month_body": if (!scheduler.config.dblclick_create) break; var pos=this._mouse_coords(e); var start=this._min_date.valueOf()+(pos.y*this.config.time_step+(this._table_view?0:pos.x)*24*60)*60000; start = this._correct_shift(start); this.addEventNow(start,null,e); break; case "dhx_body": case "dhx_cal_event_line": case "dhx_cal_event_clear": var id = this._locate_event(src); if (!this.callEvent("onDblClick",[id,e])) return; if (this.config.details_on_dblclick || this._table_view || !this.getEvent(id)._timed) this.showLightbox(id); else this.edit(id); break; case "": if (src.parentNode) return scheduler._on_dbl_click(e,src.parentNode); default: var t = this["dblclick_"+name]; if (t) t.call(this,e); break; } } scheduler._mouse_coords=function(ev){ var pos; var b=document.body; var d = document.documentElement; if(ev.pageX || ev.pageY) pos={x:ev.pageX, y:ev.pageY}; else pos={ x:ev.clientX + (b.scrollLeft||d.scrollLeft||0) - b.clientLeft, y:ev.clientY + (b.scrollTop||d.scrollTop||0) - b.clientTop } //apply layout pos.x-=getAbsoluteLeft(this._obj)+(this._table_view?0:this.xy.scale_width); pos.y-=getAbsoluteTop(this._obj)+this.xy.nav_height+(this._dy_shift||0)+this.xy.scale_height-this._els["dhx_cal_data"][0].scrollTop; pos.ev = ev; var handler = this["mouse_"+this._mode]; if (handler) return handler.call(this,pos); //transform to date if (!this._table_view){ pos.x=Math.max(0,Math.ceil(pos.x/this._cols[0])-1); pos.y=Math.max(0,Math.ceil(pos.y*60/(this.config.time_step*this.config.hour_size_px))-1)+this.config.first_hour*(60/this.config.time_step); } else { var dy=0; for (dy=1; dy < this._colsS.heights.length; dy++) if (this._colsS.heights[dy]>pos.y) break; pos.y=(Math.max(0,Math.ceil(pos.x/this._cols[0])-1)+Math.max(0,dy-1)*7)*24*60/this.config.time_step; pos.x=0; } return pos; } scheduler._close_not_saved=function(){ if (new Date().valueOf()-(scheduler._new_event||0) > 500 && scheduler._edit_id){ var c=scheduler.locale.labels.confirm_closing; if (!c || confirm(c)) scheduler.editStop(scheduler.config.positive_closing); } } scheduler._correct_shift=function(start, back){ return start-=((new Date(scheduler._min_date)).getTimezoneOffset()-(new Date(start)).getTimezoneOffset())*60000*(back?-1:1); } scheduler._on_mouse_move=function(e){ if (this._drag_mode){ var pos=this._mouse_coords(e); if (!this._drag_pos || this._drag_pos.x!=pos.x || this._drag_pos.y!=pos.y){ if (this._edit_id!=this._drag_id) this._close_not_saved(); this._drag_pos=pos; if (this._drag_mode=="create"){ this._close_not_saved(); this._loading=true; //will be ignored by dataprocessor var start=this._min_date.valueOf()+(pos.y*this.config.time_step+(this._table_view?0:pos.x)*24*60)*60000; //if (this._mode != "week" && this._mode != "day") start = this._correct_shift(start); if (!this._drag_start){ this._drag_start=start; return; } var end = start; if (end==this._drag_start) return; this._drag_id=this.uid(); this.addEvent(new Date(this._drag_start), new Date(end),this.locale.labels.new_event,this._drag_id, pos.fields); this.callEvent("onEventCreated",[this._drag_id,e]); this._loading=false; this._drag_mode="new-size"; } var ev=this.getEvent(this._drag_id); var start,end; if (this._drag_mode=="move"){ start = this._min_date.valueOf()+(pos.y*this.config.time_step+pos.x*24*60)*60000; if (!pos.custom && this._table_view) start+=this.date.time_part(ev.start_date)*1000; start = this._correct_shift(start); end = ev.end_date.valueOf()-(ev.start_date.valueOf()-start); } else { start = ev.start_date.valueOf(); if (this._table_view) end = this._min_date.valueOf()+pos.y*this.config.time_step*60000 + (pos.custom?0:24*60*60000); else{ end = this.date.date_part(new Date(ev.end_date)).valueOf()+pos.y*this.config.time_step*60000; this._els["dhx_cal_data"][0].style.cursor="s-resize"; if (this._mode == "week" || this._mode == "day") end = this._correct_shift(end); } if (this._drag_mode == "new-size"){ if (end <= this._drag_start){ var shift = pos.shift||((this._table_view && !pos.custom)?24*60*60000:0); start = end-shift; end = this._drag_start+(shift||(this.config.time_step*60000)); } else { start = this._drag_start; } } else if (end<=start) end=start+this.config.time_step*60000; } var new_end = new Date(end-1); var new_start = new Date(start); //prevent out-of-borders situation for day|week view if (this._table_view || (new_end.getDate()==new_start.getDate() && new_end.getHours()=ed) cls='dhx_after'; else if (sd.valueOf()==cd.valueOf()) cls='dhx_now'; html+=" class='"+cls+" "+this.templates.month_date_class(sd,cd)+"' "; html+=">
"+this.templates.month_day(sd)+"
" sd=this.date.add(sd,1,"day"); } html+=""; h[i] = cellheight; cellheight+=this._colsS.height; } html+=""; this._max_date=sd; b.innerHTML=html; return sd; } scheduler.getLabel = function(property, key) { var sections = this.config.lightbox.sections; for (var i=0; i