]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/modules/Meetings/jsclass_scheduler.js
Release 6.4.0
[Github/sugarcrm.git] / jssource / src_files / modules / Meetings / jsclass_scheduler.js
1 /*********************************************************************************
2  * SugarCRM Community Edition is a customer relationship management program developed by
3  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
4  * 
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.
11  * 
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
15  * details.
16  * 
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
20  * 02110-1301 USA.
21  * 
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.
24  * 
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.
28  * 
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  ********************************************************************************/
35
36
37
38 //////////////////////////////////////////////////
39 // class: SugarWidgetListView
40 // widget to display a list view
41 //
42 //////////////////////////////////////////////////
43
44 SugarClass.inherit("SugarWidgetListView","SugarClass");
45
46 function SugarWidgetListView() {
47         this.init();
48 }
49
50 SugarWidgetListView.prototype.init = function() {
51
52 }
53
54 SugarWidgetListView.prototype.load = function(parentNode) {
55         this.parentNode = parentNode;
56         this.display();
57 }
58
59 SugarWidgetListView.prototype.display = function() {
60         if(typeof GLOBAL_REGISTRY['result_list'] == 'undefined') {
61                 this.display_loading();
62                 return;
63         }
64
65         var div = document.getElementById('list_div_win');
66         div.style.display = 'block';
67         //div.style.height='125px';
68         var html = '<table width="100%" cellpadding="0" cellspacing="0" border="0" class="list view">';
69         html += '<tr>';
70         html += '<th width="2%" nowrap="nowrap">&nbsp;</th>';
71         html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_NAME']+'</th>';
72         html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_EMAIL']+'</th>';
73         html += '<th width="20%" nowrap="nowrap">'+GLOBAL_REGISTRY['meeting_strings']['LBL_PHONE']+'</th>';
74         html += '<th width="18%" nowrap="nowrap">&nbsp;</th>';
75         html += '</tr>';
76         //var html = '<table width="100%" cellpadding="0" cellspacing="0">';
77         for(var i=0;i<GLOBAL_REGISTRY['result_list'].length;i++) {
78                 var bean = GLOBAL_REGISTRY['result_list'][i];
79                 var disabled = false;
80                 var className='evenListRowS1';
81
82                 if(typeof(GLOBAL_REGISTRY.focus.users_arr_hash[ bean.fields.id]) != 'undefined') {
83                         disabled = true;
84                 }
85                 if((i%2) == 0) {
86                         className='oddListRowS1';
87                 } else {
88                         className='evenListRowS1';
89                 }
90                 if(typeof (bean.fields.first_name) == 'undefined') {
91                         bean.fields.first_name = '';
92                 }
93                 if(typeof (bean.fields.email1) == 'undefined' || bean.fields.email1 == "") {
94                         bean.fields.email1 = '&nbsp;';
95                 }
96                 if(typeof (bean.fields.phone_work) == 'undefined' || bean.fields.phone_work == "") {
97                         bean.fields.phone_work = '&nbsp;';
98                 }
99
100                 html += '<tr class="'+className+'">';
101                 html += '<td><img src="'+GLOBAL_REGISTRY.config['site_url']+'/index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName='+bean.module+'s.gif"/></td>';
102                 html += '<td>'+bean.fields.full_name+'</td>';
103                 html += '<td>'+bean.fields.email1+'</td>';
104                 html += '<td>'+bean.fields.phone_work+'</td>';
105                 html += '<td align="right">';
106                 //      hidden = 'hidden';
107                 hidden = 'visible';
108                 if(!disabled) {
109                         //      hidden = 'visible';
110                 }
111                 html += '<input type="button" class="button" onclick="this.disabled=true;SugarWidgetSchedulerAttendees.form_add_attendee('+i+');" value="'+GLOBAL_REGISTRY['meeting_strings']['LBL_ADD_BUTTON']+'"/ style="visibility: '+hidden+'"/>';
112                 html += '</td>';
113
114                 html += '</tr>';
115         }
116         html += '</table>';
117         this.parentNode.innerHTML = html;
118 }
119
120 SugarWidgetListView.prototype.display_loading = function() {
121
122 }
123
124 //////////////////////////////////////////////////
125 // class: SugarWidgetSchedulerSearch
126 // widget to display the meeting scheduler search box
127 //
128 //////////////////////////////////////////////////
129
130 SugarClass.inherit("SugarWidgetSchedulerSearch","SugarClass");
131
132 function SugarWidgetSchedulerSearch() {
133         this.init();
134 }
135
136 SugarWidgetSchedulerSearch.prototype.init = function() {
137         this.form_id = 'scheduler_search';
138         GLOBAL_REGISTRY['widget_element_map'] = new Object();
139         GLOBAL_REGISTRY['widget_element_map'][this.form_id] = this;
140 }
141
142 SugarWidgetSchedulerSearch.prototype.load = function(parentNode) {
143         this.parentNode = parentNode;
144         this.display();
145 }
146
147 SugarWidgetSchedulerSearch.submit = function(form) {
148         //construct query obj:
149         var conditions  = new Array();
150
151         if(form.search_first_name.value != '') {
152                 conditions[conditions.length] = {"name":"first_name","op":"starts_with","value":form.search_first_name.value}
153         }
154         if(form.search_last_name.value != '') {
155                 conditions[conditions.length] = {"name":"last_name","op":"starts_with","value":form.search_last_name.value}
156         }
157         if(form.search_email.value != '') {
158                 conditions[conditions.length] = {"name":"email1","op":"starts_with","value":form.search_email.value}
159         }
160
161         var query = {"modules":["Users","Contacts"
162         ,"Leads"
163         ],"group":"and","field_list":['id','full_name','email1','phone_work'],"conditions":conditions};
164         global_request_registry[req_count] = [this,'display'];
165         req_id = global_rpcClient.call_method('query',query);
166         global_request_registry[req_id] = [ GLOBAL_REGISTRY['widget_element_map'][form.id],'refresh_list'];
167 }
168
169 SugarWidgetSchedulerSearch.prototype.refresh_list = function(rslt) {
170         GLOBAL_REGISTRY['result_list'] = rslt['list'];
171         this.list_view.display();
172 }
173
174 SugarWidgetSchedulerSearch.prototype.display = function() {
175         var html ='<div class="schedulerInvitees"><h3>'+GLOBAL_REGISTRY['meeting_strings']['LBL_ADD_INVITEE']+'</h5><table border="0" cellpadding="0" cellspacing="0" width="100%" class="edit view">';
176         html +='<tr><td>';                  
177         html += '<form name="schedulerwidget" id="'+this.form_id+'" onsubmit="SugarWidgetSchedulerSearch.submit(this);return false;">';
178
179         html += '<table width="100%" cellpadding="0" cellspacing="0" width="100%" >'
180         html += '<tr>';
181         //html += '<form id="'+this.form_id+'"><table width="100%"><tbody><tr>';
182         html += '<td scope="col" nowrap><label for="search_first_name">'+GLOBAL_REGISTRY['meeting_strings']['LBL_FIRST_NAME']+':</label>&nbsp;&nbsp;<input  name="search_first_name" id="search_first_name" value="" type="text" size="10"></td>';
183         html += '<td scope="col" nowrap><label for="search_last_name">'+GLOBAL_REGISTRY['meeting_strings']['LBL_LAST_NAME']+':</label>&nbsp;&nbsp;<input  name="search_last_name" id="search_last_name" value="" type="text" size="10"></td>';
184         html += '<td scope="col" nowrap><label for="search_email">'+GLOBAL_REGISTRY['meeting_strings']['LBL_EMAIL']+':</label>&nbsp;&nbsp;<input  name="search_email" id="search_email" type="text" value="" size="15"></td>';
185         //html += '<td valign="center"><input type="submit" onclick="SugarWidgetSchedulerSearch.submit(this.form);" value="Search" ></td></tr></tbody></table></form>';
186         html += '<td valign="center"><input type="submit" class="button" value="'+GLOBAL_REGISTRY['meeting_strings']['LBL_SEARCH_BUTTON']+'" ></td></tr>';
187         html += '</table>';
188         html += '</form>';
189         html += '</td></tr></table></div>';
190
191         // append the list_view as the third row of the outside table
192         this.parentNode.innerHTML += html;
193
194         var div = document.createElement('div');
195         div.setAttribute('id','list_div_win');
196         div.style.overflow = 'auto';
197         div.style.width = '100%';
198         div.style.height= '100%';
199         div.style.display = 'none';
200     this.parentNode.appendChild(div);
201         
202     this.list_view = new SugarWidgetListView();
203         this.list_view.load(div);
204 }
205
206 //////////////////////////////////////////////////
207 // class: SugarWidgetScheduler
208 // widget to display the meeting scheduler
209 //
210 //////////////////////////////////////////////////
211
212 SugarClass.inherit("SugarWidgetScheduler","SugarClass");
213
214 function SugarWidgetScheduler() {
215         this.init();
216 }
217
218 SugarWidgetScheduler.prototype.init = function() {
219         //var row = new SugarWidgetScheduleAttendees();
220         //row.load(this);
221 }
222
223 SugarWidgetScheduler.prototype.load = function(parentNode) {
224         this.parentNode = parentNode;
225         this.display();
226 }
227
228 SugarWidgetScheduler.fill_invitees = function(form) {
229         for(var i=0;i<GLOBAL_REGISTRY.focus.users_arr.length;i++) {
230                 if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'User') {
231                         form.user_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
232                 } else if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'Contact') {
233                         form.contact_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
234                 } else if(GLOBAL_REGISTRY.focus.users_arr[i].module == 'Lead') {
235                         form.lead_invitees.value += GLOBAL_REGISTRY.focus.users_arr[i].fields.id + ",";
236                 }
237         }
238 }
239
240 SugarWidgetScheduler.update_time = function() {
241
242         var form_name;
243         if(typeof document.EditView != 'undefined')
244                 form_name = "EditView";
245         else if(typeof document.CalendarEditView != 'undefined')
246                 form_name = "CalendarEditView";
247         else
248                 return;
249     
250    //check for field value, we can't do anything if it doesnt exist.
251     if(typeof document.forms[form_name].date_start == 'undefined')
252                 return;
253
254         var date_start = document.forms[form_name].date_start.value;
255         if(date_start.length < 16) {
256                 return;
257         }
258         var hour_start = parseInt(date_start.substring(11,13), 10);
259         var minute_start = parseInt(date_start.substring(14,16), 10);
260         var has_meridiem = /am|pm/i.test(date_start);
261         if(has_meridiem) {
262         var meridiem = trim(date_start.substring(16));
263         }
264
265         GLOBAL_REGISTRY.focus.fields.date_start = date_start;
266
267         if(has_meridiem) {
268                 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start + meridiem;
269         } else {
270                 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start;
271         }
272
273         GLOBAL_REGISTRY.focus.fields.duration_hours = document.forms[form_name].duration_hours.value;
274         GLOBAL_REGISTRY.focus.fields.duration_minutes = document.forms[form_name].duration_minutes.value;
275         GLOBAL_REGISTRY.focus.fields.datetime_start = SugarDateTime.mysql2jsDateTime(GLOBAL_REGISTRY.focus.fields.date_start,GLOBAL_REGISTRY.focus.fields.time_start);
276
277         GLOBAL_REGISTRY.scheduler_attendees_obj.init();
278         GLOBAL_REGISTRY.scheduler_attendees_obj.display();
279 }
280
281 SugarWidgetScheduler.prototype.display = function() {
282     this.parentNode.innerHTML = '';
283
284         var attendees = new SugarWidgetSchedulerAttendees();
285         attendees.load(this.parentNode);
286
287         var search = new SugarWidgetSchedulerSearch();
288         search.load(this.parentNode);
289 }
290
291
292 //////////////////////////////////////////////////
293 // class: SugarWidgetSchedulerAttendees
294 // widget to display the meeting attendees and availability
295 //
296 //////////////////////////////////////////////////
297
298 SugarClass.inherit("SugarWidgetSchedulerAttendees","SugarClass");
299
300 function SugarWidgetSchedulerAttendees() {
301         this.init();
302 }
303
304 SugarWidgetSchedulerAttendees.prototype.init = function() {
305
306         var form_name;
307         if(typeof document.EditView != 'undefined')
308                 form_name = "EditView";
309         else if(typeof document.CalendarEditView != 'undefined')
310                 form_name = "CalendarEditView";
311         else
312                 return;
313
314         // this.datetime = new SugarDateTime();
315         GLOBAL_REGISTRY.scheduler_attendees_obj = this;
316         var date_start = document.forms[form_name].date_start.value;
317         var hour_start = parseInt(date_start.substring(11,13), 10);
318         var minute_start = parseInt(date_start.substring(14,16), 10);
319         var has_meridiem = /am|pm/i.test(date_start);
320         if(has_meridiem) {
321         var meridiem = trim(date_start.substring(16));
322         }
323
324         if(has_meridiem) {
325                 GLOBAL_REGISTRY.focus.fields.time_start = hour_start + time_separator + minute_start + meridiem;
326         } else {
327                 GLOBAL_REGISTRY.focus.fields.time_start = hour_start+time_separator+minute_start;
328                 //GLOBAL_REGISTRY.focus.fields.time_start = document.forms[form_name].time_hour_start.value+time_separator+minute_start;
329         }
330
331         GLOBAL_REGISTRY.focus.fields.date_start = document.forms[form_name].date_start.value;
332         GLOBAL_REGISTRY.focus.fields.duration_hours = document.forms[form_name].duration_hours.value;
333         GLOBAL_REGISTRY.focus.fields.duration_minutes = document.forms[form_name].duration_minutes.value;
334         GLOBAL_REGISTRY.focus.fields.datetime_start = SugarDateTime.mysql2jsDateTime(GLOBAL_REGISTRY.focus.fields.date_start,GLOBAL_REGISTRY.focus.fields.time_start);
335
336         this.timeslots = new Array();
337         this.hours = 9;
338         this.segments = 4;
339         this.start_hours_before = 4;
340
341         var minute_interval = 15;
342         var dtstart = GLOBAL_REGISTRY.focus.fields.datetime_start;
343
344         // initialize first date in timeslots
345         var curdate = new Date(dtstart.getFullYear(),dtstart.getMonth(),dtstart.getDate(),dtstart.getHours()-this.start_hours_before,0);
346
347         if(typeof(GLOBAL_REGISTRY.focus.fields.duration_minutes) == 'undefined') {
348                 GLOBAL_REGISTRY.focus.fields.duration_minutes = 0;
349         }
350         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);
351
352         var has_start = false;
353         var has_end = false;
354
355         for(i=0;i < this.hours*this.segments; i++) {
356                 var hash = SugarDateTime.getUTCHash(curdate);
357                 var obj = {"hash":hash,"date_obj":curdate};
358                 if(has_start == false && GLOBAL_REGISTRY.focus.fields.datetime_start.getTime() <= curdate.getTime()) {
359                         obj.is_start = true;
360                         has_start = true;
361                 }
362                 if(has_end == false && GLOBAL_REGISTRY.focus.fields.datetime_end.getTime() <= curdate.getTime()) {
363                         obj.is_end = true;
364                         has_end = true;
365                 }
366                 this.timeslots.push(obj);
367
368                 curdate = new Date(curdate.getFullYear(),curdate.getMonth(),curdate.getDate(),curdate.getHours(),curdate.getMinutes()+minute_interval);
369         }
370 }
371
372 SugarWidgetSchedulerAttendees.prototype.load = function (parentNode) {
373         this.parentNode = parentNode;
374         this.display();
375 }
376
377 SugarWidgetSchedulerAttendees.prototype.display = function() {
378
379         var form_name;
380         if(typeof document.EditView != 'undefined')
381                 form_name = "EditView";
382         else if(typeof document.CalendarEditView != 'undefined')
383                 form_name = "CalendarEditView";
384         else
385                 return;
386
387         var dtstart = GLOBAL_REGISTRY.focus.fields.datetime_start;
388         var top_date = SugarDateTime.getFormattedDate(dtstart);
389         var html = '<h3>'+GLOBAL_REGISTRY['meeting_strings']['LBL_SCHEDULING_FORM_TITLE']+'</h3><table id ="schedulerTable">';
390         html += '<tr class="schedulerTopRow">';
391         html += '<th colspan="'+((this.hours*this.segments)+2)+'"><h4>'+ top_date +'</h4></th>';
392         html += '</tr>';
393         html += '<tr class="schedulerTimeRow">';
394         html += '<td>&nbsp;</td>';
395
396         for(var i=0;i < (this.timeslots.length/this.segments); i++) {
397                 var hours = this.timeslots[i*this.segments].date_obj.getHours();
398                 var am_pm = '';
399
400                 if(time_reg_format.indexOf('A') >= 0 || time_reg_format.indexOf('a') >= 0) {
401                         am_pm = "AM";
402
403                         if(hours > 12) {
404                                 am_pm = "PM";
405                                 hours -= 12;
406                         }
407                         if(hours == 12) {
408                                 am_pm = "PM";
409                         }
410                         if(hours == 0) {
411                                 hours = 12;
412                                 am_pm = "AM";
413                         }
414                         if(time_reg_format.indexOf('a') >= 0) {
415                                 am_pm = am_pm.toLowerCase();
416                         }
417                         if(hours != 0 && hours != 12 && i != 0) {
418                                 am_pm = "";
419                         }
420
421                 }
422
423                 var form_hours = hours+time_separator+"00";
424                 html += '<th scope="col" colspan="'+this.segments+'">'+form_hours+am_pm+'</th>';
425         }
426
427         html += '<td>&nbsp;</td>';
428         html += '</tr>';
429         html += '</table>';
430     if ( this.parentNode.childNodes.length < 1 )
431         this.parentNode.innerHTML += '<div class="schedulerDiv">' + html + '</div>';
432     else
433         this.parentNode.childNodes[0].innerHTML = html;
434
435         var thetable = "schedulerTable";
436
437         if(typeof (GLOBAL_REGISTRY) == 'undefined') {
438                 return;
439         }
440
441         //set the current user (as event-coordinator) so that they can be added to invitee list
442         //only IF the first removed flag has not been set AND this is a new record
443         if((typeof (GLOBAL_REGISTRY.focus.users_arr) == 'undefined' || GLOBAL_REGISTRY.focus.users_arr.length == 0)
444       && document.forms[form_name].record.value =='' && typeof(GLOBAL_REGISTRY.FIRST_REMOVE)=='undefined') {
445                 GLOBAL_REGISTRY.focus.users_arr = [ GLOBAL_REGISTRY.current_user ];
446         }
447         
448         if(typeof GLOBAL_REGISTRY.focus.users_arr_hash == 'undefined') {
449                 GLOBAL_REGISTRY.focus.users_arr_hash = new Object();
450         }
451
452         // append attendee rows
453         for(var i=0;i < GLOBAL_REGISTRY.focus.users_arr.length;i++) {
454                 var row = new SugarWidgetScheduleRow(this.timeslots);
455                 row.focus_bean = GLOBAL_REGISTRY.focus.users_arr[i];
456                 GLOBAL_REGISTRY.focus.users_arr_hash[ GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']] =     GLOBAL_REGISTRY.focus.users_arr[i];
457                 row.load(thetable);
458         }
459 }
460
461 SugarWidgetSchedulerAttendees.form_add_attendee = function (list_row) {
462         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') {
463                 GLOBAL_REGISTRY.focus.users_arr[ GLOBAL_REGISTRY.focus.users_arr.length ] = GLOBAL_REGISTRY.result_list[list_row];
464         }
465         GLOBAL_REGISTRY.scheduler_attendees_obj.display();
466 }
467
468
469 //////////////////////////////////////////////////
470 // class: SugarWidgetScheduleRow
471 // widget to display each row in the scheduler
472 //
473 //////////////////////////////////////////////////
474 SugarClass.inherit("SugarWidgetScheduleRow","SugarClass");
475
476 function SugarWidgetScheduleRow(timeslots) {
477         this.init(timeslots);
478 }
479
480 SugarWidgetScheduleRow.prototype.init = function(timeslots) {
481         this.timeslots = timeslots;
482 }
483
484 SugarWidgetScheduleRow.prototype.load = function (thetableid) {
485         this.thetableid = thetableid;
486         var self = this;
487
488         vcalClient = new SugarVCalClient();
489         if(typeof (GLOBAL_REGISTRY['freebusy_adjusted']) == 'undefined' ||      typeof (GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id]) == 'undefined') {
490                 global_request_registry[req_count] = [this,'display'];
491                 vcalClient.load(this.focus_bean.fields.id,req_count);
492                 req_count++;
493         } else {
494                 this.display();
495         }
496 }
497
498 SugarWidgetScheduleRow.prototype.display = function() {
499         SUGAR.util.doWhen("document.getElementById('" + this.thetableid + "') != null", function(){
500         var tr;
501         this.thetable = document.getElementById(this.thetableid);
502
503         if(typeof (this.element) != 'undefined') {
504             if (this.element.parentNode != null)
505                 this.thetable.deleteRow(this.element.rowIndex);
506
507             tr = document.createElement('tr');
508             this.thetable.appendChild(tr);
509         } else {
510             tr = this.thetable.insertRow(this.thetable.rows.length);
511         }
512         tr.className = "schedulerAttendeeRow";
513
514         td = document.createElement('td');
515         tr.appendChild(td);
516         //insertCell(tr.cells.length);
517
518         // icon + full name
519         td.scope = 'row';
520         var img = '<img align="absmiddle" src="index.php?entryPoint=getImage&themeName='
521                 + SUGAR.themes.theme_name+'&imageName='+this.focus_bean.module+'s.gif"/>&nbsp;';
522         td.innerHTML = img;
523
524         td.innerHTML = td.innerHTML;
525
526         if (this.focus_bean.fields.full_name)
527             td.innerHTML += ' ' + this.focus_bean.fields.full_name;
528         else
529             td.innerHTML += ' ' + this.focus_bean.fields.name;
530
531         // add freebusy tds here:
532         this.add_freebusy_nodes(tr);
533
534         // delete button
535         var td = document.createElement('td');
536         tr.appendChild(td);
537         //var td = tr.insertCell(tr.cells.length);
538         td.className = 'schedulerAttendeeDeleteCell';
539         td.noWrap = true;
540         //CCL - Remove check to disallow removal of assigned user or current user
541         //if ( GLOBAL_REGISTRY.focus.fields.assigned_user_id != this.focus_bean.fields.id && GLOBAL_REGISTRY.current_user.fields.id != this.focus_bean.fields.id) {
542        td.innerHTML = '<a title="'+ GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE']
543                     + '" class="listViewTdToolsS1" style="text-decoration:none;" '
544                     + 'href="javascript:SugarWidgetScheduleRow.deleteRow(\''+this.focus_bean.fields.id+'\');">&nbsp;'
545                     + '<img src="index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=delete_inline.gif" '
546                     + 'align="absmiddle" alt="'+ GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE'] +'" border="0"> '
547                     + GLOBAL_REGISTRY['meeting_strings']['LBL_REMOVE'] +'</a>';
548         //}
549         this.element = tr;
550         this.element_index = this.thetable.rows.length - 1;
551     }, null, this);
552 }
553
554 SugarWidgetScheduleRow.deleteRow = function(bean_id) {
555         // can't delete organizer
556         /*
557         if(GLOBAL_REGISTRY.focus.users_arr.length == 1 || GLOBAL_REGISTRY.focus.fields.assigned_user_id == bean_id) {
558                 return;
559         }
560     */
561         for(var i=0;i<GLOBAL_REGISTRY.focus.users_arr.length;i++) {
562                 if(GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']==bean_id) {
563                         delete GLOBAL_REGISTRY.focus.users_arr_hash[GLOBAL_REGISTRY.focus.users_arr[i]['fields']['id']];
564                         GLOBAL_REGISTRY.focus.users_arr.splice(i,1);
565                 //set first remove flag to true for processing in display() function
566                         GLOBAL_REGISTRY.FIRST_REMOVE = true;
567                         GLOBAL_REGISTRY.container.root_widget.display();
568                 }
569         }
570 }
571
572
573 function DL_GetElementLeft(eElement) {
574         /*
575          * ifargument is invalid
576          * (not specified, is null or is 0)
577          * and function is a method
578          * identify the element as the method owner
579          */
580         if(!eElement && this) {
581                 eElement = this;
582         }
583
584         /*
585          * initialize var to store calculations
586          * identify first offset parent element
587          * move up through element hierarchy
588          * appending left offset of each parent
589          * until no more offset parents exist
590          */
591         var nLeftPos = eElement.offsetLeft;
592         var eParElement = eElement.offsetParent;
593         while (eParElement != null) {
594                 nLeftPos += eParElement.offsetLeft;
595                 eParElement = eParElement.offsetParent;
596         }
597         return nLeftPos; // return the number calculated
598 }
599
600
601 function DL_GetElementTop(eElement) {
602         if(!eElement && this) {
603                 eElement = this;
604         }
605
606         var nTopPos = eElement.offsetTop;
607         var eParElement = eElement.offsetParent;
608         while (eParElement != null) {
609                 nTopPos += eParElement.offsetTop;
610                 eParElement = eParElement.offsetParent;
611         }
612         return nTopPos;
613 }
614
615
616 //////////////////////////////////////////
617 // adds the <td>s for freebusy display within a row
618 SugarWidgetScheduleRow.prototype.add_freebusy_nodes = function(tr,attendee) {
619         var hours = 9;
620         var segments = 4;
621         var html = '';
622         var is_loaded = false;
623
624         if(typeof GLOBAL_REGISTRY['freebusy_adjusted'] != 'undefined' && typeof GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id] != 'undefined') {
625                 is_loaded = true;
626         }
627
628         for(var i=0;i < this.timeslots.length; i++) {
629                 var td = document.createElement('td');
630                 tr.appendChild(td);
631                 //var td = tr.insertCell(tr.cells.length);
632         td.innerHTML = '&nbsp;';
633                 if(typeof(this.timeslots[i]['is_start']) != 'undefined') {
634                         td.className = 'schedulerSlotCellStartTime';
635                 }
636                 if(typeof(this.timeslots[i]['is_end']) != 'undefined') {
637                         td.className = 'schedulerSlotCellEndTime';
638                 }
639
640                 if(is_loaded) {
641                         // iftheres a freebusy stack in this slice
642                         if(     typeof(GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id][this.timeslots[i].hash]) != 'undefined') {
643                                 td.style.backgroundColor="#4D5EAA";
644
645                                 if(td.className == 'schedulerSlotCellStartTime') {
646                                         fb_limit = 1;
647                                         if(typeof(GLOBAL_REGISTRY.focus.orig_users_arr_hash) != 'undefined' && typeof(GLOBAL_REGISTRY.focus.orig_users_arr_hash[this.focus_bean.fields.id]) != 'undefined') {
648                                                 fb_limit = 2;
649                                         }
650
651                                         if(     GLOBAL_REGISTRY['freebusy_adjusted'][this.focus_bean.fields.id][this.timeslots[i].hash] >= fb_limit) {
652                                                 td.style.backgroundColor="#AA4D4D";
653                                         } else {
654                                                 td.style.backgroundColor="#4D5EAA";
655                                         }
656                                 }
657                         }
658                 }
659         }
660 }