var CalendarModuleMonth = function(date,dom,subpart,url){ _this = this; var events = {} var template = dom.find(".month_template"), month_names = ["Jan","Feb","March","April","May","June","July","Aug","Sep","Oct","Nov","Dec"], monthNames = ['January','February','March','April','May','June','July','August','September','October','November','December'], initialDate = date, subpartid = subpart, index_url = url, fetchInterval = null, month = date.getMonth(), year = date.getFullYear(), first_target_day = new Date(year,month,1), last_target_day = new Date(year,month+1,0), firstDay = new Date(year,month,1), lastDay = new Date(year,month+1,0), today = date.getDate(), last_inserted_date = 1, monthDom = $("
"), eventHTML = dom.find('div.calendar-events')[0], prevMonthFunc, nextMonthFunc, toggle_data; monthDom.html(template); var format_time = function(date){ var hours = date.getHours(), minutes = date.getMinutes(); if (hours < 10) {hours = "0"+hours} if (minutes < 10) {minutes = "0"+minutes} return hours+':'+minutes; } function rgb2hex(rgb) { rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); function hex(x) { return ("0" + parseInt(x).toString(16)).slice(-2); } if (rgb){ return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); }else{ return "#000000"; } } function lighten_color(my_hex,percent){ if (my_hex[0] == '#'){ my_hex = my_hex.slice(1) } var comp = '' var rgb = [] var batch_size = Math.ceil(my_hex.length/3) for (var i=0;i<3;i++){ rgb.push(my_hex.slice(batch_size*i,batch_size*(i+1))) } $.each(rgb,function(){ var a = this var tmp tmp = Math.ceil(parseInt(a,16)*(1+percent/100)) if (tmp>255) tmp = 255 if (tmp < 0) tmp = 0 tmp = tmp.toString(16) for (var i=0;i<2-tmp.length;i++){ tmp = '0' + tmp } comp = comp + tmp }) return '#'+comp } var format_date = function(date){ var y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate(); if (m < 10) {m = "0"+m} if (d < 10) {d = "0"+d} return y+'/'+m+'/'+d; } var formate_datetime = function(date){ date = new Date(date) return [format_date(date),format_time(date)] } $(window).resize(function(){ var window_w = $(window).width() $('.widget-calendar-1 div.calendar-events').each(function(){ var this_w = $(this).parents('.widget-calendar-1').width() if (this_w>=728 && window_w>=768){ if (!$(this).hasClass('width-50')){ $(this).removeClass('width-100') $(this).addClass('width-50') $(this).css('width','50%') $(this).parents('div[data-module="calendar"]').find('div').eq(0).css('width','50%') } }else{ if (!$(this).hasClass('width-100')){ $(this).addClass('width-100') $(this).removeClass('width-50') $(this).css('width','100%') $(this).parents('div[data-module="calendar"]').find('div').eq(0).css('width','100%') } } }) }) var show_event = function(date,ele){ var date_split = date.split('-') var event_div = $(ele).parents('div[data-module="calendar"]').find('div.calendar-events') event_div.find('.event-header').text(parseInt(date_split[2])+'/'+(parseInt(date_split[1])+1)+'/'+parseInt(date_split[0])) event_div.find('.event-container').remove() $(ele).parents('.w-calendar').find('td.shown').removeClass('shown') $(ele).addClass('shown') $.each(events[date],function(k,v){ var tp if (v.url_linked==''){ var time_string = '' if(v.allDay) { var end_time var start_time = formate_datetime(v.start)[0] if(v.end) end_time = formate_datetime(v.end)[0] else end_time = start_time time_string = (start_time==end_time ? "

" + start_time + "

" : " " + start_time + " " + end_time + "") }else{ var st = formate_datetime(v.start), et = formate_datetime(v.end), start_time = st[0], end_time = et[0], same = (start_time==end_time), etime = et[1], stime = st[1] time_string = (same ? "

" + start_time + "

" + stime + " " + etime : "

" + start_time + "" + stime + "

" + end_time + "" + etime + "

"); } var modal_tp = ('') tp = $('
'+modal_tp+'
') }else{ tp = $('
').attr('href',v.url_linked) } var sd = formate_datetime(v.start), ed = formate_datetime(v.end), duration = ''; if(v.allDay){ if (sd[0]!=ed[0]){ duration = sd[0]+'>'+ed[0] +'
' } }else if (sd[0]==ed[0]){ duration = sd[1]+'>'+ed[1] +'
' }else{ duration = sd[0]+' '+sd[1]+'>'+ed[0]+' '+ed[1] +'
' } tp.find('.event-info').html(duration+v.title+"
"+v.note+"
") tp.find('.event-bullet-event').css('background',v.color) event_div.find('.event-containers').append(tp) }) $(ele).parents('div[data-module="calendar"]').css('display','flex') if ($(ele).parents('div[data-module="calendar"]').width()>=728 && $(window).width()>=768){ event_div.css('width','50%') $(ele).parents('div[data-module="calendar"]').find('div').eq(0).css('width','50%') }else{ event_div.css('width','100%') $(ele).parents('div[data-module="calendar"]').find('div').eq(0).css('width','100%') } event_div.show() $('.close_box').off('click') $('.close_box').on('click',function(){ hide_event(this) }) } var hide_event = function(ele){ $(ele).parents('.w-calendar').find('td.shown').removeClass('shown') var event_div = $(ele).parents('div[data-module="calendar"]').find('div.calendar-events') $(ele).parents('div[data-module="calendar"]').css('display','block') $(ele).parents('div[data-module="calendar"]').find('div').eq(0).css('width','') event_div.hide() //$(ele).parents('div[data-module="calendar"]').find('td.w-calendar-toggle').removeClass('w-calendar-toggle') event_div.find('.event-container').remove() } var renderMonth = function(){ var num_of_rows = getNumberOfRows(), head_title = monthDom.find("h4 span.text"), table_body = monthDom.find("table.table tbody"); table_body.html(""); for(var i = 0; i < num_of_rows; i++){ var tr = null; if(i == 0){ tr = makeRow("first"); }else if(i == (num_of_rows - 1)){ tr = makeRow("last"); }else{ tr = makeRow("middle"); } if(tr == null){ break; } table_body.append(tr); head_title.text(monthNames[firstDay.getMonth()] + " " + firstDay.getFullYear()); } } var getNumberOfRows = function() { var day = 1, sat_counter = 0, sunday_counter = 0, date = new Date(year, month, day); while(date.getMonth() === month) { if(date.getDay() === 0) { sunday_counter++; }else if(date.getDay() === 6) { sat_counter++; } day++; date = new Date(year, month, day); } return (sunday_counter == 5 && sat_counter == 5 ? 6 : 5); } var makeRow = function(position){ if(last_inserted_date <= lastDay.getDate()){ var row = $(""); switch (position){ case "first": var first_line_first_day = new Date(year,month,firstDay.getDate()-firstDay.getDay()) var first_line_first_date = first_line_first_day.getDate() var first_line_first_month = first_line_first_day.getMonth() var first_line_first_year = first_line_first_day.getFullYear() first_target_day = new Date(first_line_first_year,first_line_first_month,first_line_first_date) for(var i = 0;i < 7;i++){ var td = $("
"); if(i >= firstDay.getDay()){ if(today != 0 && last_inserted_date == today){ td.addClass("w-calendar-today"); } td.find('div').text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; }else{ td.find('div').text(first_line_first_date+i) td.attr("data-date-node",(first_line_first_date+i)+"-"+first_line_first_month+"-"+first_line_first_year); td.addClass("w-calendar-other-month") } row.append(td); } break; case "middle": for(var i = 0;i < 7;i++){ var td = $("
"); if(today != 0 && last_inserted_date == today){ td.attr("class","w-calendar-today"); } td.find('div').text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; row.append(td); } break; case "last": var next_month = month+1, next_year = year; if (next_month==12){ next_month = 0; next_year = next_year + 1; } last_target_day = new Date(next_year,next_month,6-lastDay.getDay()) for(var i = 0;i < 7;i++){ var td = $("
"); if(i <= lastDay.getDay()){ if(today != 0 && last_inserted_date == today){ td.attr("class","w-calendar-today"); } td.find('div').text(last_inserted_date); td.attr("data-date-node",last_inserted_date+"-"+firstDay.getMonth()+"-"+firstDay.getFullYear()); last_inserted_date++; }else{ td.find('div').text(i-lastDay.getDay()) td.attr("data-date-node",(i-lastDay.getDay())+"-"+next_month+"-"+next_year); td.addClass("w-calendar-other-month") } row.append(td); } break; } }else{ var row = null; } return row; } function toggle_event(ele,type){ $(ele).parents('.month_template').find('td').removeClass('w-calendar-toggle') if ($(ele).length==1){ $(ele).addClass('w-calendar-toggle') toggle_data = $(ele).data('date-node') } var toggle_month = $(ele).data('date-node').split('-')[1] if (toggle_month==month || $(ele).length!=1){ if (type=='show'){ show_event($(ele).data('date-node'),ele) }else{ hide_event(ele) } } else if(toggle_month==month+1 || toggle_month==0){ nextMonthFunc(toggle_data) }else{ prevMonthFunc(toggle_data) } } var fetchEvents = function(){ var usd = Math.round(firstDay/1000), usd_target = Math.round(first_target_day/1000), ued_target = Math.round(last_target_day/1000); $.ajax({ url : "/xhr/calendars/agenda", data : {"month_start" : usd,"unix_start" : usd_target, "unix_end" : ued_target, "subpart_id" : subpartid, "locale" : $('html').attr('lang')}, dataType : "json", type : "get" }).done(function(data){ events = {} $(dom).find('.w-calendar-title span').eq(-1).html(data['calendar_title']) $.each(data.events,function(index,eve){ var sd = new Date(eve.start), ed = new Date(eve.end), sd_date = new Date(formate_datetime(eve.start)[0]), ed_date = new Date(formate_datetime(eve.end)[0]), timeDiff = ed_date.getTime() - sd_date.getTime(), dayDiff = Math.round(timeDiff / (1000 * 3600 * 24)); if(eve.allDay && dayDiff < 1){ dayDiff = 1 } if(dayDiff > 0){ var inserting_date = sd.getDate(); for(var i = 0;i <= dayDiff; i++){ var dt = inserting_date + "-" + month + "-" + year, td = dom.find("td[data-date-node=" + dt + "]"); if (events[dt]==undefined){ events[dt]=[] } events[dt].push(eve) td.addClass("w-calendar-event"); if(events[dt] && events[dt].length==1){ td.click(function(){ toggle_event(this,'show') }) } inserting_date++; if(inserting_date > lastDay.getDate() || (ed.getMonth() == month && inserting_date > ed.getDate())){ break; } } }else{ var dt = sd.getDate() + "-" + sd.getMonth() + "-" + sd.getFullYear(); td = dom.find("td[data-date-node=" + dt + "]"); if (events[dt]==undefined){ events[dt]=[] } events[dt].push(eve) if(events[dt] && events[dt].length==1){ td.click(function(){ toggle_event(this,'show') }) } td.addClass("w-calendar-event"); } }) if (!toggle_data){ if (dom.find('td.w-calendar-today').length != 0){ toggle_event(dom.find('td.w-calendar-today'),'show') }else{ toggle_event(dom.find('td'),'hide') } } dom.find('td:not(td.w-calendar-event)').click(function(){ toggle_event(this,'hide') }) var clicked_color = dom.find('.w-calendar-event').css('background-color') if (clicked_color){ clicked_color = lighten_color(rgb2hex(clicked_color),-45) if (clicked_color!='#000000'){ dom.find('table').append($('')) } } monthDom.find("i.loading").addClass("hide"); }) } this.currentMonth = function(){ renderMonth(); var div_tag = $('
') var widge_title = dom.find('.w-calendar-title').eq(0) div_tag.html(monthDom) div_tag.prepend(widge_title) dom.html(div_tag); monthDom.find("i.loading").removeClass("hide"); fetchInterval = setTimeout(fetchEvents,0); dom.find('div').eq(0).after(eventHTML) } this.nextMonth = function(toggle_flag){ clearTimeout(fetchInterval); monthDom.find("i.loading").removeClass("hide"); month++; if(month == 12){ year++; month = 0; } firstDay = new Date(year,month,1); lastDay = new Date(year,month+1,0); today = (initialDate.getMonth() == month && initialDate.getFullYear() == year ? initialDate.getDate() : 0); last_inserted_date = 1; var toggle_type,ele; if (toggle_data && toggle_flag){ ele = dom.find('td[data-date-node="'+toggle_data+'"]') toggle_type = (ele.hasClass('w-calendar-event') ? 'show' : 'hide') }else{ toggle_data = undefined } renderMonth(); dom.find("table.w-calendar-table tbody").html(monthDom.find("tbody").html()); if (ele){ ele = dom.find('td[data-date-node="'+toggle_data+'"]') toggle_event(ele,toggle_type) } fetchInterval = setTimeout(fetchEvents,300); } nextMonthFunc = this.nextMonth; this.prevMonth = function(toggle_flag){ clearTimeout(fetchInterval); monthDom.find("i.loading").removeClass("hide"); month--; if(month == -1){ year--; month = 11; } firstDay = new Date(year,month,1); lastDay = new Date(year,month+1,0); today = (initialDate.getMonth() == month && initialDate.getFullYear() == year ? initialDate.getDate() : 0); last_inserted_date = 1; var toggle_type,ele; if (toggle_data && toggle_flag){ ele = dom.find('td[data-date-node="'+toggle_data+'"]') toggle_type = (ele.hasClass('w-calendar-event') ? 'show' : 'hide') }else{ toggle_data = undefined } renderMonth(); dom.find("table.w-calendar-table tbody").html(monthDom.find("tbody").html()); if (ele){ ele = dom.find('td[data-date-node="'+toggle_data+'"]') toggle_event(ele,toggle_type) } fetchInterval = setTimeout(fetchEvents,300); } prevMonthFunc = this.prevMonth; }