Title / Description
Code $(function() { var pleaseEnterName = 'ПожалуйÑта, введите имÑ'; var pleaseChooseService = 'ПожалуйÑта, выберите ÑервиÑ'; $('#calendar_tabs a').click(function(){ var mode = $(this).attr('id'); $('#calendar_tabs a').removeAttr('class'); $(this).addClass('active'); scheduler.setCurrentView(scheduler._date,mode); }); function isWorkingHoursForEmployer(date, working_hours) { copyTimeValue = function (date, time) { var ndate = scheduler.date.copy(date); ndate.setHours(time.getHours(), time.getMinutes(), time.getSeconds(), 0); return ndate; } wd_parse = function(wd) { var convert = scheduler.date.str_to_date('%Y-%m-%d %H:%i:%s '); var min_time = scheduler.date.copy(date); min_time.setHours(23, 59, 59, 10); var max_time = scheduler.date.copy(date); max_time.setHours(0, 0, 1); return $.extend({}, { startTime: wd.from ? copyTimeValue(date, convert(wd.from.replace(/[T,Z]/gi, ' '))) : min_time, endTime: wd.to ? copyTimeValue(date, convert(wd.to.replace(/[T,Z]/gi, ' '))) : max_time }); }; var day_work = []; $.each(working_hours, function(index, val) { var tmp = $.grep(val, function (wh){ return wh[0].id == date.getDay(); })[0][0]; day_work.push(wd_parse(tmp)); }); return function(curTime) { for (var j = 0; j < day_work.length; j++) { if ((curTime >= day_work[j].startTime) && (curTime < day_work[j].endTime)) return true; } return false; }; } function AppointmentForm(child_codes, service_providers) { formatMinutes = function(minute) { var date = new Date(2000, 1, 1, 0, 0, 0); date = scheduler.date.add(date, parseInt(minute), "minute"); return scheduler.date.date_to_str("%H:%i")(date); }; return { init: function(id) { var self = this; this.event = scheduler.getEvent(id); this.id = id; this.edit_mode = this.event.service_provider_code !== undefined; this.errors = []; //for tmpl this.services = []; this.spChilds = []; self.display(); }, remove_event: function(){ delete scheduler._events[this.id]; scheduler.unselect(this.id); scheduler.event_updated(this.event); }, display: function() { if (!this.init_service_providers()) return this.remove_event(); $("#ph").html(ich.details_tmpl({ SpServices:this.services, spChilds: this.spChilds })); if (!this.edit_mode) this.observe_providers(); this.init_form_values(); this.init_clients(); this.observe_services(); this.add_button_listeners(); scheduler.startLightbox(this.id, $("#appointment_form").get(0)); }, init_service_providers: function() { var ev = this.event; if (this.edit_mode) { this.spChilds = [$.extend({}, { childCode: ev.service_provider_code, childName: service_providers[ev.service_provider_code].name })]; this.services = this.get_services(this.event.service_provider_code); return true; } //round minutes to step var minute = Math.round(ev.start_date.getMinutes()/scheduler.config.event_duration)*scheduler.config.event_duration; ev.start_date.setMinutes(0); ev.start_date = scheduler.date.add(ev.start_date, minute, "minute"); //Main service provider shoud be first in the list var spchilds = []; var isWork = isWorkingHoursForEmployer(ev.start_date, [service_providers[current_context_code].working_hours]); if (isWork(ev.start_date)) spchilds.push($.extend({}, { childCode: current_context_code, childName: service_providers[current_context_code].name})); $.each(child_codes, function(index, val) { isWork = isWorkingHoursForEmployer(ev.start_date, [service_providers[val].working_hours]); if (!isWork(ev.start_date)) return; spchilds.push($.extend({}, { childCode: val, childName: service_providers[val].name})); }); this.spChilds = spchilds; return spchilds.length > 0; }, is_valid: function() { this.errors = []; if (!parseInt($('#user_hidden').val())) { var name = $('#user_input').val(); if (name == pleaseEnterName) { this.errors.push("ПожалуйÑта, выберите клиента или введите его Ð¸Ð¼Ñ Ð¸ номер телефона"); // this.errors.push("Please, select a client or enter his/her name and phone number"); } if (name.indexOf(' ') <= 0) { this.errors.push("Ð˜Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° должно Ñодержать Ð¸Ð¼Ñ Ð¸ фамилию"); // this.errors.push("Client name should consist of first and last name"); } if ($('#phone').val().length == 0) { this.errors.push("Ðеобходимо ввеÑти номер телефона"); // this.errors.push("Phone can't be blank"); } } if (Number($('#services :selected').val()) <= 0) { this.errors.push("УÑлуга не выбрана"); // this.errors.push("Service is not selected"); } return this.errors.length == 0; }, display_errors: function() { var error_message = this.errors[0]; $('#errors').html('<div class="error">' + error_message + '</div>'); $('#submit_btn').removeAttr('disabled'); }, init_form_values: function() { if (this.edit_mode) $('#providers').attr('disabled', 'disabled'); else $('#providers').trigger('change'); var ev = this.event; $("#notes").text(ev.text); $('#price').text(ev.price); if (parseInt(ev.duration) > 0) $('#duration').attr("duration", ev.duration).text(formatMinutes(ev.duration)).show(); if (ev.service_provider_service_id !== undefined) { $("#services [value='" + ev.service_provider_service_id + "']").attr("selected", "selected").trigger("change"); } this.set_datetime_values(); }, set_datetime_values: function() { var startDt = $("#start_date"); var endDt = $("#end_date"); var dtpOptions = { step:{minutes:15}, dateFormat: 'dd-mm-yy', timeFormat: 'hh:mm' }; $(startDt).dateplustimepicker($.extend(dtpOptions, {altTimeField: '#start_time'})); $(startDt).dateplustimepicker("setDateTime", this.event.start_date); $(endDt).dateplustimepicker($.extend(dtpOptions, {altTimeField: '#end_time'})); $(endDt).dateplustimepicker("setDateTime", this.event.end_date); }, get_services: function(spcode) { if (service_providers[spcode].services === undefined) { var respond = this.request_services(spcode); $.extend(service_providers[spcode], {services: respond}); } var data = service_providers[spcode].services; var services = []; $.each(data, function(i, obj) { services.push($.extend({}, { srvId:obj.service_provider_service.id, srvName:obj.service_provider_service.name, srvPrice:obj.service_provider_service.visible_price, srvDuration:obj.service_provider_service.duration } )); }); return services; }, init_clients: function() { var ev = this.event; var options = {}; $('#phone').mask("(999) 999-9999"); options = {watermark:pleaseEnterName, width: 290, inputClass: "user_input"}; if (ev.user_name !== undefined && ev.user_name !== "") { $.extend(options, {initialValue:ev.user_name}); } $.extend(options, {onSelect:function() { var xhr = $.ajax("/".concat(service_provider_code, "/merchant_users/with_name_like.json")); var value = this.value; xhr.success(function(data) { var users = data.results; var selected_user = $.grep(users, function(u) { return u.name == value; }); $('#phone').val(selected_user[0].phone); $('#phone').attr('disabled', 'disabled'); }); }}); $("#user").empty().flexbox("/".concat(service_provider_code, "/merchant_users/with_name_like.json"), options); $('#user_input').keypress(function() { if ($(this).val() == '') { $('#phone').val(''); $('#phone').removeAttr('disabled', 'disabled'); } }); if (ev.user_id !== undefined) { $('#user_hidden').val(ev.user_id); $('#phone').val(ev.user_phone); } }, observe_providers: function() { var self = this; $('#providers').change(function(e) { setTimeout(function() { self.services = self.get_services($('#providers :selected').val()); var htm = "<option value='-1'>" + pleaseChooseService + "</option>"; $.each(self.services, function(index, val) { htm += "<option value='" + val.srvId + "'>" + val.srvName + "</option>"; }); $('#services').empty().html(htm).trigger('change'); }, 0); }); }, observe_services: function() { var self = this; $("#services").change(function(e) { var selected = Number($(e.target).val()); var svc = $.grep(self.services, function(serv) { return serv.srvId === selected; }); if (svc.length > 0) { $("#price").text(svc[0].srvPrice); $("#duration").attr("duration", svc[0].srvDuration).text(formatMinutes(svc[0].srvDuration)).show(); var edt = $('#start_date').dateplustimepicker("getDateTime"); $('#end_date').dateplustimepicker("setDateTime", edt.addMinutes(svc[0].srvDuration)); } else { $("#price").text("0.0"); $("#duration").attr("duration", 0).text(formatMinutes("0")); } }); }, add_button_listeners: function() { var ev = this.event; var self = this; $("#delete_btn").click(function() { scheduler.deleteEvent(scheduler._lightbox_id); scheduler.endLightbox(false, $("#appointment_form").get(0)); }); $("#submit_btn").click(function() { $(this).attr('disabled', 'disabled'); var params = self.get_form_values(); var add_event_callback = self.add_event; if (self.is_valid()) { if (!!parseInt(params['user_id'])) { self.add_event(params); } else { self.create_user(params, add_event_callback); } } else { self.display_errors(); } }); $("#cancel_btn").click(function() { scheduler.endLightbox(false, $("#appointment_form").get(0)); }); }, get_form_values: function() { var ev = this.event; return { id: ev.user_id !== undefined ? ev.id : null, start_date: $('#start_date').val() + ' ' + $('#start_time').val(), end_date: $('#end_date').val() + ' ' + $('#end_time').val(), user_id: $('#user_hidden').val(), user_phone: $('#phone').val(), user_name: $('#user_input').val(), price: $('#price').text(), duration: $('#duration').attr("duration"), notes: $('#notes').val(), service_id: $('#services :selected').val(), service_name: $('#services :selected').text(), service_provider_code: $('#providers :selected').val(), service_provider_id: service_providers[$('#providers :selected').val()].id + "" }; }, add_event: function(params) { var custom = { user_id: params['user_id'], service_provider_code: params['service_provider_code'], service_provider_id: params['service_provider_id'], service_provider_service_id: params['service_id'], service_provider_service_name: params['service_name'], user_name: params['user_name'], user_phone: params['user_phone'], duration: params['duration'], price: params['price'] }; scheduler.addEvent( this.edit_mode ? this.event.start_date : params['start_date'], this.edit_mode ? scheduler.date.add(this.event.start_date, parseInt(custom.duration), "minute") : params['end_date'], params['notes'], params['id'], custom); }, create_user: function(params, callback) { //creating user var self = this; var name_array = params['user_name'].split(' '); var first_name = name_array[0]; var last_name = name_array[name_array.length - 1]; var merchant_user = {"merchant_user":{ "user_attributes":{ first_name: first_name, last_name: last_name, phone: params['user_phone'] } } }; var jxhr = $.ajax({ type: 'POST', contentType: 'application/json', url: '/'.concat(service_provider_code, "/merchant_users"), data: JSON.stringify(merchant_user) }); jxhr.success(function(data) { params['user_id'] = data.user_id; callback.call(null, params); }); jxhr.error(function(data) { var response = JSON.parse(data.responseText); var messages = []; for (var prop in response) { messages = response[prop]; } self.errors.push("Ðевозможно Ñоздать пользователÑ: " + messages[0]); // self.errors.push("Can't create a user: " + messages[0]); self.display_errors(); }); }, request_services: function(sp_code) { var u = sp_code ? ("/services/provider_services.json?code=" + sp_code) : "/services.json"; var respond; $.ajax({ url: "/".concat(service_provider_code, u), dataType: "json", async: false, success: function (data) { respond = data; } }) return respond; //return $.getJSON("/".concat(service_provider_code, u)); } }; } function Calendar(providers_hash, childs) { var self = this; this.service_providers = providers_hash; this.service_provider_code = current_context_code; this.child_codes = childs; this.legend_child = []; this.setup = function() { var step,format; //Default length for employees visible list step = 15; scheduler.locale.labels.new_event = ""; scheduler.config.details_on_create = true; scheduler.config.details_on_dblclick = true; scheduler.config.dblclick_create = true; scheduler.config.xml_date = "%Y-%m-%d %H:%i"; scheduler.config.api_date = "%d-%m-%Y %H:%i"; scheduler.config.hour_date = "%H:%i";//"%h:%i %A"; scheduler.config.server_utc = false; scheduler.config.first_hour = 8; scheduler.config.last_hour = 20; scheduler.config.event_duration = step; format = scheduler.date.date_to_str("%H:%i"); scheduler.config.hour_size_px = (60 / step) * 21; scheduler.templates.hour_scale = function(date) { html = ""; for (var i = 0; i < 60 / step; i++) { html += "<div style='height:21px;line-height:21px;'>" + format(date) + "</div>"; date = scheduler.date.add(date, step, "minute"); } return html; }; scheduler.templates.event_class = function(start, end, event) { var index = -1; for (var i = 0; i < self.legend_child.length; i++) { if (event.service_provider_code == self.legend_child[i].code) { index = i%20; break; }; } return 'calendar_event_' + index; }; scheduler.templates.event_text = function(start, end, event) { var details = event.user_name || event.text; return "<b> " + ( event.service_provider_service_name || '') + "</b><br>" + details; }; scheduler.config.multi_day = true; scheduler.showLightbox = function(id) { var form = new AppointmentForm(self.child_codes, self.service_providers); form.init(id); }; }; this.render_scheduler = function() { this.setup(); attach_scheduler_handlers(); load_scheduler('', new Date); }; function setBlockTime() { var current_date = new Date(); var step = scheduler.config.event_duration; var vis_block = 60 * (scheduler.config.last_hour - scheduler.config.first_hour) / step; var whs = [self.service_providers[current_context_code].working_hours]; $.each(self.child_codes, function(index, val) { whs.push(self.service_providers[val].working_hours); }); for (var j = 0; j < 7; j++) { var isWork_hours = isWorkingHoursForEmployer(current_date, whs); var cur_time = scheduler.date.date_part(scheduler.date.copy(current_date)); cur_time.setHours(scheduler.config.first_hour); var last_minute = scheduler.config.first_hour*60; var _work = null; var block_time = []; for (var i = 0; i < vis_block; i++) { var work = isWork_hours(cur_time); if ((_work != null && _work != work) || (i + 1) == vis_block) { if ((i + 1) == vis_block) _work = work; if (!_work) block_time.push(last_minute, cur_time.getHours()*60 + cur_time.getMinutes() + ((i + 1) == vis_block ? step : 0)); last_minute = cur_time.getHours()*60 + cur_time.getMinutes(); } cur_time = scheduler.date.add(cur_time, step, "minute"); _work = work; } scheduler.blockTime(current_date.getDay(), block_time); current_date = scheduler.date.add(current_date, 1, "day"); } } function load_scheduler(query, date) { setBlockTime(); scheduler.init('scheduler_here', date, "week"); $.ajax({ url:'/'.concat(service_provider_code, '/appointments/appointments_with_child.xml?code=', current_context_code), dataType:'text', data: query, type:'GET' }).done(function(xmlData) { self.legend_child = [{ code: current_context_code, id: self.service_providers[current_context_code].id + "", name: self.service_providers[current_context_code].name, visible: true}]; $.each(self.child_codes, function(index, val) { var child = self.service_providers[val]; if (!child.has_appointment) return; self.legend_child.push({ code: val, id: child.id + "", name: child.name, visible: true}); }); reload_legend(); scheduler.parse(xmlData); }); } function refresh_calendar_view() { scheduler.setCurrentView(scheduler.getState().date, scheduler.getState().mode); } function reload_legend(newEventId) { legend_item = function(i, n) { return "<li><a href='#' onclick='return false;' " + (n.visible ? "class='active' " : "") + "id='" + n.code + "'" + "><div class='legend_item calendar_event_" + i%20 + "'><div class='color_box'></div>" + n.name + "</div></a></li>" } var ex; if (newEventId !== undefined) { var e = scheduler.getEvent(newEventId); ex = false; for (var i=0; i < self.legend_child.length; i++) { if (self.legend_child[i].code == e.service_provider_code) { ex = self.legend_child[i].visible = true; break; } }; if (!ex) { self.legend_child.push({ code: e.service_provider_code, id: self.service_providers[e.service_provider_code].id + "", name: self.service_providers[e.service_provider_code].name, visible: true }); } } var htm = ""; $.each(self.legend_child, function(index, val) { htm += legend_item(index, val); }); $("#calendar_legend").empty(); if (self.legend_child.length > 1) { $("#calendar_legend").html(htm).find("a").click(function() { var code = $(this).toggleClass('active').attr("id"); for (var i = 0; i < self.legend_child.length; i++) { if (code == self.legend_child[i].code) { self.legend_child[i].visible = !self.legend_child[i].visible; break; } } scheduler.filter_week = function(eventId) { var ev = scheduler.getEvent(eventId); for (var j = 0; j < self.legend_child.length; j++) if (ev.service_provider_code == self.legend_child[j].code && !self.legend_child[j].visible) return false; return true; }; scheduler.filter_month = scheduler.filter_day = scheduler.filter_week; refresh_calendar_view(); }); refresh_calendar_view(); } } /* function genWorkingTimeHTML_Appearance(day) { var current_date = day; var step = scheduler.config.event_duration; var vis_block = 60 * (scheduler.config.last_hour - scheduler.config.first_hour) / step; var whs = [self.service_providers[current_context_code].working_hours]; $.each(self.child_codes, function(index, val) { whs.push(self.service_providers[val].working_hours); }); var isWork_hours = isWorkingHoursForEmployer(current_date, whs); var start_date = scheduler.date.date_part(scheduler.date.copy(current_date)); start_date.setHours(scheduler.config.first_hour); var cur_time = scheduler.date.copy(start_date); var html = ""; var row_h = 21; var cur_h = 0; var _work = null; for (var i = 0; i < vis_block; i++) { var work = isWork_hours(cur_time); if ((_work != null && _work != work) || (i + 1) == vis_block) { if ((i + 1) == vis_block) { _work = work; cur_h += row_h; } var td_class = "class='dhx_cal_sec " + (_work ? "" : "grayed") + "' "; td_class += "style='height: " + (cur_h - 2) + "px;' "; html += "<div " + td_class + "></div>"; cur_h = 0; } cur_time = scheduler.date.add(cur_time, step, "minute"); cur_h += row_h; _work = work; } return html; } */ function attach_scheduler_handlers() { add_timezone_offset = function (dateTime, back) { var offset = dateTime.getTimezoneOffset() * (back ? -1 : 1); return scheduler.date.add(scheduler.date.copy(dateTime), offset, "minute"); } correct_event_timezone = function (evenId) { scheduler._events[evenId].start_date = add_timezone_offset(scheduler._events[evenId].start_date); scheduler._events[evenId].end_date = add_timezone_offset(scheduler._events[evenId].end_date); scheduler.updateEvent(evenId); }; scheduler.attachEvent("onEventAdded", function(event_id, event_object) { var appointment = {}; var appDetail = {}; $.extend(appDetail, { service_provider_service_id:event_object.service_provider_service_id, service_provider_id: event_object.service_provider_id, start_date:event_object.start_date, notes:event_object.text, user_id:event_object.user_id, price:event_object.price }); $.extend(appointment, {appointment:appDetail}); var jxhr = $.ajax({ type: 'POST', contentType: 'application/json', url: '/'.concat(service_provider_code, "/appointments.json"), data: JSON.stringify(appointment) }); jxhr.success(function(data) { var newId = data.appointment.id; scheduler.changeEventId(event_id, newId); correct_event_timezone(newId); scheduler.endLightbox(false, $("#appointment_form").get(0)); reload_legend(newId); }); jxhr.error(function(data) { try { delete scheduler._events[event_id]; scheduler.unselect(event_id); scheduler.event_updated(event_object); } catch (err) {}; handle_errors(data); }); }); scheduler.attachEvent("onEventChanged", function(event_id, event_object) { var appointment = {}; var appDetail = {}; $.extend(appDetail, { start_date: add_timezone_offset(event_object.start_date, true), notes: event_object.text, end_date: add_timezone_offset(event_object.end_date, true), service_provider_service_id: event_object.service_provider_service_id, service_provider_id: event_object.service_provider_id, user_id:event_object.user_id, price:event_object.price }); $.extend(appointment, {appointment:appDetail}); var jxhr = $.ajax({ type: 'PUT', contentType: 'application/json', url: '/'.concat(service_provider_code, "/appointments/", event_id, ".json"), data: JSON.stringify(appointment) }); jxhr.success(function(data) { //correct_event_timezone(data.appointment.id); scheduler.endLightbox(false, $("#appointment_form").get(0)); }); jxhr.error(function(data) { handle_errors(data); }); }); scheduler.attachEvent("onBeforeEventDelete", function(event_id, event_object) { var jxhr = $.ajax({ type: 'DELETE', contentType: 'application/json', url: '/'.concat(service_provider_code, "/appointments/", event_id, ".json") }); jxhr.success(function() { delete scheduler._events[event_id]; scheduler.unselect(event_id); scheduler.event_updated(event_object); }); jxhr.error(function(data) { alert('error in ajax'); return true; }); }); scheduler.attachEvent("onViewChange", function (mode , date){ //set to readonly month view var isMonthMode = mode == "month"; scheduler.config.readonly = isMonthMode; scheduler.config.drag_move = scheduler.config.dblclick_create = scheduler.config.details_on_create = scheduler.config.details_on_dblclick = !isMonthMode; }); /* scheduler.attachEvent("onScaleAdd", function(area, day){ if ($.inArray(scheduler.getState().mode, ["day", "week"]) >= 0) { area.innerHTML += genWorkingTimeHTML_Appearance(day); } });*/ scheduler.attachEvent("onTemplatesReady", function(){ scheduler.templates.api_date = scheduler.date.str_to_date(scheduler.config.api_date, true); }); } function handle_errors(data) { var error_message; if (data.responseText.match(/\{.*\}/)) { error_message = $.parseJSON(data.responseText)['base']; } else { // TODO should be handled more carefully error_message = "Server Error:" + data.responseText; } $('#errors').html('<div class="error">' + error_message + '</div>'); } } var service_provider_code = $("#calendar_page").attr("service_provider_code"); var current_context_code = $("#calendar_page").attr("current_context_provider_code"); $.getJSON("/".concat("service_providers/employees_id.json?id=", current_context_code), function(data) { var service_providers = {}; var child_codes = []; $.each(data, function(index, val) { service_providers[val.code] = val; if (val.code != current_context_code) child_codes.push(val.code); }); var calendar = new Calendar(service_providers, child_codes); calendar.render_scheduler(); }); });
Author
Highlight as C C++ CSS Clojure Delphi ERb Groovy (beta) HAML HTML JSON Java JavaScript PHP Plain text Python Ruby SQL XML YAML diff code