1 /*********************************************************************************
2 * SugarCRM Community Edition is a customer relationship management program developed by
3 * SugarCRM, Inc. Copyright (C) 2004-2012 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 initMySugar = function(){
39 SUGAR.mySugar = function() {
40 var originalLayout = null;
41 var configureDashletId = null;
42 var currentDashlet = null;
43 var leftColumnInnerHTML = null;
44 var leftColObj = null;
48 var closeDashletsDialogTimer = null;
50 var activeTab = activePage;
51 var current_user = current_user_id;
53 var module = moduleName;
55 var charts = new Object();
57 if (module == 'Dashboard'){
58 cookiePageIndex = current_user + "_activeDashboardPage";
61 cookiePageIndex = current_user + "_activePage";
82 // get the current dashlet layout
83 getLayout: function(asString) {
84 columns = new Array();
85 for(je = 0; je < 3; je++) {
86 dashlets = document.getElementById('col_'+activeTab+'_'+ je);
88 if (dashlets != null){
89 dashletIds = new Array();
90 for(wp = 0; wp < dashlets.childNodes.length; wp++) {
91 if(typeof dashlets.childNodes[wp].id != 'undefined' && dashlets.childNodes[wp].id.match(/dashlet_[\w-]*/)) {
92 dashletIds.push(dashlets.childNodes[wp].id.replace(/dashlet_/,''));
96 columns[je] = dashletIds.join(',');
98 columns[je] = dashletIds;
102 if(asString) return columns.join('|');
106 // called when dashlet is picked up
107 onDrag: function(e, id) {
108 originalLayout = SUGAR.mySugar.getLayout(true);
111 // called when dashlet is dropped
112 onDrop: function(e, id) {
113 newLayout = SUGAR.mySugar.getLayout(true);
114 if(originalLayout != newLayout) { // only save if the layout has changed
115 SUGAR.mySugar.saveLayout(newLayout);
116 SUGAR.mySugar.sugarCharts.loadSugarCharts(); // called safely because there is a check to be sure the array exists
120 // save the layout of the dashlet
121 saveLayout: function(order) {
122 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVING_LAYOUT'));
123 var success = function(data) {
124 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVED_LAYOUT'));
125 window.setTimeout('ajaxStatus.hideStatus()', 2000);
128 url = 'index.php?to_pdf=1&module='+module+'&action=DynamicAction&DynamicAction=saveLayout&layout=' + order + '&selectedPage=' + activeTab;
129 var cObj = YAHOO.util.Connect.asyncRequest('GET', url, {success: success, failure: success});
133 uncoverPage: function(id) {
135 document.getElementById('dlg_c').style.display = 'none';
138 if ( document.getElementById('dashletType') == null ) {
141 dashletType = document.getElementById('dashletType').value;
143 SUGAR.mySugar.retrieveDashlet(SUGAR.mySugar.configureDashletId, dashletType);
146 // call to configure a Dashlet
147 configureDashlet: function(id) {
148 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_LOADING'));
149 configureDlg = new YAHOO.widget.SimpleDialog("dlg",
152 effect:[{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.5}],
158 fillInConfigureDiv = function(data){
159 ajaxStatus.hideStatus();
160 // uncomment the line below to debug w/ FireBug
161 // console.log(data.responseText);
163 eval(data.responseText);
166 result = new Array();
167 result['header'] = 'error';
168 result['body'] = 'There was an error handling this request.';
170 configureDlg.setHeader(result['header']);
171 configureDlg.setBody(result['body']);
172 var listeners = new YAHOO.util.KeyListener(document, { keys : 27 }, {fn: function() {this.hide();}, scope: configureDlg, correctScope:true} );
173 configureDlg.cfg.queueProperty("keylisteners", listeners);
175 configureDlg.render(document.body);
177 configureDlg.configFixedCenter(null, false) ;
178 SUGAR.util.evalScript(result['body']);
181 SUGAR.mySugar.configureDashletId = id; // save the id of the dashlet being configured
182 var cObj = YAHOO.util.Connect.asyncRequest('GET','index.php?to_pdf=1&module='+module+'&action=DynamicAction&DynamicAction=configureDashlet&id=' + id,
183 {success: fillInConfigureDiv, failure: fillInConfigureDiv}, null);
187 /** returns dashlets contents
188 * if url is defined, dashlet will be retrieve with it, otherwise use default url
190 * @param string id id of the dashlet to refresh
191 * @param string url url to be used
192 * @param function callback callback function after refresh
193 * @param bool dynamic does the script load dynamic javascript, set to true if you user needs to refresh the dashlet after load
195 retrieveDashlet: function(id, url, callback, dynamic) {
196 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_LOADING'));
199 url = 'index.php?action=DynamicAction&DynamicAction=displayDashlet&session_commit=1&module='+module+'&to_pdf=1&id=' + id;
200 is_chart_dashlet = false;
202 else if (url == 'predefined_chart'){
203 url = 'index.php?action=DynamicAction&DynamicAction=displayDashlet&session_commit=1&module='+module+'&to_pdf=1&id=' + id;
204 scriptUrl = 'index.php?action=DynamicAction&DynamicAction=getPredefinedChartScript&session_commit=1&module='+module+'&to_pdf=1&id=' + id;
205 is_chart_dashlet = true;
210 url += '&dynamic=true';
213 var fillInDashlet = function(data) {
215 ajaxStatus.hideStatus();
218 // before we refresh, lets make sure that the returned data is for the current dashlet in focus
219 // AND that it is not the initial 'please reload' verbage, start by grabbing the current dashlet id
220 current_dashlet_id = SUGAR.mySugar.currentDashlet.getAttribute('id');
222 //lets extract the guid portion of the id, to use as a reference
223 dashlet_guid = current_dashlet_id.substr('dashlet_entire'.length);
225 //now that we have the guid portion, let's search the returned text for it. There should be many references to it.
226 if(data.responseText.indexOf(dashlet_guid)<0 && data.responseText != SUGAR.language.get('app_strings', 'LBL_RELOAD_PAGE') ){
227 //guid id was not found in the returned html, that means we have stale dashlet info due to an auto refresh, do not update
230 SUGAR.mySugar.currentDashlet.innerHTML = data.responseText;
233 SUGAR.util.evalScript(data.responseText);
234 if(callback) callback();
236 var processChartScript = function(scriptData){
237 SUGAR.util.evalScript(scriptData.responseText);
239 SUGAR.mySugar.sugarCharts.loadSugarCharts(activePage);
242 if(typeof(is_chart_dashlet)=='undefined'){
243 is_chart_dashlet = false;
245 if (is_chart_dashlet){
246 var chartScriptObj = YAHOO.util.Connect.asyncRequest('GET', scriptUrl,
247 {success: processChartScript, failure: processChartScript}, null);
251 SUGAR.mySugar.currentDashlet = document.getElementById('dashlet_entire_' + id);
252 var cObj = YAHOO.util.Connect.asyncRequest('GET', url,
253 {success: fillInDashlet, failure: fillInDashlet}, null);
257 // for the display columns widget
258 setChooser: function() {
259 var displayColumnsDef = new Array();
260 var hideTabsDef = new Array();
262 var left_td = document.getElementById('display_tabs_td');
263 var right_td = document.getElementById('hide_tabs_td');
265 var displayTabs = left_td.getElementsByTagName('select')[0];
266 var hideTabs = right_td.getElementsByTagName('select')[0];
268 for(i = 0; i < displayTabs.options.length; i++) {
269 displayColumnsDef.push(displayTabs.options[i].value);
272 if(typeof hideTabs != 'undefined') {
273 for(i = 0; i < hideTabs.options.length; i++) {
274 hideTabsDef.push(hideTabs.options[i].value);
278 document.getElementById('displayColumnsDef').value = displayColumnsDef.join('|');
279 document.getElementById('hideTabsDef').value = hideTabsDef.join('|');
282 deleteDashlet: function(id) {
283 if(confirm(SUGAR.language.get('app_strings', 'LBL_REMOVE_DASHLET_CONFIRM'))) {
284 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_REMOVING_DASHLET'));
287 var success = function(data) {
288 dashlet = document.getElementById('dashlet_' + id);
289 dashlet.parentNode.removeChild(dashlet);
290 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_REMOVED_DASHLET'));
291 window.setTimeout('ajaxStatus.hideStatus()', 2000);
295 var cObj = YAHOO.util.Connect.asyncRequest('GET','index.php?to_pdf=1&module='+module+'&action=DynamicAction&DynamicAction=deleteDashlet&activePage=' + activeTab + '&id=' + id,
296 {success: success, failure: success}, null);
299 var anim = new YAHOO.util.Anim('dashlet_entire_' + id, { height: {to: 1} }, .5 );
300 anim.onComplete.subscribe(del);
301 document.getElementById('dashlet_entire_' + id).style.overflow = 'hidden';
310 addDashlet: function(id, type, type_module) {
311 ajaxStatus.hideStatus();
312 columns = SUGAR.mySugar.getLayout();
314 var num_dashlets = columns[0].length;
315 if (typeof columns[1] == undefined){
316 num_dashlets = num_dashlets + columns[1].length;
319 if((num_dashlets) >= SUGAR.mySugar.maxCount) {
320 alert(SUGAR.language.get('app_strings', 'LBL_MAX_DASHLETS_REACHED'));
323 /* if((columns[0].length + columns[1].length) >= SUGAR.mySugar.maxCount) {
324 alert(SUGAR.language.get('Home', 'LBL_MAX_DASHLETS_REACHED'));
327 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_ADDING_DASHLET'));
328 var success = function(data) {
330 colZero = document.getElementById('col_'+activeTab+'_0');
331 newDashlet = document.createElement('li'); // build the list item
332 newDashlet.id = 'dashlet_' + data.responseText;
333 newDashlet.className = 'noBullet active';
334 // hide it first, but append to getRegion
335 newDashlet.innerHTML = '<div style="position: absolute; top: -1000px; overflow: hidden;" id="dashlet_entire_' + data.responseText + '"></div>';
337 colZero.insertBefore(newDashlet, colZero.firstChild); // insert it into the first column
339 var finishRetrieve = function() {
340 dashletEntire = document.getElementById('dashlet_entire_' + data.responseText);
341 dd = new ygDDList('dashlet_' + data.responseText); // make it draggable
342 dd.setHandleElId('dashlet_header_' + data.responseText);
343 // Bug #47097 : Dashlets not displayed after moving them
344 // add new property to save real id of dashlet, it needs to have ability reload dashlet by id
345 dd.dashletID = data.responseText;
346 dd.onMouseDown = SUGAR.mySugar.onDrag;
347 dd.onDragDrop = SUGAR.mySugar.onDrop;
349 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_ADDED_DASHLET'));
350 dashletRegion = YAHOO.util.Dom.getRegion(dashletEntire);
351 dashletEntire.style.position = 'relative';
352 dashletEntire.style.height = '1px';
353 dashletEntire.style.top = '0px';
354 dashletEntire.className = 'dashletPanel';
357 var anim = new YAHOO.util.Anim('dashlet_entire_' + data.responseText, { height: {to: dashletRegion.bottom - dashletRegion.top} }, .5 );
358 anim.onComplete.subscribe(function() { document.getElementById('dashlet_entire_' + data.responseText).style.height = '100%'; });
361 newLayout = SUGAR.mySugar.getLayout(true);
362 SUGAR.mySugar.saveLayout(newLayout);
363 // window.setTimeout('ajaxStatus.hideStatus()', 2000);
366 if (type == 'module' || type == 'web'){
370 else if (type == 'predefined_chart'){
371 url = 'predefined_chart';
372 type = 'predefined_chart';
374 else if (type == 'chart'){
379 SUGAR.mySugar.retrieveDashlet(data.responseText, url, finishRetrieve, true); // retrieve it from the server
382 var cObj = YAHOO.util.Connect.asyncRequest('GET','index.php?to_pdf=1&module='+module+'&action=DynamicAction&DynamicAction=addDashlet&activeTab=' + activeTab + '&id=' + id+'&type=' + type + '&type_module=' + encodeURIComponent(type_module),
383 {success: success, failure: success}, null);
388 showDashletsDialog: function() {
389 columns = SUGAR.mySugar.getLayout();
391 if (this.closeDashletsDialogTimer != null) {
392 window.clearTimeout(this.closeDashletsDialogTimer);
395 var num_dashlets = 0;
397 for ( i = 0 ; i < 3; i++ ) {
398 if (typeof columns[i] != "undefined") {
399 num_dashlets = num_dashlets + columns[i].length;
403 if((num_dashlets) >= SUGAR.mySugar.maxCount) {
404 alert(SUGAR.language.get('app_strings', 'LBL_MAX_DASHLETS_REACHED'));
407 ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_LOADING'));
409 var success = function(data) {
410 eval(data.responseText);
411 dashletsListDiv = document.getElementById('dashletsList');
412 dashletsListDiv.innerHTML = response['html'];
414 document.getElementById('dashletsDialog_c').style.display = '';
415 SUGAR.mySugar.dashletsDialog.show();
417 eval(response['script']);
418 ajaxStatus.hideStatus();
421 var cObj = YAHOO.util.Connect.asyncRequest('GET', 'index.php?to_pdf=true&module='+module+'&action=DynamicAction&DynamicAction=dashletsDialog', {success: success, failure: success});
425 closeDashletsDialog: function(){
426 SUGAR.mySugar.dashletsDialog.hide();
427 if (this.closeDashletsDialogTimer != null) {
428 window.clearTimeout(this.closeDashletsDialogTimer);
430 this.closeDashletsDialogTimer = window.setTimeout("document.getElementById('dashletsDialog_c').style.display = 'none';", 2000);
433 toggleDashletCategories: function(category){
434 document.getElementById('search_string').value = '';
435 document.getElementById('searchResults').innerHTML = '';
437 var moduleTab = document.getElementById('moduleCategory');
438 var moduleTabAnchor = document.getElementById('moduleCategoryAnchor');
439 var moduleListDiv = document.getElementById('moduleDashlets');
441 var chartTab = document.getElementById('chartCategory');
442 var chartTabAnchor = document.getElementById('chartCategoryAnchor');
443 var chartListDiv = document.getElementById('chartDashlets');
445 var toolsTab = document.getElementById('toolsCategory');
446 var toolsTabAnchor = document.getElementById('toolsCategoryAnchor');
447 var toolsListDiv = document.getElementById('toolsDashlets');
449 var webTab = document.getElementById('webCategory');
450 var webTabAnchor = document.getElementById('webCategoryAnchor');
451 var webListDiv = document.getElementById('webDashlets');
455 moduleTab.className = 'active';
456 moduleTabAnchor.className = 'current';
457 moduleListDiv.style.display = '';
459 chartTab.className = '';
460 chartTabAnchor.className = '';
461 chartListDiv.style.display = 'none';
463 toolsTab.className = '';
464 toolsTabAnchor.className = '';
465 toolsListDiv.style.display = 'none';
467 webTab.className = '';
468 webTabAnchor.className = '';
469 webListDiv.style.display = 'none';
473 moduleTab.className = '';
474 moduleTabAnchor.className = '';
475 moduleListDiv.style.display = 'none';
477 chartTab.className = 'active';
478 chartTabAnchor.className = 'current';
479 chartListDiv.style.display = '';
481 toolsTab.className = '';
482 toolsTabAnchor.className = '';
483 toolsListDiv.style.display = 'none';
485 webTab.className = '';
486 webTabAnchor.className = '';
487 webListDiv.style.display = 'none';
491 moduleTab.className = '';
492 moduleTabAnchor.className = '';
493 moduleListDiv.style.display = 'none';
495 chartTab.className = '';
496 chartTabAnchor.className = '';
497 chartListDiv.style.display = 'none';
499 toolsTab.className = 'active';
500 toolsTabAnchor.className = 'current';
501 toolsListDiv.style.display = '';
503 webTab.className = '';
504 webTabAnchor.className = '';
505 webListDiv.style.display = 'none';
509 moduleTab.className = '';
510 moduleTabAnchor.className = '';
511 moduleListDiv.style.display = 'none';
513 chartTab.className = '';
514 chartTabAnchor.className = '';
515 chartListDiv.style.display = 'none';
517 toolsTab.className = '';
518 toolsTabAnchor.className = '';
519 toolsListDiv.style.display = 'none';
521 webTab.className = 'active';
522 webTabAnchor.className = 'current';
523 webListDiv.style.display = '';
530 document.getElementById('search_category').value = category;
534 searchDashlets: function(searchStr, searchCategory){
535 var moduleTab = document.getElementById('moduleCategory');
536 var moduleTabAnchor = document.getElementById('moduleCategoryAnchor');
537 var moduleListDiv = document.getElementById('moduleDashlets');
539 var chartTab = document.getElementById('chartCategory');
540 var chartTabAnchor = document.getElementById('chartCategoryAnchor');
541 var chartListDiv = document.getElementById('chartDashlets');
543 var toolsTab = document.getElementById('toolsCategory');
544 var toolsTabAnchor = document.getElementById('toolsCategoryAnchor');
545 var toolsListDiv = document.getElementById('toolsDashlets');
547 if (moduleTab != null && chartTab != null && toolsTab != null){
548 moduleListDiv.style.display = 'none';
549 chartListDiv.style.display = 'none';
550 toolsListDiv.style.display = 'none';
553 // dashboards case, where there are no tabs
555 chartListDiv.style.display = 'none';
558 var searchResultsDiv = document.getElementById('searchResults');
559 searchResultsDiv.style.display = '';
561 var success = function(data) {
562 eval(data.responseText);
564 searchResultsDiv.innerHTML = response['html'];
567 var cObj = YAHOO.util.Connect.asyncRequest('GET', 'index.php?to_pdf=true&module='+module+'&action=DynamicAction&DynamicAction=searchDashlets&search='+searchStr+'&category='+searchCategory, {success: success, failure: success});
571 collapseList: function(chartList){
572 document.getElementById(chartList+'List').style.display='none';
573 document.getElementById(chartList+'ExpCol').innerHTML = '<a href="javascript:void(0)" onClick="javascript:SUGAR.mySugar.expandList(\''+chartList+'\');"><img border="0" src="' + SUGAR.themes.image_server + 'index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=advanced_search.gif" align="absmiddle" />';
576 expandList: function(chartList){
577 document.getElementById(chartList+'List').style.display='';
578 document.getElementById(chartList+'ExpCol').innerHTML = '<a href="javascript:void(0)" onClick="javascript:SUGAR.mySugar.collapseList(\''+chartList+'\');"><img border="0" src="' + SUGAR.themes.image_server + 'index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=basic_search.gif" align="absmiddle" />';
581 collapseReportList: function(reportChartList){
582 document.getElementById(reportChartList+'ReportsChartDashletsList').style.display='none';
583 document.getElementById(reportChartList+'ExpCol').innerHTML = '<a href="javascript:void(0)" onClick="javascript:SUGAR.mySugar.expandReportList(\''+reportChartList+'\');"><img border="0" src="' + SUGAR.themes.image_server + 'index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=ProjectPlus.gif" align="absmiddle" />';
586 expandReportList: function(reportChartList){
587 document.getElementById(reportChartList+'ReportsChartDashletsList').style.display='';
588 document.getElementById(reportChartList+'ExpCol').innerHTML = '<a href="javascript:void(0)" onClick="javascript:SUGAR.mySugar.collapseReportList(\''+reportChartList+'\');"><img border="0" src="' + SUGAR.themes.image_server + 'index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=ProjectMinus.gif" align="absmiddle" />';
591 clearSearch: function(){
592 document.getElementById('search_string').value = '';
594 var moduleTab = document.getElementById('moduleCategory');
595 var moduleTabAnchor = document.getElementById('moduleCategoryAnchor');
596 var moduleListDiv = document.getElementById('moduleDashlets');
598 document.getElementById('searchResults').innerHTML = '';
599 if (moduleTab != null){
600 SUGAR.mySugar.toggleDashletCategories('module');
603 document.getElementById('searchResults').style.display = 'none';
604 document.getElementById('chartDashlets').style.display = '';
608 doneAddDashlets: function() {
609 SUGAR.mySugar.dashletsDialog.hide();
616 renderDashletsDialog: function(){
621 // adjust dialog height according to current page height
622 var pageHeight = document.documentElement.clientHeight;
623 var height = Math.min(maxHeight, pageHeight - minMargin * 2);
624 height = Math.max(height, minHeight);
626 SUGAR.mySugar.dashletsDialog = new YAHOO.widget.Dialog("dashletsDialog",
628 height: height + "px",
632 // effect:[{effect:YAHOO.widget.ContainerEffect.SLIDETOP, duration:0.5},{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.5}],
637 var listeners = new YAHOO.util.KeyListener(document, { keys : 27 }, {fn: function() {SUGAR.mySugar.closeDashletsDialog();} } );
638 SUGAR.mySugar.dashletsDialog.cfg.queueProperty("keylisteners", listeners);
640 document.getElementById('dashletsDialog').style.display = '';
641 SUGAR.mySugar.dashletsDialog.render();
642 document.getElementById('dashletsDialog_c').style.display = 'none';