1 /*********************************************************************************
2 * SugarCRM Community Edition is a customer relationship management program developed by
3 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Affero General Public License version 3 as published by the
7 * Free Software Foundation with the addition of the following permission added
8 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
9 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
10 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * You should have received a copy of the GNU Affero General Public License along with
18 * this program; if not, see http://www.gnu.org/licenses or write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
23 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25 * The interactive user interfaces in modified source and object code versions
26 * of this program must display Appropriate Legal Notices, as required under
27 * Section 5 of the GNU Affero General Public License version 3.
29 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
30 * these Appropriate Legal Notices must retain the display of the "Powered by
31 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
32 * technical reasons, the Appropriate Legal Notices must display the words
33 * "Powered by SugarCRM".
34 ********************************************************************************/
38 //////////////////////////////////////////////////
39 // class: SugarWidgetListView
40 // widget to display a list view
42 //////////////////////////////////////////////////
44 SugarClass.inherit("SugarWidgetListView","SugarClass");
46 function SugarWidgetListView() {
50 SugarWidgetListView.prototype.init = function() {
54 SugarWidgetListView.prototype.load = function(parentNode) {
55 this.parentNode = parentNode;
59 SugarWidgetListView.prototype.display = function() {
61 if(typeof GLOBAL_REGISTRY['result_list'] == 'undefined') {
62 this.display_loading();
66 var div = document.getElementById('list_div_win');
67 div.style.display = 'block';
68 //div.style.height='125px';
69 var html = '<table width="100%" cellpadding="0" cellspacing="0" border="0" class="list view">';
71 html += '<th width="2%" nowrap="nowrap"> </th>';
72 html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_NAME']+'</th>';
73 html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_EMAIL']+'</th>';
74 html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_PHONE']+'</th>';
75 html += '<th width="18%" nowrap="nowrap"> </th>';
77 //var html = '<table width="100%" cellpadding="0" cellspacing="0">';
78 for(var i=0;i<GLOBAL_REGISTRY['result_list'].length;i++) {
79 var bean = GLOBAL_REGISTRY['result_list'][i];
81 var className='evenListRowS1';
83 if(typeof(GLOBAL_REGISTRY.focus.users_arr_hash[ bean.fields.id]) != 'undefined') {
87 className='oddListRowS1';
89 className='evenListRowS1';
91 if(typeof (bean.fields.first_name) == 'undefined') {
92 bean.fields.first_name = '';
94 if(typeof (bean.fields.email1) == 'undefined' || bean.fields.email1 == "") {
95 bean.fields.email1 = ' ';
97 if(typeof (bean.fields.phone_work) == 'undefined' || bean.fields.phone_work == "") {
98 bean.fields.phone_work = ' ';
101 html += '<tr class="'+className+'">';
102 html += '<td><img src="'+GLOBAL_REGISTRY.config['site_url']+'/index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName='+bean.module+'s.gif"/></td>';
103 html += '<td>'+bean.fields.full_name+'</td>';
104 html += '<td>'+bean.fields.email1+'</td>';
105 html += '<td>'+bean.fields.phone_work+'</td>';
106 html += '<td align="right">';
107 // hidden = 'hidden';
110 // hidden = 'visible';
112 html += '<input type="button" id="invitees_add_'+(i+1)+'" class="button" onclick="this.disabled=true;SugarWidgetSchedulerAttendees.form_add_attendee('+i+');" value="'+GLOBAL_REGISTRY['meeting_strings']['LBL_ADD_BUTTON']+'"/ style="visibility: '+hidden+'"/>';
118 //this.parentNode.innerHTML = html;
120 div.innerHTML = html;
123 SugarWidgetListView.prototype.display_loading = function() {
127 //////////////////////////////////////////////////
128 // class: SugarWidgetSchedulerSearch
129 // widget to display the meeting scheduler search box
131 //////////////////////////////////////////////////
133 SugarClass.inherit("SugarWidgetSchedulerSearch","SugarClass");
135 function SugarWidgetSchedulerSearch() {
139 SugarWidgetSchedulerSearch.prototype.init = function() {
140 this.form_id = 'scheduler_search';
141 GLOBAL_REGISTRY['widget_element_map'] = new Object();
142 GLOBAL_REGISTRY['widget_element_map'][this.form_id] = this;
143 GLOBAL_REGISTRY.scheduler_search_obj = this;
146 SugarWidgetSchedulerSearch.prototype.load = function(parentNode) {
147 this.parentNode = parentNode;
151 SugarWidgetSchedulerSearch.submit = function(form) {
153 SugarWidgetSchedulerSearch.hideCreateForm();
155 //construct query obj:
156 var conditions = new Array();
158 if(form.search_first_name.value != '') {
159 conditions[conditions.length] = {"name":"first_name","op":"starts_with","value":form.search_first_name.value}
161 if(form.search_last_name.value != '') {
162 conditions[conditions.length] = {"name":"last_name","op":"starts_with","value":form.search_last_name.value}
164 if(form.search_email.value != '') {
165 conditions[conditions.length] = {"name":"email1","op":"starts_with","value":form.search_email.value}
168 var query = {"modules":["Users","Contacts"
170 ],"group":"and","field_list":['id','full_name','email1','phone_work'],"conditions":conditions};
171 global_request_registry[req_count] = [this,'display'];
172 req_id = global_rpcClient.call_method('query',query);
173 global_request_registry[req_id] = [ GLOBAL_REGISTRY['widget_element_map'][form.id],'refresh_list'];
176 SugarWidgetSchedulerSearch.prototype.refresh_list = function(rslt) {
178 GLOBAL_REGISTRY['result_list'] = rslt['list'];
180 if (rslt['list'].length > 0) {
181 this.list_view.display();
182 document.getElementById('empty-search-message').style.display = 'none';
184 document.getElementById('list_div_win').style.display = 'none';
185 document.getElementById('empty-search-message').style.display = '';
190 SugarWidgetSchedulerSearch.prototype.display = function() {
192 // append the list_view as the third row of the outside table
193 var html = document.createElement("div");
194 html.setAttribute('class','schedulerInvitees');
196 var h3 = document.createElement("h3");
197 h3.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_ADD_INVITEE'];
198 html.appendChild(h3);
200 var table1 = document.createElement("table");
201 table1.setAttribute('class','edit view');
202 table1.setAttribute('border','0');
203 table1.setAttribute('cellpadding','0');
204 table1.setAttribute('cellspacing','0');
205 table1.setAttribute('width','100%');
206 var row1 = table1.insertRow(0);
207 var cell1 = row1.insertCell(0);
209 var form = document.createElement("form");
210 form.setAttribute('name','schedulerwidget');
211 form.setAttribute('id',this.form_id);
212 form.setAttribute('onsubmit','SugarWidgetSchedulerSearch.submit(this);return false;');
214 var table2 = document.createElement("table");
215 table2.setAttribute('border','0');
216 table2.setAttribute('cellpadding','0');
217 table2.setAttribute('cellspacing','0');
218 table2.setAttribute('width','100%');
220 var row2 = table2.insertRow(0);
221 var cell21 = row2.insertCell(0);
222 cell21.setAttribute('scope','col');
223 cell21.setAttribute('nowrap','nowrap');
225 var label1 = document.createElement("label");
226 label1.setAttribute('for','search_first_name');
227 label1.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_FIRST_NAME']+': ';
228 cell21.appendChild(label1);
230 var input1 = document.createElement("input");
231 input1.setAttribute('name','search_first_name');
232 input1.setAttribute('id','search_first_name');
233 input1.setAttribute('value','');
234 input1.setAttribute('type','text');
235 input1.setAttribute('size','10');
236 cell21.appendChild(input1);
238 var cell22 = row2.insertCell(1);
239 cell22.setAttribute('scope','col');
240 cell22.setAttribute('nowrap','nowrap');
242 var label2 = document.createElement("label");
243 label2.setAttribute('for','search_last_name');
244 label2.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_LAST_NAME']+': ';
245 cell22.appendChild(label2);
247 var input2 = document.createElement("input");
248 input2.setAttribute('name','search_last_name');
249 input2.setAttribute('id','search_last_name');
250 input2.setAttribute('value','');
251 input2.setAttribute('type','text');
252 input2.setAttribute('size','10');
253 cell22.appendChild(input2);
255 var cell23 = row2.insertCell(2);
256 cell23.setAttribute('scope','col');
257 cell23.setAttribute('nowrap','nowrap');
259 var label3 = document.createElement("label");
260 label3.setAttribute('for','search_email');
261 label3.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_EMAIL']+': ';
262 cell23.appendChild(label3);
264 var input3 = document.createElement("input");
265 input3.setAttribute('name','search_email');
266 input3.setAttribute('id','search_email');
267 input3.setAttribute('value','');
268 input3.setAttribute('type','text');
269 input3.setAttribute('size','10');
270 cell23.appendChild(input3);
272 var cell24 = row2.insertCell(3);
273 cell24.setAttribute('valign','center');
275 var input3 = document.createElement("input");
276 input3.setAttribute('class','button');
277 input3.setAttribute('id','invitees_search');
278 input3.setAttribute('value',GLOBAL_REGISTRY['meeting_strings']['LBL_SEARCH_BUTTON']);
279 input3.setAttribute('type','submit');
280 cell24.appendChild(input3);
282 form.appendChild(table2);
283 cell1.appendChild(form);
284 html.appendChild(table1);
286 this.parentNode.appendChild(html);
288 var div = document.createElement('div');
289 div.setAttribute('id','list_div_win');
290 div.style.overflow = 'auto';
291 div.style.width = '100%';
292 div.style.height= '100%';
293 div.style.display = 'none';
294 this.parentNode.appendChild(div);
296 var create_invitees = document.createElement("div");
297 create_invitees.setAttribute('id','create-invitees');
298 create_invitees.setAttribute('style','margin-bottom: 10px;');
300 var empty_search_message = document.createElement("div");
301 empty_search_message.setAttribute('id','empty-search-message');
302 empty_search_message.setAttribute('style','display: none;');
303 empty_search_message.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_EMPTY_SEARCH_RESULT'];
304 create_invitees.appendChild(empty_search_message);
306 var h3 = document.createElement("h3");
307 h3.setAttribute('id', 'create-invitees-title');
308 h3.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_CREATE_INVITEE'];
309 create_invitees.appendChild(h3);
311 var create_invitees_buttons = document.createElement("div");
312 create_invitees_buttons.setAttribute('id','create-invitees-buttons');
314 var button1 = document.createElement("button");
315 button1.setAttribute('id', 'create_invitee_as_contact');
316 button1.setAttribute('type', 'button');
317 button1.setAttribute('onclick', 'SugarWidgetSchedulerSearch.showCreateForm(\'Contacts\');');
318 button1.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_CREATE_CONTACT'];
319 create_invitees_buttons.appendChild(button1);
321 var button2 = document.createElement("button");
322 button2.setAttribute('id', 'create_invitee_as_lead');
323 button2.setAttribute('type', 'button');
324 button2.setAttribute('onclick', 'SugarWidgetSchedulerSearch.showCreateForm(\'Leads\');');
325 button2.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_CREATE_LEAD'];
326 create_invitees_buttons.appendChild(button2);
327 create_invitees.appendChild(create_invitees_buttons);
329 var create_invitee_edit = document.createElement("div");
330 create_invitee_edit.setAttribute('id','create-invitee-edit');
331 create_invitee_edit.setAttribute('style','display: none;');
333 var form1 = document.createElement("form");
334 form1.setAttribute('name','createInviteeForm');
335 form1.setAttribute('id','createInviteeForm');
336 form1.setAttribute('onsubmit','SugarWidgetSchedulerSearch.createInvitee(this); return false;');
338 var input4 = document.createElement("input");
339 input4.setAttribute('name','inviteeModule');
340 input4.setAttribute('value','Contacts');
341 input4.setAttribute('type','hidden');
342 form1.appendChild(input4);
344 var table3 = document.createElement("table");
345 table3.setAttribute('class','edit view');
346 table3.setAttribute('cellpadding','0');
347 table3.setAttribute('cellspacing','0');
348 table3.setAttribute('style','width: 330px; margin-top: 2px;');
350 var row3 = table3.insertRow(0);
351 var cell31 = row3.insertCell(0);
352 cell31.setAttribute('valign','top');
353 cell31.setAttribute('width','33%');
354 cell31.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_FIRST_NAME']+':';
356 var cell32 = row3.insertCell(1);
357 cell32.setAttribute('valign','top');
359 var input5 = document.createElement("input");
360 input5.setAttribute('name','first_name');
361 input5.setAttribute('size','19');
362 input5.setAttribute('type','text');
363 cell32.appendChild(input5);
365 var row4 = table3.insertRow(1);
366 var cell41 = row4.insertCell(0);
367 cell41.setAttribute('valign','top');
368 cell41.setAttribute('width','33%');
369 cell41.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_LAST_NAME']+':';
371 var cell42 = row4.insertCell(1);
372 cell42.setAttribute('valign','top');
374 var input6 = document.createElement("input");
375 input6.setAttribute('name','last_name');
376 input6.setAttribute('size','19');
377 input6.setAttribute('type','text');
378 cell42.appendChild(input6);
380 var row5 = table3.insertRow(2);
381 var cell51 = row5.insertCell(0);
382 cell51.setAttribute('valign','top');
383 cell51.setAttribute('width','33%');
384 cell51.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_EMAIL']+':';
386 var cell52 = row5.insertCell(1);
387 cell52.setAttribute('valign','top');
389 var input7 = document.createElement("input");
390 input7.setAttribute('name','email1');
391 input7.setAttribute('size','19');
392 input7.setAttribute('type','text');
393 cell52.appendChild(input7);
395 form1.appendChild(table3);
397 var button3 = document.createElement("button");
398 button3.setAttribute('id', 'create-invitee-btn');
399 button3.setAttribute('type', 'button');
400 button3.setAttribute('onclick', 'SugarWidgetSchedulerSearch.createInvitee(this.form);');
401 button3.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_CREATE_AND_ADD'];
402 form1.appendChild(button3);
404 var button4 = document.createElement("button");
405 button4.setAttribute('id', 'cancel-create-invitee-btn');
406 button4.setAttribute('type', 'button');
407 button4.setAttribute('onclick', 'SugarWidgetSchedulerSearch.hideCreateForm();');
408 button4.innerHTML = GLOBAL_REGISTRY['meeting_strings']['LBL_CANCEL_CREATE_INVITEE'];
409 form1.appendChild(button4);
411 create_invitee_edit.appendChild(form1);
412 create_invitees.appendChild(create_invitee_edit);
413 this.parentNode.appendChild(create_invitees);
415 addToValidate('createInviteeForm', 'last_name', 'last_name', true, GLOBAL_REGISTRY['meeting_strings']['LBL_LAST_NAME']);
417 this.list_view = new SugarWidgetListView();
418 this.list_view.load(div);
421 SugarWidgetSchedulerSearch.showCreateForm = function(module){
422 document.getElementById('create-invitee-edit').style.display = '';
423 document.getElementById('create-invitees-buttons').style.display = 'none';
424 document.getElementById('list_div_win').style.display = 'none';
425 document.forms['createInviteeForm'].elements['inviteeModule'].value = module;
427 document.getElementById('empty-search-message').style.display = 'none';
429 if (typeof document.createInviteeForm.first_name != 'undefined' && typeof document.schedulerwidget.search_first_name != 'undefined')
430 document.createInviteeForm.first_name.value = document.schedulerwidget.search_first_name.value;
431 if (typeof document.createInviteeForm.last_name != 'undefined' && typeof document.schedulerwidget.search_last_name != 'undefined')
432 document.createInviteeForm.last_name.value = document.schedulerwidget.search_last_name.value;
433 if (typeof document.createInviteeForm.email1 != 'undefined' && typeof document.schedulerwidget.search_email != 'undefined')
434 document.createInviteeForm.email1.value = document.schedulerwidget.search_email.value;
438 SugarWidgetSchedulerSearch.hideCreateForm = function(module){
439 document.getElementById('create-invitee-edit').style.display = 'none';
440 document.getElementById('create-invitees-buttons').style.display = '';
442 document.forms['createInviteeForm'].reset();
445 SugarWidgetSchedulerSearch.resetSearchForm = function() {
446 if(GLOBAL_REGISTRY.scheduler_search_obj && document.forms[GLOBAL_REGISTRY.scheduler_search_obj.form_id]) {
447 //if search form is initiated, it clears the input fields.
448 document.forms[GLOBAL_REGISTRY.scheduler_search_obj.form_id].reset();
452 SugarWidgetSchedulerSearch.createInvitee = function(form){
453 if(!(check_form('createInviteeForm'))){
457 document.getElementById('create-invitee-btn').setAttribute('disabled', 'disabled');
458 document.getElementById('cancel-create-invitee-btn').setAttribute('disabled', 'disabled');
460 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVING'));
463 success: function (response) {
465 var rObj = eval("("+response.responseText+")");
467 ajaxStatus.hideStatus();
469 if (typeof rObj.noAccess != 'undefined') {
470 var alertMsg = GLOBAL_REGISTRY['meeting_strings']['LBL_NO_ACCESS'];
471 alertMsg = alertMsg.replace("\$module", rObj.module);
472 SugarWidgetSchedulerSearch.hideCreateForm();
477 GLOBAL_REGISTRY.focus.users_arr[GLOBAL_REGISTRY.focus.users_arr.length] = rObj;
478 GLOBAL_REGISTRY.scheduler_attendees_obj.display();
480 SugarWidgetSchedulerSearch.hideCreateForm();
481 //Bug#51357: Reset the search input fields after invitee is added.
482 SugarWidgetSchedulerSearch.resetSearchForm();
484 document.getElementById('create-invitee-btn').removeAttribute('disabled');
485 document.getElementById('cancel-create-invitee-btn').removeAttribute('disabled');
489 var fieldList = ['id', 'full_name', 'email1', 'phone_work'];
492 for (i in fieldList) {
493 t.push("fieldList[]=" + encodeURIComponent(fieldList[i]));
495 var postData = t.join("&");
497 var url = "index.php?module=Calendar&action=CreateInvitee&sugar_body_only=true";
498 YAHOO.util.Connect.setForm(document.forms['createInviteeForm']);
499 YAHOO.util.Connect.asyncRequest('POST', url, callback, postData);
503 //////////////////////////////////////////////////
504 // class: SugarWidgetScheduler
505 // widget to display the meeting scheduler
507 //////////////////////////////////////////////////
509 SugarClass.inherit("SugarWidgetScheduler","SugarClass");
511 function SugarWidgetScheduler() {
515 SugarWidgetScheduler.prototype.init = function() {
516 //var row = new SugarWidgetScheduleAttendees();
520 SugarWidgetScheduler.prototype.load = function(parentNode) {
521 this.parentNode = parentNode;
525 SugarWidgetScheduler.fill_invitees = function(form) {
526 for(var i=0;i<GLOBAL_REGISTRY.focus.users_arr.length;i++) {
527 if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'User') {
528 form.user_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
529 } else if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'Contact') {
530 form.contact_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
531 } else if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'Lead') {
532 form.lead_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
537 SugarWidgetScheduler.update_time = function() {
540 if(typeof document.EditView != 'undefined')
541 form_name = "EditView";
542 else if(typeof document.CalendarEditView != 'undefined')
543 form_name = "CalendarEditView";
547 //check for field value, we can't do anything if it doesnt exist.
548 if(typeof document.forms[form_name].date_start == 'undefined')
551 var date_start = document.forms[form_name].date_start.value;
552 if(date_start.length < 16) {
555 var hour_start = parseInt(date_start.substring(11,13), 10);
556 var minute_start = parseInt(date_start.substring(14,16), 10);
557 var has_meridiem = /am|pm/i.test(date_start);
559 var meridiem = trim(date_start.substring(16));
562 GLOBAL_REGISTRY.focus.fields.date_start = date_start;
565 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start + meridiem;
567 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start;
570 GLOBAL_REGISTRY.focus.fields.duration_hours = document.forms[form_name].duration_hours.value;
571 GLOBAL_REGISTRY.focus.fields.duration_minutes = document.forms[form_name].duration_minutes.value;
572 GLOBAL_REGISTRY.focus.fields.datetime_start = SugarDateTime.mysql2jsDateTime(GLOBAL_REGISTRY.focus.fields.date_start,GLOBAL_REGISTRY.focus.fields.time_start);
574 GLOBAL_REGISTRY.scheduler_attendees_obj.init();
575 GLOBAL_REGISTRY.scheduler_attendees_obj.display();
578 SugarWidgetScheduler.prototype.display = function() {
579 this.parentNode.innerHTML = '';
581 var attendees = new SugarWidgetSchedulerAttendees();
582 attendees.load(this.parentNode);
584 var search = new SugarWidgetSchedulerSearch();
585 search.load(this.parentNode);
589 //////////////////////////////////////////////////
590 // class: SugarWidgetSchedulerAttendees
591 // widget to display the meeting attendees and availability
593 //////////////////////////////////////////////////
595 SugarClass.inherit("SugarWidgetSchedulerAttendees","SugarClass");
597 function SugarWidgetSchedulerAttendees() {
601 SugarWidgetSchedulerAttendees.prototype.init = function() {
604 if(typeof document.EditView != 'undefined')
605 form_name = "EditView";
606 else if(typeof document.CalendarEditView != 'undefined')
607 form_name = "CalendarEditView";
611 // this.datetime = new SugarDateTime();
612 GLOBAL_REGISTRY.scheduler_attendees_obj = this;
613 var date_start = document.forms[form_name].date_start.value;
614 var hour_start = parseInt(date_start.substring(11,13), 10);
615 var minute_start = parseInt(date_start.substring(14,16), 10);
616 var has_meridiem = /am|pm/i.test(date_start);
618 var meridiem = trim(date_start.substring(16));
622 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start + meridiem;
624 GLOBAL_REGISTRY.focus.fields.time_start = hour_start+time_separator+minute_start;
625 //GLOBAL_REGISTRY.focus.fields.time_start = document.forms[form_name].time_hour_start.value+time_separator+minute_start;
628 GLOBAL_REGISTRY.focus.fields.date_start = document.forms[form_name].date_start.value;
629 GLOBAL_REGISTRY.focus.fields.duration_hours = document.forms[form_name].duration_hours.value;
630 GLOBAL_REGISTRY.focus.fields.duration_minutes = document.forms[form_name].duration_minutes.value;
631 GLOBAL_REGISTRY.focus.fields.datetime_start = SugarDateTime.mysql2jsDateTime(GLOBAL_REGISTRY.focus.fields.date_start,GLOBAL_REGISTRY.focus.fields.time_start);
633 this.timeslots = new Array();
636 this.start_hours_before = 4;
638 var minute_interval = 15;
639 var dtstart = GLOBAL_REGISTRY.focus.fields.datetime_start;
641 // initialize first date in timeslots
642 var curdate = new Date(dtstart.getFullYear(),dtstart.getMonth(),dtstart.getDate(),dtstart.getHours()-this.start_hours_before,0);
644 if(typeof(GLOBAL_REGISTRY.focus.fields.duration_minutes) == 'undefined') {
645 GLOBAL_REGISTRY.focus.fields.duration_minutes = 0;
647 GLOBAL_REGISTRY.focus.fields.datetime_end = new Date(dtstart.getFullYear(),dtstart.getMonth(),dtstart.getDate(),dtstart.getHours()+parseInt(GLOBAL_REGISTRY.focus.fields.duration_hours),dtstart.getMinutes()+parseInt(GLOBAL_REGISTRY.focus.fields.duration_minutes),0);
649 var has_start = false;
652 for(i=0;i < this.hours*this.segments; i++) {
653 var hash = SugarDateTime.getUTCHash(curdate);
654 var obj = {"hash":hash,"date_obj":curdate};
655 if(has_start == false && GLOBAL_REGISTRY.focus.fields.datetime_start.getTime() <= curdate.getTime()) {
659 if(has_end == false && GLOBAL_REGISTRY.focus.fields.datetime_end.getTime() <= curdate.getTime()) {
663 this.timeslots.push(obj);
665 curdate = new Date(curdate.getFullYear(),curdate.getMonth(),curdate.getDate(),curdate.getHours(),curdate.getMinutes()+minute_interval);
667 //Bug#51357: Reset the search input fields after attandee popup is initiated.
668 SugarWidgetSchedulerSearch.resetSearchForm();
671 SugarWidgetSchedulerAttendees.prototype.load = function (parentNode) {
672 this.parentNode = parentNode;
676 SugarWidgetSchedulerAttendees.prototype.display = function() {
679 if(typeof document.EditView != 'undefined')
680 form_name = "EditView";
681 else if(typeof document.CalendarEditView != 'undefined')
682 form_name = "CalendarEditView";
686 var dtstart = GLOBAL_REGISTRY.focus.fields.datetime_start;
687 var top_date = SugarDateTime.getFormattedDate(dtstart);
688 var html = '<h3>'+GLOBAL_REGISTRY['meeting_strings']['LBL_SCHEDULING_FORM_TITLE']+'</h3><table id ="schedulerTable">';
689 html += '<tr class="schedulerTopRow">';
690 html += '<th colspan="'+((this.hours*this.segments)+2)+'"><h4>'+ top_date +'</h4></th>';
692 html += '<tr class="schedulerTimeRow">';
693 html += '<td> </td>';
695 for(var i=0;i < (this.timeslots.length/this.segments); i++) {
696 var hours = this.timeslots[i*this.segments].date_obj.getHours();
699 if(time_reg_format.indexOf('A') >= 0 || time_reg_format.indexOf('a') >= 0) {
713 if(time_reg_format.indexOf('a') >= 0) {
714 am_pm = am_pm.toLowerCase();
716 if(hours != 0 && hours != 12 && i != 0) {
722 var form_hours = hours+time_separator+"00";
723 html += '<th scope="col" colspan="'+this.segments+'">'+form_hours+am_pm+'</th>';
726 html += '<td> </td>';
729 if ( this.parentNode.childNodes.length < 1 )
730 this.parentNode.innerHTML += '<div class="schedulerDiv">' + html + '</div>';
732 this.parentNode.childNodes[0].innerHTML = html;
734 var thetable = "schedulerTable";
736 if(typeof (GLOBAL_REGISTRY) == 'undefined') {
740 //set the current user (as event-coordinator) so that they can be added to invitee list
741 //only IF the first removed flag has not been set AND this is a new record
742 if((typeof (GLOBAL_REGISTRY.focus.users_arr) == 'undefined' || GLOBAL_REGISTRY.focus.users_arr.length == 0)
743 && document.forms[form_name].record.value =='' && typeof(GLOBAL_REGISTRY.FIRST_REMOVE)=='undefined') {
744 GLOBAL_REGISTRY.focus.users_arr = [ GLOBAL_REGISTRY.current_user ];
747 if(typeof GLOBAL_REGISTRY.focus.users_arr_hash == 'undefined') {
748 GLOBAL_REGISTRY.focus.users_arr_hash = new Object();
751 // append attendee rows
752 for(var i=0;i < GLOBAL_REGISTRY.focus.users_arr.length;i++) {
753 var row = new SugarWidgetScheduleRow(this.timeslots);
754 row.focus_bean = GLOBAL_REGISTRY.focus.users_arr[i];
755 GLOBAL_REGISTRY.focus.users_arr_hash[ GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']] = GLOBAL_REGISTRY.focus.users_arr[i];
760 SugarWidgetSchedulerAttendees.form_add_attendee = function (list_row) {
761 if(typeof (GLOBAL_REGISTRY.result_list[list_row]) != 'undefined' && typeof(GLOBAL_REGISTRY.focus.users_arr_hash[ GLOBAL_REGISTRY.result_list[list_row].fields.id]) == 'undefined') {
762 GLOBAL_REGISTRY.focus.users_arr[ GLOBAL_REGISTRY.focus.users_arr.length ] = GLOBAL_REGISTRY.result_list[list_row];
764 GLOBAL_REGISTRY.scheduler_attendees_obj.display();
768 //////////////////////////////////////////////////
769 // class: SugarWidgetScheduleRow
770 // widget to display each row in the scheduler
772 //////////////////////////////////////////////////
773 SugarClass.inherit("SugarWidgetScheduleRow","SugarClass");
775 function SugarWidgetScheduleRow(timeslots) {
776 this.init(timeslots);
779 SugarWidgetScheduleRow.prototype.init = function(timeslots) {
780 this.timeslots = timeslots;
783 SugarWidgetScheduleRow.prototype.load = function (thetableid) {
784 this.thetableid = thetableid;
787 vcalClient = new SugarVCalClient();
788 if(typeof (GLOBAL_REGISTRY['freebusy_adjusted']) == 'undefined' || typeof (GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id]) == 'undefined') {
789 global_request_registry[req_count] = [this,'display'];
790 vcalClient.load(this.focus_bean.fields.id,req_count);
797 SugarWidgetScheduleRow.prototype.display = function() {
798 SUGAR.util.doWhen("document.getElementById('" + this.thetableid + "') != null", function(){
800 this.thetable = document.getElementById(this.thetableid);
802 if(typeof (this.element) != 'undefined') {
803 if (this.element.parentNode != null)
804 this.thetable.deleteRow(this.element.rowIndex);
806 tr = document.createElement('tr');
807 this.thetable.appendChild(tr);
809 tr = this.thetable.insertRow(this.thetable.rows.length);
811 tr.className = "schedulerAttendeeRow";
813 td = document.createElement('td');
815 //insertCell(tr.cells.length);
819 var img = '<img align="absmiddle" src="index.php?entryPoint=getImage&themeName='
820 + SUGAR.themes.theme_name+'&imageName='+this.focus_bean.module+'s.gif"/> ';
823 td.innerHTML = td.innerHTML;
825 if (this.focus_bean.fields.full_name)
826 td.innerHTML += ' ' + this.focus_bean.fields.full_name;
828 td.innerHTML += ' ' + this.focus_bean.fields.name;
830 // add freebusy tds here:
831 this.add_freebusy_nodes(tr);
834 var td = document.createElement('td');
836 //var td = tr.insertCell(tr.cells.length);
837 td.className = 'schedulerAttendeeDeleteCell';
839 //CCL - Remove check to disallow removal of assigned user or current user
840 //if ( GLOBAL_REGISTRY.focus.fields.assigned_user_id != this.focus_bean.fields.id && GLOBAL_REGISTRY.current_user.fields.id != this.focus_bean.fields.id) {
841 td.innerHTML = '<a title="'+ GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE']
842 + '" class="listViewTdToolsS1" style="text-decoration:none;" '
843 + 'href="javascript:SugarWidgetScheduleRow.deleteRow(\''+this.focus_bean.fields.id+'\');"> '
844 + '<img src="index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=delete_inline.gif" '
845 + 'align="absmiddle" alt="'+ GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE'] +'" border="0"> '
846 + GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE'] +'</a>';
849 this.element_index = this.thetable.rows.length - 1;
853 SugarWidgetScheduleRow.deleteRow = function(bean_id) {
854 // can't delete organizer
856 if(GLOBAL_REGISTRY.focus.users_arr.length == 1 || GLOBAL_REGISTRY.focus.fields.assigned_user_id == bean_id) {
860 for(var i=0;i<GLOBAL_REGISTRY.focus.users_arr.length;i++) {
861 if(GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']==bean_id) {
862 delete GLOBAL_REGISTRY.focus.users_arr_hash[GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']];
863 GLOBAL_REGISTRY.focus.users_arr.splice(i,1);
864 //set first remove flag to true for processing in display() function
865 GLOBAL_REGISTRY.FIRST_REMOVE = true;
866 GLOBAL_REGISTRY.container.root_widget.display();
872 function DL_GetElementLeft(eElement) {
874 * ifargument is invalid
875 * (not specified, is null or is 0)
876 * and function is a method
877 * identify the element as the method owner
879 if(!eElement && this) {
884 * initialize var to store calculations
885 * identify first offset parent element
886 * move up through element hierarchy
887 * appending left offset of each parent
888 * until no more offset parents exist
890 var nLeftPos = eElement.offsetLeft;
891 var eParElement = eElement.offsetParent;
892 while (eParElement != null) {
893 nLeftPos += eParElement.offsetLeft;
894 eParElement = eParElement.offsetParent;
896 return nLeftPos; // return the number calculated
900 function DL_GetElementTop(eElement) {
901 if(!eElement && this) {
905 var nTopPos = eElement.offsetTop;
906 var eParElement = eElement.offsetParent;
907 while (eParElement != null) {
908 nTopPos += eParElement.offsetTop;
909 eParElement = eParElement.offsetParent;
915 //////////////////////////////////////////
916 // adds the <td>s for freebusy display within a row
917 SugarWidgetScheduleRow.prototype.add_freebusy_nodes = function(tr,attendee) {
921 var is_loaded = false;
923 if(typeof GLOBAL_REGISTRY['freebusy_adjusted'] != 'undefined' && typeof GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id] != 'undefined') {
927 for(var i=0;i < this.timeslots.length; i++) {
928 var td = document.createElement('td');
930 //var td = tr.insertCell(tr.cells.length);
931 td.innerHTML = ' ';
932 if(typeof(this.timeslots[i]['is_start']) != 'undefined') {
933 td.className = 'schedulerSlotCellStartTime';
935 if(typeof(this.timeslots[i]['is_end']) != 'undefined') {
936 td.className = 'schedulerSlotCellEndTime';
940 // iftheres a freebusy stack in this slice
941 if( typeof(GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id][this.timeslots[i].hash]) != 'undefined') {
942 td.style.backgroundColor="#4D5EAA";
944 if( GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id][this.timeslots[i].hash] > 1) {
945 td.style.backgroundColor="#AA4D4D";