| // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) |
| // |
| // MIT License (MIT) |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a |
| // copy of this software and associated documentation files (the "Software"), |
| // to deal in the Software without restriction, including without limitation |
| // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| // and/or sell copies of the Software, and to permit persons to whom the |
| // Software is furnished to do so, subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in |
| // all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
| // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A |
| // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE |
| // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| // |
| |
| pscript.onload_calendar = function(wrapper) { |
| if(!erpnext.calendar) { |
| erpnext.calendar = new Calendar(); |
| erpnext.calendar.init(wrapper); |
| rename_observers.push(erpnext.calendar); |
| } |
| } |
| |
| ///// CALENDAR |
| |
| Calendar=function() { |
| this.views=[]; |
| this.events = {}; |
| this.events_by_name = {}; |
| this.weekdays = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); |
| } |
| |
| Calendar.prototype.init=function (parent) { |
| |
| this.wrapper = parent; |
| this.body = $('.cal_body').get(0); |
| |
| //this.make_head_buttons(); |
| //this.make_header(); |
| this.view_title = $('.cal_view_title').get(0); |
| |
| this.todays_date = new Date(); |
| this.selected_date = this.todays_date; |
| this.selected_hour = 8; |
| |
| // Create views |
| this.views['Month'] = new Calendar.MonthView(this); |
| this.views['Week'] = new Calendar.WeekView(this); |
| this.views['Day'] = new Calendar.DayView(this); |
| |
| // Month view as initial |
| this.cur_view = this.views['Month']; |
| this.views['Month'].show(); |
| |
| } |
| |
| Calendar.prototype.rename_notify = function(dt, old_name, new_name) { |
| // calendar |
| if(dt = 'Event'){ |
| if(this.events_by_name[old_name]) { |
| delete this.events_by_name[old_name]; |
| } |
| } |
| } |
| |
| //------------------------------------------------------ |
| |
| Calendar.prototype.show_event = function(ev, cal_ev) { |
| var me = this; |
| if(!this.event_dialog) { |
| var d = new Dialog(400, 400, 'Calendar Event'); |
| d.make_body([ |
| ['HTML','Heading'] |
| ,['Text','Description'] |
| ,['Check', 'Public Event'] |
| ,['Check', 'Cancel Event'] |
| ,['HTML', 'Event Link'] |
| ,['Button', 'Save'] |
| ]) |
| |
| // show the event when the dialog opens |
| d.onshow = function() { |
| // heading |
| var c = me.selected_date; |
| var tmp = time_to_ampm(this.ev.event_hour); |
| tmp = tmp[0]+':'+tmp[1]+' '+tmp[2]; |
| |
| this.widgets['Heading'].innerHTML = |
| '<div style="text-align: center; padding:4px; font-size: 14px">' |
| + erpnext.calendar.weekdays[c.getDay()] + ', ' + c.getDate() + ' ' + month_list_full[c.getMonth()] + ' ' + c.getFullYear() |
| + ' - <b>'+tmp+'</b></div>'; |
| |
| // set |
| this.widgets['Description'].value = cstr(this.ev.description); |
| |
| this.widgets['Public Event'].checked = false; |
| this.widgets['Cancel Event'].checked = false; |
| |
| if(this.ev.event_type=='Public') |
| this.widgets['Public Event'].checked = true; |
| |
| this.widgets['Event Link'].innerHTML = ''; |
| |
| // link |
| var div = $a(this.widgets['Event Link'], 'div', 'link_type', {margin:'4px 0px'}); |
| div.onclick = function() { me.event_dialog.hide(); loaddoc('Event', me.event_dialog.ev.name); } |
| div.innerHTML = 'View Event details, add or edit participants'; |
| |
| } |
| |
| // event save |
| d.widgets['Save'].onclick = function() { |
| var d = me.event_dialog; |
| |
| // save values |
| d.ev.description = d.widgets['Description'].value; |
| if(d.widgets['Cancel Event'].checked) |
| d.ev.event_type='Cancel'; |
| else if(d.widgets['Public Event'].checked) |
| d.ev.event_type='Public'; |
| |
| me.event_dialog.hide(); |
| |
| // if new event |
| me.save_event(d.ev); |
| } |
| this.event_dialog = d; |
| } |
| this.event_dialog.ev = ev; |
| this.event_dialog.cal_ev = cal_ev ? cal_ev : null; |
| this.event_dialog.show(); |
| |
| } |
| |
| Calendar.prototype.save_event = function(doc) { |
| var me = this; |
| save_doclist('Event', doc.name, 'Save', function(r) { |
| var doc = locals['Event'][r.docname]; |
| var cal = erpnext.calendar; |
| cal.cur_view.refresh(); |
| |
| // if cancelled, hide |
| if(doc.event_type=='Cancel') { |
| $(cal.events_by_name[doc.name].body).toggle(false); |
| } |
| }); |
| } |
| |
| //------------------------------------------------------ |
| |
| Calendar.prototype.add_event = function() { |
| |
| var ev = LocalDB.create('Event'); |
| ev = locals['Event'][ev]; |
| |
| ev.event_date = dateutil.obj_to_str(this.selected_date); |
| ev.event_hour = this.selected_hour+':00'; |
| ev.event_type = 'Private'; |
| |
| this.show_event(ev); |
| } |
| //------------------------------------------------------ |
| |
| Calendar.prototype.get_month_events = function(call_back) { |
| // ret fn |
| var me = this; |
| var f = function(r, rt) { |
| if(me.cur_view) me.cur_view.refresh(); |
| if(call_back)call_back(); |
| } |
| |
| //load |
| var y=this.selected_date.getFullYear(); var m = this.selected_date.getMonth(); |
| if(!this.events[y] || !this.events[y][m]) { |
| $c('webnotes.widgets.event.load_month_events', args = { |
| 'month': m + 1, |
| 'year' : y}, |
| f); |
| } |
| } |
| //------------------------------------------------------ |
| |
| Calendar.prototype.get_daily_event_list=function(day) { |
| var el = []; |
| var d = day.getDate(); var m = day.getMonth(); var y = day.getFullYear() |
| if(this.events[y] && this.events[y][m] && |
| this.events[y][m][d]) { |
| var l = this.events[y][m][d] |
| for(var i in l) { |
| for(var j in l[i]) el[el.length] = l[i][j]; |
| } |
| return el; |
| } |
| else return []; |
| } |
| //------------------------------------------------------ |
| |
| Calendar.prototype.set_event = function(ev) { |
| // don't duplicate |
| if(this.events_by_name[ev.name]) { |
| return this.events_by_name[ev.name]; |
| } |
| |
| var dt = dateutil.str_to_obj(ev.event_date); |
| var m = dt.getMonth(); |
| var d = dt.getDate(); |
| var y = dt.getFullYear(); |
| |
| if(!this.events[y]) this.events[y] = []; |
| if(!this.events[y][m]) this.events[y][m] = []; |
| if(!this.events[y][m][d]) this.events[y][m][d] = []; |
| if(!this.events[y][m][d][cint(ev.event_hour)]) |
| this.events[y][m][d][cint(ev.event_hour)] = []; |
| |
| var cal_ev = new Calendar.CalEvent(ev, this); |
| this.events[y][m][d][cint(ev.event_hour)].push(cal_ev); |
| this.events_by_name[ev.name] = cal_ev; |
| |
| return cal_ev; |
| } |
| |
| //------------------------------------------------------ |
| |
| Calendar.prototype.refresh = function(viewtype){//Sets the viewtype of the Calendar and Calls the View class based on the viewtype |
| if(viewtype) |
| this.viewtype = viewtype; |
| // switch view if reqd |
| if(this.cur_view.viewtype!=this.viewtype) { |
| this.cur_view.hide(); |
| this.cur_view = this.views[this.viewtype]; |
| this.cur_view.in_home = false; // for home page |
| this.cur_view.show(); |
| } |
| else{ |
| this.cur_view.refresh(this); |
| } |
| } |
| |
| //------------------------------------------------------ |
| |
| Calendar.CalEvent= function(doc, cal) { |
| this.body = document.createElement('div'); |
| this.link = $a(this.body, 'a', '', {}, locals['Event'][doc.name].description || ''); |
| this.doc = doc; |
| var me = this; |
| |
| this.link.onclick = function() { |
| if(me.doc.name) { |
| cal.show_event(me.doc, me); |
| } |
| } |
| } |
| |
| Calendar.CalEvent.prototype.show = function(vu) { |
| |
| var t = this.doc.event_type; |
| this.my_class = 'cal_event_'+ t; |
| |
| if(this.body.parentNode) |
| this.body.parentNode.removeChild(this.body); |
| vu.body.appendChild(this.body); |
| |
| // refresh |
| this.link.innerHTML = this.doc.description || ''; |
| this.body.className = this.my_class; |
| } |
| |
| |
| // ---------- |
| |
| Calendar.View =function() { this.daystep = 0; this.monthstep = 0; } |
| Calendar.View.prototype.init=function(cal) { |
| this.cal = cal; |
| this.body = $a(cal.body, 'div', 'cal_view_body'); |
| this.body.style.display = 'none'; |
| this.create_table(); |
| } |
| |
| |
| Calendar.View.prototype.show=function() { |
| this.get_events(); this.refresh(); this.body.style.display = 'block'; |
| } |
| |
| Calendar.View.prototype.hide=function() { this.body.style.display = 'none';} |
| |
| Calendar.View.prototype.next = function() { |
| var s = this.cal.selected_date; |
| this.cal.selected_date = new Date(s.getFullYear(), s.getMonth() + this.monthstep, s.getDate() + this.daystep); |
| this.get_events(); this.refresh(); |
| } |
| |
| Calendar.View.prototype.prev = function() { |
| var s = this.cal.selected_date; |
| this.cal.selected_date = new Date(s.getFullYear(), s.getMonth() - this.monthstep, s.getDate() - this.daystep); |
| this.get_events(); this.refresh(); |
| } |
| |
| Calendar.View.prototype.get_events = function() { |
| this.cal.get_month_events(); |
| } |
| Calendar.View.prototype.add_unit = function(vu) { |
| this.viewunits[this.viewunits.length] = vu; |
| } |
| Calendar.View.prototype.refresh_units = function() { |
| // load the events |
| if(locals['Event']) { |
| for(var name in locals['Event']) { |
| this.cal.set_event(locals['Event'][name]); |
| } |
| } |
| |
| |
| for(var r in this.table.rows) { |
| for(var c in this.table.rows[r].cells) { |
| if(this.table.rows[r].cells[c].viewunit) { |
| this.table.rows[r].cells[c].viewunit.refresh(); |
| } |
| } |
| } |
| } |
| |
| // ................. Month View.......................... |
| Calendar.MonthView = function(cal) { this.init(cal); this.monthstep = 1; this.rows = 5; this.cells = 7; } |
| Calendar.MonthView.prototype=new Calendar.View(); |
| Calendar.MonthView.prototype.create_table = function() { |
| |
| // create head |
| this.head_wrapper = $a(this.body, 'div', 'cal_month_head'); |
| |
| // create headers |
| this.headtable = $a(this.head_wrapper, 'table', 'cal_month_headtable'); |
| var r = this.headtable.insertRow(0); |
| for(var j=0;j<7;j++) { |
| var cell = r.insertCell(j); |
| cell.innerHTML = erpnext.calendar.weekdays[j]; $w(cell, (100 / 7) + '%'); |
| } |
| |
| this.main = $a(this.body, 'div', 'cal_month_body'); |
| this.table = $a(this.main, 'table', 'cal_month_table'); |
| var me = this; |
| |
| // create body |
| for(var i=0;i<5;i++) { |
| var r = this.table.insertRow(i); |
| for(var j=0;j<7;j++) { |
| var cell = r.insertCell(j); |
| cell.viewunit = new Calendar.MonthViewUnit(cell); |
| } |
| } |
| } |
| |
| Calendar.MonthView.prototype.refresh = function() { |
| var c =this.cal.selected_date; |
| var me=this; |
| // fill other days |
| |
| var cur_row = 0; |
| |
| var cur_month = c.getMonth(); |
| var cur_year = c.getFullYear(); |
| |
| var d = new Date(cur_year, cur_month, 1); |
| var day = 1 - d.getDay(); |
| |
| |
| // set day headers |
| var d = new Date(cur_year, cur_month, day); |
| |
| this.cal.view_title.innerHTML = month_list_full[cur_month] + ' ' + cur_year; |
| |
| for(var i=0;i<6;i++) { |
| if((i<5) || cur_month==d.getMonth()) { // if this month |
| for(var j=0;j<7;j++) { |
| var cell = this.table.rows[cur_row].cells[j]; |
| |
| if((i<5) || cur_month==d.getMonth()) { // if this month |
| cell.viewunit.day = d; |
| cell.viewunit.hour = 8; |
| if(cur_month == d.getMonth()) { |
| cell.viewunit.is_disabled = false; |
| |
| if(same_day(this.cal.todays_date, d)) |
| cell.viewunit.is_today = true; |
| else |
| cell.viewunit.is_today = false; |
| |
| } else { |
| cell.viewunit.is_disabled = true; |
| } |
| } |
| // new date |
| day++; |
| d = new Date(cur_year, cur_month, day); |
| } |
| } |
| cur_row++; |
| if(cur_row == 5) {cur_row = 0;} // back to top |
| } |
| this.refresh_units(); |
| |
| } |
| // ................. Daily View.......................... |
| Calendar.DayView=function(cal){ this.init(cal); this.daystep = 1; } |
| Calendar.DayView.prototype=new Calendar.View(); |
| Calendar.DayView.prototype.create_table = function() { |
| |
| // create body |
| this.main = $a(this.body, 'div', 'cal_day_body'); |
| this.table = $a(this.main, 'table', 'cal_day_table'); |
| var me = this; |
| |
| for(var i=0;i<24;i++) { |
| var r = this.table.insertRow(i); |
| for(var j=0;j<2;j++) { |
| var cell = r.insertCell(j); |
| if(j==0) { |
| var tmp = time_to_ampm((i)+':00'); |
| cell.innerHTML = tmp[0]+':'+tmp[1]+' '+tmp[2]; |
| $w(cell, '10%'); |
| } else { |
| cell.viewunit = new Calendar.DayViewUnit(cell); |
| cell.viewunit.hour = i; |
| $w(cell, '90%'); |
| if((i>=7)&&(i<=20)) { |
| cell.viewunit.is_daytime = true; |
| } |
| } |
| } |
| } |
| } |
| |
| Calendar.DayView.prototype.refresh = function() { |
| var c =this.cal.selected_date; |
| |
| // fill other days |
| var me=this; |
| |
| this.cal.view_title.innerHTML = erpnext.calendar.weekdays[c.getDay()] + ', ' |
| + c.getDate() + ' ' + month_list_full[c.getMonth()] + ' ' + c.getFullYear(); |
| |
| // headers |
| var d = c; |
| |
| for(var i=0;i<24;i++) { |
| var cell = this.table.rows[i].cells[1]; |
| if(same_day(this.cal.todays_date, d)) cell.viewunit.is_today = true; |
| else cell.viewunit.is_today = false; |
| cell.viewunit.day = d; |
| } |
| this.refresh_units(); |
| } |
| |
| // ................. Weekly View.......................... |
| Calendar.WeekView=function(cal) { this.init(cal); this.daystep = 7; } |
| Calendar.WeekView.prototype=new Calendar.View(); |
| Calendar.WeekView.prototype.create_table = function() { |
| |
| // create head |
| this.head_wrapper = $a(this.body, 'div', 'cal_month_head'); |
| |
| // day headers |
| this.headtable = $a(this.head_wrapper, 'table', 'cal_month_headtable'); |
| var r = this.headtable.insertRow(0); |
| for(var j=0;j<8;j++) { |
| var cell = r.insertCell(j); |
| $w(cell, (100 / 8) + '%'); |
| } |
| |
| // hour header |
| |
| // create body |
| this.main = $a(this.body, 'div', 'cal_week_body'); |
| this.table = $a(this.main, 'table', 'cal_week_table'); |
| var me = this; |
| |
| for(var i=0;i<24;i++) { |
| var r = this.table.insertRow(i); |
| for(var j=0;j<8;j++) { |
| var cell = r.insertCell(j); |
| if(j==0) { |
| var tmp = time_to_ampm(i+':00'); |
| cell.innerHTML = tmp[0]+':'+tmp[1]+' '+tmp[2]; |
| |
| $w(cell, '10%'); |
| } else { |
| cell.viewunit = new Calendar.WeekViewUnit(cell); |
| cell.viewunit.hour = i; |
| if((i>=7)&&(i<=20)) { |
| cell.viewunit.is_daytime = true; |
| } |
| } |
| } |
| } |
| } |
| |
| Calendar.WeekView.prototype.refresh = function() { |
| var c =this.cal.selected_date; |
| // fill other days |
| var me=this; |
| |
| this.cal.view_title.innerHTML = month_list_full[c.getMonth()] + ' ' + c.getFullYear(); |
| |
| // headers |
| var d = new Date(c.getFullYear(), c.getMonth(), c.getDate() - c.getDay()); |
| |
| for (var k=1;k<8;k++) { |
| this.headtable.rows[0].cells[k].innerHTML = erpnext.calendar.weekdays[d.getDay()] + ' ' + d.getDate(); |
| |
| for(var i=0;i<24;i++) { |
| var cell = this.table.rows[i].cells[k]; |
| if(same_day(this.cal.todays_date, d)) |
| cell.viewunit.is_today = true; |
| else cell.viewunit.is_today = false; |
| |
| cell.viewunit.day = d; |
| //cell.viewunit.refresh(); |
| } |
| d=new Date(d.getFullYear(),d.getMonth(),d.getDate() + 1); |
| |
| } |
| |
| this.refresh_units(); |
| } |
| |
| //------------------------------------------------------. |
| |
| Calendar.ViewUnit = function() {} |
| Calendar.ViewUnit.prototype.init = function(parent) { |
| parent.style.border = "1px solid #CCC" ; |
| this.body = $a(parent, 'div', this.default_class); |
| this.parent = parent; |
| |
| var me = this; |
| this.body.onclick = function() { |
| erpnext.calendar.selected_date = me.day; |
| erpnext.calendar.selected_hour = me.hour; |
| |
| if(erpnext.calendar.cur_vu && erpnext.calendar.cur_vu!=me){ |
| erpnext.calendar.cur_vu.deselect(); |
| me.select(); |
| erpnext.calendar.cur_vu = me; |
| } |
| } |
| this.body.ondblclick = function() { |
| erpnext.calendar.add_event(); |
| } |
| } |
| |
| Calendar.ViewUnit.prototype.set_header=function(v) { |
| this.header.innerHTML = v; |
| } |
| |
| Calendar.ViewUnit.prototype.set_today = function() { |
| this.is_today = true; |
| this.set_display(); |
| } |
| |
| Calendar.ViewUnit.prototype.clear = function() { |
| if(this.header)this.header.innerHTML = ''; |
| |
| // clear body |
| while(this.body.childNodes.length) |
| this.body.removeChild(this.body.childNodes[0]); |
| } |
| |
| Calendar.ViewUnit.prototype.set_display = function() { |
| var cn = '#FFF'; |
| |
| // colors |
| var col_tod_sel = '#EEE'; |
| var col_tod = '#FFF'; |
| var col_sel = '#EEF'; |
| |
| if(this.is_today) { |
| if(this.selected) cn = col_tod_sel; |
| else cn = col_tod; |
| } else |
| if(this.selected) cn = col_sel; |
| |
| if(this.header) { |
| if(this.is_disabled) { |
| this.body.className = this.default_class + ' cal_vu_disabled'; |
| this.header.style.color = '#BBB'; |
| } else { |
| this.body.className = this.default_class; |
| this.header.style.color = '#000'; |
| } |
| |
| if(this.day&&this.day.getDay()==0) |
| this.header.style.backgroundColor = '#FEE'; |
| else |
| this.header.style.backgroundColor = ''; |
| } |
| this.parent.style.backgroundColor = cn; |
| } |
| |
| Calendar.ViewUnit.prototype.is_selected = function() { |
| return (same_day(this.day, erpnext.calendar.selected_date) |
| && this.hour==erpnext.calendar.selected_hour) |
| } |
| |
| Calendar.ViewUnit.prototype.get_event_list = function() { |
| var y = this.day.getFullYear(); |
| var m = this.day.getMonth(); |
| var d = this.day.getDate(); |
| if(erpnext.calendar.events[y] && erpnext.calendar.events[y][m] && |
| erpnext.calendar.events[y][m][d] && |
| erpnext.calendar.events[y][m][d][this.hour]) { |
| return erpnext.calendar.events[y][m][d][this.hour]; |
| } else |
| return []; |
| } |
| |
| Calendar.ViewUnit.prototype.refresh = function() { |
| this.clear(); |
| |
| if(this.is_selected()) { |
| if(erpnext.calendar.cur_vu)erpnext.calendar.cur_vu.deselect(); |
| this.selected = true; |
| erpnext.calendar.cur_vu = this; |
| } |
| this.set_display(); |
| this.el = this.get_event_list(); |
| if(this.onrefresh)this.onrefresh(); |
| |
| for(var i in this.el) { |
| this.el[i].show(this); |
| } |
| |
| var me = this; |
| } |
| |
| Calendar.ViewUnit.prototype.select=function() { this.selected = true; this.set_display(); } |
| Calendar.ViewUnit.prototype.deselect=function() { this.selected = false; this.set_display(); } |
| Calendar.ViewUnit.prototype.setevent=function() { } |
| |
| Calendar.MonthViewUnit=function(parent) { |
| this.header = $a(parent, 'div' , "cal_month_date"); |
| this.default_class = "cal_month_unit"; |
| |
| this.init(parent); |
| |
| this.onrefresh = function() { |
| this.header.innerHTML = this.day.getDate(); |
| } |
| } |
| Calendar.MonthViewUnit.prototype = new Calendar.ViewUnit(); |
| Calendar.MonthViewUnit.prototype.is_selected = function() { |
| return same_day(this.day, erpnext.calendar.selected_date) |
| } |
| |
| Calendar.MonthViewUnit.prototype.get_event_list = function() { |
| return erpnext.calendar.get_daily_event_list(this.day); |
| } |
| |
| Calendar.DayViewUnit= function(parent) { |
| this.default_class = "cal_day_unit"; this.init(parent); |
| } |
| Calendar.DayViewUnit.prototype = new Calendar.ViewUnit(); |
| Calendar.DayViewUnit.prototype.onrefresh = function() { |
| if(this.el.length<3) |
| this.body.style.height = '30px'; |
| else this.body.style.height = ''; |
| } |
| |
| Calendar.WeekViewUnit=function(parent) { |
| this.default_class = "cal_week_unit"; this.init(parent); |
| } |
| Calendar.WeekViewUnit.prototype = new Calendar.ViewUnit(); |
| Calendar.WeekViewUnit.prototype.onrefresh = function() { |
| if(this.el.length<3) this.body.style.height = '30px'; |
| else this.body.style.height = ''; |
| } |