Overview
Creating custom dashlets.
Sugar Dashlets
A Module View is the simplest Sugar Dashlet to create. This is a customizable ListView of a Sugar Dashlet. For this section we will use the MyAccountsDashlet as an example.
./modules/Accounts/Dashlets/MyAccountsDashlet/MyAccountsDashlet.php
<?php
require_once('include/Dashlets/DashletGeneric.php');
class MyAccountsDashlet extends DashletGeneric {
function MyAccountsDashlet($id, $def = null) {
global $current_user, $app_strings;
require('modules/Accounts/Dashlets/MyAccountsDashlet/MyAccountsDashlet.data.php');
parent::DashletGeneric($id, $def);
if(empty($def['title'])) $this->title = translate('LBL_HOMEPAGE_TITLE', 'Accounts');
$this->searchFields = $dashletData['MyAccountsDashlet']['searchFields'];
$this->columns = $dashletData['MyAccountsDashlet']['columns'];
$this->seedBean = new Account();
}
/**
* Overrides the generic process to include custom logic for email addresses,
* since they are no longer stored in a list view friendly manner.
* (A record may have an undetermined number of email addresses).
*
* @param array $lvsParams
*/
function process($lvsParams = array())
{
if (isset($this->displayColumns) && array_search('email1', $this->displayColumns) !== false) {
$lvsParams['custom_select'] = ', email_address as email1';
$lvsParams['custom_from'] = ' LEFT JOIN email_addr_bean_rel eabr ON eabr.deleted = 0 AND bean_module = \'Accounts\'' . ' AND eabr.bean_id = accounts.id AND primary_address = 1' . ' LEFT JOIN email_addresses ea ON ea.deleted = 0 AND ea.id = eabr.email_address_id';
}
if (isset($this->displayColumns) && array_search('parent_name', $this->displayColumns) !== false) {
$lvsParams['custom_select'] = empty($lvsParams['custom_select']) ? ', a1.name as parent_name ' : $lvsParams['custom_select'] . ', a1.name as parent_name '; $lvsParams['custom_from'] = empty($lvsParams['custom_from']) ? ' LEFT JOIN accounts a1 on a1.id = accounts.parent_id' : $lvsParams['custom_from'] . ' LEFT JOIN accounts a1 on a1.id = accounts.parent_id';
}
parent::process($lvsParams);
}
}
?>
All the metadata for this Sugar Dashlet is defined in the constructor. $searchFields are the search inputs that can be applied to the view. Defining these here will tell which input fields to generate corresponding filters when the user configures the Sugar Dashlet. $columns define the available columns to the user. These contain the visible columns and the columns the user can make visible. Initially, both columns and searchFields are defined in MyAccountsDashlet.data.php.
./modules/Accounts/Dashlets/MyAccountsDashlet/MyAccountsDashlet.data.php
<?php
if (!defined('sugarEntry') || !sugarEntry)
die('Not A Valid Entry Point');
global $current_user;
$dashletData['MyAccountsDashlet']['searchFields'] = array(
'date_entered' => array(
'default' => ''
),
'account_type' => array(
'default' => ''
),
'industry' => array(
'default' => ''
),
'billing_address_country' => array(
'default' => ''
),
'team_id' => array(
'default' => '',
'label' => 'LBL_TEAMS'
),
'assigned_user_id' => array(
'type' => 'assigned_user_name',
'default' => $current_user->name,
'label' => 'LBL_ASSIGNED_TO'
)
);
$dashletData['MyAccountsDashlet']['columns'] = array(
'name' => array(
'width' => '40',
'label' => 'LBL_LIST_ACCOUNT_NAME',
'link' => true,
'default' => true
),
'website' => array(
'width' => '8',
'label' => 'LBL_WEBSITE',
'default' => true
),
'phone_office' => array(
'width' => '15',
'label' => 'LBL_LIST_PHONE',
'default' => true
),
'phone_fax' => array(
'width' => '8',
'label' => 'LBL_PHONE_FAX'
),
'phone_alternate' => array(
'width' => '8',
'label' => 'LBL_OTHER_PHONE'
),
'billing_address_city' => array(
'width' => '8',
'label' => 'LBL_BILLING_ADDRESS_CITY'
),
'billing_address_street' => array(
'width' => '8',
'label' => 'LBL_BILLING_ADDRESS_STREET'
),
'billing_address_state' => array(
'width' => '8',
'label' => 'LBL_BILLING_ADDRESS_STATE'
),
'billing_address_postalcode' => array(
'width' => '8',
'label' => 'LBL_BILLING_ADDRESS_POSTALCODE'
),
'billing_address_country' => array(
'width' => '8',
'label' => 'LBL_BILLING_ADDRESS_COUNTRY',
'default' => true
),
'shipping_address_city' => array(
'width' => '8',
'label' => 'LBL_SHIPPING_ADDRESS_CITY'
),
'shipping_address_street' => array(
'width' => '8',
'label' => 'LBL_SHIPPING_ADDRESS_STREET'
),
'shipping_address_state' => array(
'width' => '8',
'label' => 'LBL_SHIPPING_ADDRESS_STATE'
),
'shipping_address_postalcode' => array(
'width' => '8',
'label' => 'LBL_SHIPPING_ADDRESS_POSTALCODE'
),
'shipping_address_country' => array(
'width' => '8',
'label' => 'LBL_SHIPPING_ADDRESS_COUNTRY'
),
'email1' => array(
'width' => '8',
'label' => 'LBL_EMAIL_ADDRESS_PRIMARY'
),
'parent_name' => array(
'width' => '15',
'label' => 'LBL_MEMBER_OF',
'sortable' => false
),
'date_entered' => array(
'width' => '15',
'label' => 'LBL_DATE_ENTERED'
),
'date_modified' => array(
'width' => '15',
'label' => 'LBL_DATE_MODIFIED'
),
'created_by_name' => array(
'width' => '8',
'label' => 'LBL_CREATED'
),
'assigned_user_name' => array(
'width' => '8',
'label' => 'LBL_LIST_ASSIGNED_USER'
),
'team_name' => array(
'width' => '15',
'label' => 'LBL_LIST_TEAM'
)
);
?>
Please note that modifications made in studio to columns and searchFields will be located in ./custom/modules/Accounts/metadata/dashletviewdefs.php. These settings will overrdie the layout for all dashlets under that module name.
This data file along with the MyAccountsDashlet.meta.php file will create a generic module view Sugar Dashlet.
./Accounts/Dashlets/MyAccountsDashlet/MyAccountsDashlet.meta.php
<?php
global $app_strings;
$dashletMeta['MyAccountsDashlet'] = array(
'module' => 'Accounts',
'title' => translate('LBL_HOMEPAGE_TITLE', 'Accounts'),
'description' => 'A customizable view into Accounts',
'category' => 'Module Views'
);
?>
Custom Sugar Dashlets
Sugar Dashlets are more than generic module views. They can provide unlimited functionality and integration.
For this section we will use the JotPad Sugar Dashlet as an example. The JotPad is a simple note taking Sugar Dashlet. A user double clicks on the Sugar Dashlet and can enter any text in the Sugar Dashlet. When the user clicks outside of the textarea, the text is automatically saved via AJAX.
There are six files that define this Sugar Dashlet residing in the ./modules/Home/Dashlets/JotPadDashlet/ directory:
- JotPadDashlet.php – JotPad Class
- JotPadDashlet.meta.php – metadata about the Sugar Dashlet
- JotPadDashlet.tpl – Display Template
- JotPadDashletOptions.tpl – Configuration template
- JotPadDashletScript.tpl - Javascript
- JotPadDashlet.en_us.lang.php – English Language file
JotPadDashlet.php
The JotPadDashlet.php file handles the display of the dashlet.
./modules/Home/Dashlets/JotPadDashlet/JotPadDashlet.php:
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
require_once('include/Dashlets/Dashlet.php');
class JotPadDashlet extends Dashlet {
var $savedText; // users's saved text
var $height = '200'; // height of the pad
/**
* Constructor
*
* @global string current language
* @param guid $id id for the current dashlet (assigned from Home module)
* @param array $def options saved for this dashlet
*/
function JotPadDashlet($id, $def) {
$this->loadLanguage('JotPadDashlet'); // load the language strings here
if(!empty($def['savedText'])) // load default text is none is defined
$this->savedText = $def['savedText'];
else
$this->savedText = $this->dashletStrings['LBL_DEFAULT_TEXT'];
if(!empty($def['height'])) // set a default height if none is set
$this->height = $def['height'];
parent::Dashlet($id); // call parent constructor
$this->isConfigurable = true; // dashlet is configurable
$this->hasScript = true; // dashlet has javascript attached to it
// if no custom title, use default
if(empty($def['title'])) $this->title = $this->dashletStrings['LBL_TITLE'];
else $this->title = $def['title'];
}
/**
* Displays the dashlet
*
* @return string html to display dashlet
*/
function display() {
$ss = new Sugar_Smarty();
$ss->assign('savedText', SugarCleaner::cleanHtml($this->savedText));
$ss->assign('saving', $this->dashletStrings['LBL_SAVING']);
$ss->assign('saved', $this->dashletStrings['LBL_SAVED']);
$ss->assign('id', $this->id);
$ss->assign('height', $this->height);
$str = $ss->fetch('modules/Home/Dashlets/JotPadDashlet/JotPadDashlet.tpl');
return parent::display($this->dashletStrings['LBL_DBLCLICK_HELP']) . $str . '
'; // return parent::display for title and such
}
/**
* Displays the javascript for the dashlet
*
* @return string javascript to use with this dashlet
*/
function displayScript() {
$ss = new Sugar_Smarty();
$ss->assign('saving', $this->dashletStrings['LBL_SAVING']);
$ss->assign('saved', $this->dashletStrings['LBL_SAVED']);
$ss->assign('id', $this->id);
$str = $ss->fetch('modules/Home/Dashlets/JotPadDashlet/JotPadDashletScript.tpl');
return $str; // return parent::display for title and such
}
/**
* Displays the configuration form for the dashlet
*
* @return string html to display form
*/
function displayOptions() {
global $app_strings;
$ss = new Sugar_Smarty();
$ss->assign('titleLbl', $this->dashletStrings['LBL_CONFIGURE_TITLE']);
$ss->assign('heightLbl', $this->dashletStrings['LBL_CONFIGURE_HEIGHT']);
$ss->assign('saveLbl', $app_strings['LBL_SAVE_BUTTON_LABEL']);
$ss->assign('clearLbl', $app_strings['LBL_CLEAR_BUTTON_LABEL']);
$ss->assign('title', $this->title);
$ss->assign('height', $this->height);
$ss->assign('id', $this->id);
return parent::displayOptions() . $ss->fetch('modules/Home/Dashlets/JotPadDashlet/JotPadDashletOptions.tpl');
}
/**
* called to filter out $_REQUEST object when the user submits the configure dropdown
*
* @param array $req $_REQUEST
* @return array filtered options to save
*/
function saveOptions($req) {
global $sugar_config, $timedate, $current_user, $theme;
$options = array();
$options['title'] = $_REQUEST['title'];
if(is_numeric($_REQUEST['height'])) {
if($_REQUEST['height'] > 0 && $_REQUEST['height'] <= 300) $options['height'] = $_REQUEST['height'];
elseif($_REQUEST['height'] > 300) $options['height'] = '300';
else $options['height'] = '100';
}
$options['savedText'] = $this->savedText;
return $options;
}
/**
* Used to save text on textarea blur. Accessed via Home/CallMethodDashlet.php
* This is an example of how to to call a custom method via ajax
*/
function saveText() {
$json = getJSONobj();
if(isset($_REQUEST['savedText'])) {
$optionsArray = $this->loadOptions();
$optionsArray['savedText']=$json->decode(html_entity_decode($_REQUEST['savedText']));
$optionsArray['savedText']=SugarCleaner::cleanHtml(nl2br($optionsArray['savedText']));
$this->storeOptions($optionsArray);
}
else {
$optionsArray['savedText'] = '';
}
echo 'result = ' . $json->encode(array('id' => $_REQUEST['id'],
'savedText' => $optionsArray['savedText']));
}
}
?>