Testing UI Model
Testing UI Model
Testing UI Model
2
created from support.sugarcrm.com on 28.09.2014 by Editha Kuske
UI Model
An overview of layouts, views, fields, and the various other aspects of the user interface.
UI Model Overview.
Sidecar
Sidecar is a client side application.
Clients
Clients are the various platforms that use Sidecar to render the user interface. Each platform type will have
a specific path for its components.
Layouts
A layout is a component which wraps and places multiple views or nested layouts on a page.
Views
Views are component plugins that render data from a context.
Fields
Fields are component plugins that render widgets for individual values pulled from models.
Dashlets
Dashlets are special view component plugins that render data from a context and make use of the
Dashlet plugin.
Handlebars
Handlebars is a JavaScript library that allows for Sugar to create semantic templates.
Subpanels
Overview of the subpanel framework.
Metadata
Overview of the metadata framework.
Routes
How routes are defined and used within the system.
Legacy MVC
Legacy MVC Overview.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/
Powered by TCPDF (www.tcpdf.org)
Sidecar
Overview
Sidecar is a client side application.
Sidecar
Sidecar is a new client platform that moves processing to the client side for page rendering. It contains a complete
MVC framework based on the Backbone.js library. By creating what is known as a Single Page Web App, server
load is drastically reduced and the clients performance is increased. To explain this further, the application no
longer sends down html content but rather pure JSON data. The JSON data, returned by the v10 API, defines the
applications modules, records, and ACLs allowing the UI processing to happen on the client side and is significantly
less in terms of data transfer.
Components
Sidecar is built atop several components
Backbone.js
Backbone.js gives structure to web applications by providing models with key-value binding and custom events and
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/05_Sidecar/
Components
Everything that is renderable on the page is a component. A layout is a component which serves as a canvas for one or
more views and/or other layouts. All pages will have at least one master layout, and that master layout can contain multiple
nested layouts.
Layouts
Layouts are components which render the overall page. They are used to define the rows, columns, and fluid
layouts that the content is displayed to the user in.
Example layouts include:
Rows
Columns
Bootstrap fluid layouts, and
Drawers / Drop downs
Views
Views are components which render data from a context and may or may not include field components. Example views
include not only record and list views but also widgets including:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/05_Sidecar/
Fields
Fields render widgets for individual values pulled from the models and handle formatting (or stripping the formatting
of) field values. Just like Layouts and Views, Fields also extend Backbone Views. More information on fields can be
found in the Fields section.
Context
A Context is a container for the relevant data for a page, and it has three major attributes:
Module : The name of the module this context is based on
Model : The primary or selected model for this context
Collection : The set of models currently loaded on this context
Contexts are used to retrieve related data and to paginate through lists of data.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/05_Sidecar/
Powered by TCPDF (www.tcpdf.org)
Clients
Overview
Clients are the various platforms that use Sidecar to render the user interface. Each platform type will have a
specific path for its components.
Clients
Clients are the various platforms that access and use Sidecar to render content. Depending on the platform you are
using, the layout, view and, metadata will be driven based on its client type. The client types are listed below in the
following sections.
base
The base client is the Sugar application that you use to access your data. The framework specific views, layouts,
and fields for this application will be found in:
./clients/base/
./custom/clients/base/
./modules/<module>/clients/base/
./custom/modules/<module>/clients/base/
mobile
The mobile client is the SugarCRM Mobile application that you use to access data from your mobile device. The
framework specific views, layouts, and fields for this application will be found in:
./clients/mobile/
./custom/clients/mobile/
./modules/<module>/clients/mobile/
./custom/modules/<module>/clients/mobile/
portal
The portal client is the customer self-service portal application that comes with the Enterprise and Ultimate editions
of Sugar. The framework specific views, layouts, and fields for this application will be found in:
./clients/portal/
./custom/clients/portal/
./modules/<module>/clients/portal/
./custom/modules/<module>/clients/portal/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/10_Clients/
Powered by TCPDF (www.tcpdf.org)
Layouts
A layout is a component which wraps and places multiple views or nested layouts on a page.
Layouts Overview.
Introduction
A layout is a component which wraps and places multiple views or nested layouts on a page.
Examples
Layout examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
A layout is a component which wraps and places multiple views or nested layouts on a page.
Layouts
Layouts are component plugins that define the overall layout and positioning of the page. Layouts replace the
previous concept of MVC views and are used system wide to generate rows, columns, bootstrap fluid layouts, and
popups. Layout components are typically made up of a controller JavaScript file (.js) and a PHP file (.php),
however, layout types vary and are not dependent on having both files.
Hierarchy Diagram
The layout components are loaded in the following manner:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/00_Introduction/
Note: The Sugar application client type is "base". More information on the various client types can be found in the
Clients section.
http://{site url}/#<module>/
To route the user to the record layout for a specific record, use:
http://{site url}/#<module>/f82d09cb-48cd-a1fb-beae-521cf39247b5
http://{site url}/#<module>/layout/<layout>
Layout Example
The list layout, located in ./clients/base/layouts/list/, handles the layout for the list view. The sections below will
outline the various files that render this view.
JavaScript
The list.js, shown below, contains the JavaScript used to place the layout content.
./clients/base/layouts/list/list.js
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/00_Introduction/
Layout Definition
The layout definition is contained as an array in list.php. This layout definition contains 4 views: massupdate,
massaddtolist, recordlist, and list-bottom.
./clients/base/layouts/list/list.php
<?php
$viewdefs['base']['layout']['list'] = array(
'components' =>
array(
array(
'view' => 'massupdate',
),
array(
'view' => 'massaddtolist',
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/00_Introduction/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Examples
Layout examples.
Creating Layouts
How to create a custom layout component.
Overriding Layouts
How to override a stock layout component.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/
Powered by TCPDF (www.tcpdf.org)
Creating Layouts
Overview
How to create a custom layout component.
Creating a Layout
This example will create a custom layout named "my-layout". As layouts will define the various components to load
on the page, this layout will render a custom view named "my-view".
./custom/clients/base/layouts/my-layout/my-layout.php
<?php
$viewdefs['base']['layout']['my-layout'] = array(
'type' => 'simple',
'components' => array(
array(
'view' => 'my-view',
),
),
);
Creating a View
The view component will render the actual content we want to see on the page. The view below will display a
clickable cube icon that will spin once clicked by the user.
./custom/clients/base/views/my-view/my-view.js
({
className: 'my-view tcenter',
cubeOptions: {
spin: false
},
events: {
'click .sugar-cube': 'spinCube'
},
spinCube: function() {
this.cubeOptions.spin = !this.cubeOptions.spin;
this.render();
}
})
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Creating_Layouts/
./custom/clients/base/views/my-view/my-view.hbs
<style>
div.my-view
{
padding-top: 5%%;
}
div.my-view .sugar-cube
{
fill:#bbbbbb;
height:200px;
width:200px;
display: inline;
}
</style>
<h1>My View</h1>
{{{subFieldTemplate 'sugar-cube' 'detail' cubeOptions}}}
<p>Click to spin the cube!</p>
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
http://{site url}/#<module>/layout/my-layout
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Creating_Layouts/
Powered by TCPDF (www.tcpdf.org)
Overriding Layouts
Overview
How to override a stock layout component.
That line will change the record layout from using the base record.js view, ./clients/base/views/record/record.js, to
instead use a custom view that we will create in ./custom/clients/base/views/my-record/my-record.js. At this point,
your custom layout override should be very similar to the example below:
./custom/clients/base/layouts/record/record.php
<?php
$viewdefs['base']['layout']['record'] = array(
'components' => array(
array(
'layout' => array(
'components' => array(
array(
'layout' => array(
'components' => array(
array(
'view' => 'my-record',
'primary' => true,
),
array(
'layout' => 'extra-info',
),
array(
'layout' => array(
'name' => 'filterpanel',
'span' => 12,
'last_state' => array(
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Overriding_Layouts/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Overriding_Layouts/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Overriding_Layouts/
({
extendsFrom: 'RecordView',
initialize: function (options) {
app.view.invokeParent(this, {type: 'view', name: 'record', method: 'initializ
e', args:[options]});
//log this point
console.log("**** Override called");
}
})
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/20_Layouts/90_Examples/Overriding_Layouts/
Powered by TCPDF (www.tcpdf.org)
Views
Views are component plugins that render data from a context.
Views Overview.
Introduction
An overview of how view components work.
Filters
An overview of how to implement the various types of filters for record list views.
Examples
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
An overview of how view components work.
Views
Views are component plugins that render data from a context. View components may contain field components
and are typically made up of a controller JavaScript file (.js) and at least one Handlebars template (.hbt).
Note: The Sugar application client type is base. More information on the various client types can be found
in the Clients section.
Components
Controller
The views controller is what controls the view in how data is loaded, formatted, and manipulated. The controller is
the JavaScript file named after the view. A controller file can be found in any of the directories shown in the
hierarchy diagram above. In the Example of the record view, the main controller file is located in
./clients/base/views/record/record.js and any modules extending this controller will have a file located in
./modules/<module>/clients/base/views/record/record.js.
Handlebar Template
The views template is built on Handlebars and is what adds the display markup for the data. The template is
typically named after the view or an action in the view. In the example of the record view, the main template us
located in ./clients/base/views/record/record.hbs. This template will take the data fetched from the REST API to
render the display for the user. More information on templates can be found in the Handlebars section.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/00_Introduction/
Extending Views
When working with module views, it is important to understand the difference between overriding and extending a
view. Overriding is essentially creating or copying a view to be used by your application that is not extending its
parent. By default, some module views already extend the core ./clients/base/views/record/record.js controller. An
example of this is the accounts RecordView
./modules/Accounts/clients/base/views/record/record.js
({
extendsFrom: 'RecordView',
/**
* @inheritdoc
*/
initialize: function(options) {
this.plugins = _.union(this.plugins || [], ['HistoricalSummary']);
this._super('initialize', [options]);
}
})
As you can see, this view has the property extendsFrom: 'RecordView'. This property tells Sidecar that the view is
going to extend its parent RecordView. In addition to this, you can see that the initialize method is also calling
this._super('initialize', [options]);. Calling this._super tells Sidecar to execute the parent function. The major benefit
of doing this is that any updates to ./clients/base/views/record/record.js will be reflected for the module without any
modifications being made to ./modules/Accounts/clients/base/views/record/record.js. You should note that when
using extendsFrom, the parent views are called similarly to the load hierarchy:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/00_Introduction/
Controller
The access-denied.js, shown below, controls the manipulation actions of the view.
./clients/base/views/access-denied/access-denied.js
({
className: 'access-denied tcenter',
cubeOptions: {spin: false},
events: {
'click .sugar-cube': 'spinCube'
},
spinCube: function() {
this.cubeOptions.spin = !this.cubeOptions.spin;
this.render();
}
})
Attributes
Attribute
className
cubeOptions
events
spinCube
Description
The CSS class to apply to the view.
A set of options that are passed to the spinCube function when called.
A list of the view events. This view executes the spinCube function when the
sugar cube is clicked.
Function to control the start and stop of the cube spinning.
Handlebar Template
The access-denied.hbs file defines the format of the views content. As this view is used for restricting access, it
displays a message to the user describing the restriction.
./clients/base/views/access-denied/access-denied.hbs
<div class="error-message">
<h1>{{str 'ERR_NO_VIEW_ACCESS_TITLE'}}</h1>
<p>{{str 'ERR_NO_VIEW_ACCESS_REASON'}}</p>
<p>{{str 'ERR_NO_VIEW_ACCESS_ACTION'}}</p>
</div>
{{{subFieldTemplate 'sugar-cube' 'detail' cubeOptions}}}
Helpers
Helpers
str
subFieldTemplate
Description
Handlebars helper to render the label string.
Handlebars helper to render the cube content.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/00_Introduction/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Filters
Overview
An overview of how to implement the various types of filters for record list views.
Filters
Filters are a way to predefine searches on views that render a list of records. This functionality can be used on List
Views, Pop-up Searches, and Lookups.
Filters contain the following properties:
Property
id
name
Type
String
String
filter_definition
Array
editable
Boolean
is_template
Boolean
Description
A unique identifier for the filter
The label key for the display label
of the filter
The filter definition to apply to the
results
Determines whether the user can
edit the filter
Note: If you are creating a
predefined filter for a user, this
should be set to false.
Determines if the filter is available
as a template
Note: Related to initial pop-up
filters.
The following example will demonstrate how to add a predefined filter on the Accounts module to return all records
with an account type of Customer and industry of Other.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
<?php
$mod_strings['LBL_FILTER_ACCOUNT_BY_TYPE_AND_INDUSTRY'] = 'Customer/Other Accounts';
<?php
$viewdefs['Accounts']['base']['filter']['basic']['filters'][] = array(
'id' => 'filterAccountByTypeAndIndustry',
'name' => 'LBL_FILTER_ACCOUNT_BY_TYPE_AND_INDUSTRY',
'filter_definition' => array(
array(
'account_type' => array(
'$in' => array(
'Customer',
),
),
),
array(
'industry' => array(
'$in' => array(
'Other',
),
),
),
),
'editable' => false,
'is_template' => false,
);
You should notice that the editable and is_template options have been set to false. If editable is not set to
false, the filter will not be displayed in the list view filters list.
Finally, we will need to navigate to Admin > Repair and click Quick Repair and Rebuild to rebuild the
extensions and make the predefined filter available for users.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
<?php
$mod_strings['LBL_FILTER_ACCOUNT_TEMPLATE'] = 'Customer Accounts By A Dynamic User';
<?php
$viewdefs['Accounts']['base']['filter']['basic']['filters'][] = array(
'id' => 'filterAccountTemplate',
'name' => 'LBL_FILTER_ACCOUNT_TEMPLATE',
'filter_definition' => array(
array(
'account_type' => array(
'$in' => array(),
),
),
array(
'assigned_user_id' => ''
)
),
'editable' => true,
'is_template' => true,
);
As you can see, the filter_definition contains arrays for account_type and assigned_user_id.
These filter definitions will receive their values from the Contact record views metadata. You should also note
that this filter has editable and is_template set to true. This is required for initial filters.
Once the filter template is in place, we will need to modify the Contact record views metadata. To accomplish
this, we will edit ./custom/modules/Contacts/clients/base/views/record/record.php to adjust the account_name field.
If this file does not exist in your local Sugar install, you can navigate to Admin > Studio > Contacts > Layouts >
Record View and click Save & Deploy to generate it. Within this file, we will need to identify the
panel_body array as shown below:
1 =>
array (
'name' => 'panel_body',
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
Next, we will modify the account_name field to contain our initial filter parameters.
1 =>
array (
'name' => 'panel_body',
'label' => 'LBL_RECORD_BODY',
'columns' => 2,
'labelsOnTop' => true,
'placeholders' => true,
'newTab' => false,
'panelDefault' => 'expanded',
'fields' =>
array (
0 => 'title',
1 => 'phone_mobile',
2 => 'department',
3 => 'do_not_call',
4 => array (
//field name
'name' => 'account_name',
//the name of the filter template
'initial_filter' => 'filterAccountTemplate',
//the display label for users
'initial_filter_label' => 'LBL_FILTER_ACCOUNT_TEMPLATE',
//the hardcoded filters to pass to the templates filter definition
'filter_populate' => array(
'account_type' => array('Customer')
),
//the dynamic filters to pass to the templates filter definition
'filter_relate' => array(
'assigned_user_id' => 'assigned_user_id',
)
),
5 => 'email',
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
Finally, we will need to navigate to Admin > Repair and click Quick Repair and Rebuild. This will rebuild
the extensions and make the initial filter available for users when selecting a parent account for a contact.
//create filter
var filterOptions = new app.utils.FilterOptions()
.config({
'initial_filter': 'filterAccountTemplate',
'initial_filter_label': 'LBL_FILTER_ACCOUNT_TEMPLATE',
'filter_populate': {
'account_type': ['Customer'],
'assigned_user_id': 'seed_sally_id'
}
})
.format();
//open drawer
app.drawer.open({
layout: 'selection-list',
context: {
module: 'Accounts',
filterOptions: filterOptions,
parent: this.context
}
});
To create a filtered drawer with dynamic values, we can create a filter object and populate the config.filter_relate
property using the populateRelate method as shown below:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/05_Filters/
Powered by TCPDF (www.tcpdf.org)
Examples
View Examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/
Powered by TCPDF (www.tcpdf.org)
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
Note: When copying this array into your metadata, you will need to change $module with the text string of your
modules name.
For standard button types, the button definitions will contain the following properties:
Property
Type
name
label
css_class
showOn
Description
The widget type. Button types can be button, rowaction,
shareaction, or actiondropdown.
The name of the button.
The label string key for the display text of the button.
The CSS class to append to the button
The ACL action of the button. Values can be edit or view.
For this example we will be adding our custom button to the main dropdown. For actiondropdown types, there will
be an additional buttons array for you to specify the dropdown list of buttons. The button definitions in this array will
contain the following properties:
Property
Type
event
name
label
acl_action
Description
The widget type. Button types can be button, rowaction,
shareaction, or actiondropdown. Most custom buttons are
typed as rowaction.
The event name of the button. The name format is
button:button_name:click.
The name of the button.
The label string key for the display text of the button.
The ACL action of the button. Values can be edit or view.
array(
'type' => 'rowaction',
'event' => 'button:validate_postal_code:click',
'name' => 'validate_postal_code',
'label' => 'LBL_VALIDATE_POSTAL_CODE',
'acl_action' => 'view',
),
<?php
$viewdefs['Accounts'] =
array (
'base' =>
array (
'view' =>
array (
'record' =>
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
<?php
$mod_strings['LBL_VALIDATE_POSTAL_CODE'] = 'Validate Postal Code';
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
({
extendsFrom: 'RecordView',
zipJSON: {},
initialize: function (options) {
app.view.invokeParent(this, {type: 'view', name: 'record', method: 'initializ
e', args:[options]});
//add listener for custom button
this.context.on('button:validate_postal_code:click', this.validate_postal_cod
e, this);
},
validate_postal_code: function() {
//example of getting field data from current record
var AcctID = this.model.get('id');
var currentCity = this.model.get('billing_address_city');
var currentZip = this.model.get('billing_address_postalcode');
//jQuery AJAX call to Zippopotamus REST API
$.ajax({
url: 'http://api.zippopotam.us/us/' + currentZip,
success: function(data) {
this.zipJSON = data;
var city = this.zipJSON.places[0]['place name'];
if (city === currentCity)
{
app.alert.show('address-ok', {
level: 'success',
messages: 'City and Zipcode match.',
autoClose: true
});
}
else
{
app.alert.show('address-ok', {
level: 'error',
messages: 'City and Zipcode do not match.',
autoClose: false
});
}
}
});
}
})
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Buttons_to_the_Record_View/
Powered by TCPDF (www.tcpdf.org)
({
extendsFrom: 'CreateActionsView',
initialize: function (options) {
/*
If you are on 7.2.0, there is a dependency bug that can cause the screen to
render an empty form.
To correct this, uncomment the code below:
if (!_.has(options.meta, "template"))
{
options.meta.template = 'record';
}
*/
this._super('initialize', [options]);
//add validation tasks
this.model.addValidationTask('check_account_type', _.bind(this._doValidateChe
ckType, this));
this.model.addValidationTask('check_email', _.bind(this._doValidateEmail, thi
s));
},
_doValidateCheckType: function(fields, errors, callback) {
//validate type requirements
if (this.model.get('account_type') == 'Customer' && _.isEmpty(this.model.get(
'phone_office')))
{
errors['phone_office'] = errors['phone_office'] || {};
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Next, we will need to duplicate our validation logic for the record view. This will handle the validation when editing
existing records.
./custom/modules/Accounts/clients/base/views/record/record.js
({
/* because accounts already has a record view, we need to extend it */
extendsFrom: 'AccountsRecordView',
/* if you are running 7.2.0, you will need to use RecordView */
//extendsFrom: 'RecordView',
initialize: function (options) {
this._super('initialize', [options]);
//add validation tasks
this.model.addValidationTask('check_account_type', _.bind(this._doValidateChe
ckType, this));
this.model.addValidationTask('check_email', _.bind(this._doValidateEmail, thi
s));
},
_doValidateCheckType: function(fields, errors, callback) {
//validate requirements
if (this.model.get('account_type') == 'Customer' && _.isEmpty(this.model.get(
'phone_office')))
{
errors['phone_office'] = errors['phone_office'] || {};
errors['phone_office'].required = true;
}
callback(null, fields, errors);
},
_doValidateEmail: function(fields, errors, callback) {
//validate email requirements
if (_.isEmpty(this.model.get('email')))
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
({
className:"hidden",
_render: function() {
//No-op, Do nothing here
},
bindDataChange: function() {
//add validation tasks
this.model.addValidationTask('check_account_type', _.bind(this._doValidateChec
kType, this));
this.model.addValidationTask('check_email', _.bind(this._doValidateEmail, this
));
},
_doValidateCheckType: function(fields, errors, callback) {
//validate type requirements
if (this.model.get('account_type') == 'Customer' && _.isEmpty(this.model.get('
phone_office')))
{
errors['phone_office'] = errors['phone_office'] || {};
errors['phone_office'].required = true;
}
callback(null, fields, errors);
},
_doValidateEmail: function(fields, errors, callback) {
//validate email requirements
if (_.isEmpty(this.model.get('email')))
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Next, depending on your selected module, we will need to duplicate its create-actions layout to the modules custom
folder to handle record creation. In our accounts example, we have an existing
./modules/Accounts/clients/base/layouts/create-actions/create-actions.php file so we will need to duplicate this file
to ./custom/modules/Accounts/clients/base/layouts/create-actions/create-actions.php. After this has been
completed, we will need to append our new custom view to the components. We will need to append:
array(
'view' => 'validate-account',
),
As shown below:
./custom/modules/Accounts/clients/base/layouts/create-actions/create-actions.php
<?php
$viewdefs['Accounts']['base']['layout']['create-actions'] = array(
'components' =>
array(
array(
'layout' =>
array(
'components' =>
array(
array(
'layout' =>
array(
'components' =>
array(
array(
'view' => 'create-actions',
),
array(
'view' => 'validate-account',
),
),
'type' => 'simple',
'name' => 'main-pane',
'span' => 8,
),
),
array(
'layout' =>
array(
'components' =>
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Lastly, depending on your selected module, we will need to duplicate its record layout to the modules custom folder
to handle editing a record. In our accounts example, we do not have an existing
./modules/Accounts/clients/base/layouts/record/record.php file so we will need to duplicate the core
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
$viewdefs['base']['layout']['record'] = array(
To:
$viewdefs['Accounts']['base']['layout']['record'] = array(
After this has been completed, we will need to append our new custom view to the components. We will need to
append:
array(
'view' => 'validate-account',
),
As shown below:
./custom/modules/Accounts/clients/base/layouts/record/record.php
<?php
$viewdefs['Accounts']['base']['layout']['record'] = array(
'components' => array(
array(
'layout' => array(
'components' => array(
array(
'layout' => array(
'components' => array(
array(
'view' => 'record',
'primary' => true,
),
array(
'view' => 'validate-account',
),
array(
'layout' => 'extra-info',
),
array(
'layout' => array(
'name' => 'filterpanel',
'span' => 12,
'last_state' => array(
'id' => 'record-filterpanel',
'defaults' => array(
'toggle-view' => 'subpanels',
),
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
Error Messages
When throwing a validation error, Sugar has several stock messages you may choose to use. They are listed
below:
Error Key
Label
Description
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
ERROR_MAXVALUE
This maximum value of this field.
ERROR_MINVALUE
This minimum value of this field.
ERROR_MAX_FIELD_LEN The max length of this field.
GTH
minLength
ERROR_MIN_FIELD_LENG The min length of this field.
TH
datetime
ERROR_DATETIME
This field requires a valid date.
required
ERROR_FIELD_REQUIRE This field is required.
D
email
ERROR_EMAIL
There is an invalid email address.
primaryEmail ERROR_PRIMARY_EMAIL No primary email address is set.
duplicateEmai ERROR_DUPLICATE_EMAI There is a duplicate email address.
l
L
number
ERROR_NUMBER
This field requires a valid number.
isBefore
ERROR_IS_BEFORE
The date of this field can not be after another
date.
isAfter
ERROR_IS_AFTER
The date of this field can not be before another
date.
You also have the option of displaying multiple error messages at a time. The example below would throw an error
message notifying the user that the selected field is required and that it is also not a number.
<?php
$app_strings['ERR_CUSTOM_MESSAGE'] = 'My custom error message.';
./custom/modules/Accounts/clients/base/views/record/record.js
({
extendsFrom: 'RecordView',
initialize: function (options) {
this._super('initialize', [options]);
//add custom message key
app.error.errorName2Keys['custom_message'] = 'ERR_CUSTOM_MESSAGE';
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Adding_Field_Validation_to_the_Record_View/
Powered by TCPDF (www.tcpdf.org)
({
className: 'tcenter',
loadData: function (options) {
//populate your data
myData=new Object();
myData.myProperty = "My Value";
this.myData = myData;
/*
//alternatively, you can pass in a JSON array to populate your data
myData = $.parseJSON( '{"myData":{"myProperty":"My Value"}}' );
_.extend(this, myData);
*/
this.render();
}
})
Next, you will add your handlebars template to render the data:
./custom/clients/base/views/my-dataview/my-dataview.hbs
{{#with myData}}{{myProperty}}{{/with}}
Once the files are in place, you will need to add your view to a layout and then navigate to Admin > Repair > Quick
Repair and Rebuild.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/30_Views/Examples/Passing_Data_to_Templates/
Powered by TCPDF (www.tcpdf.org)
Fields
Fields are component plugins that render widgets for individual values pulled from models.
Fields Overview.
Introduction
An overview of how field components work.
Examples
Field examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
An overview of how field components work.
Fields
Fields are component plugins that render widgets for individual values pulled from models. Field components
handle the rendering and formatting of field values and are made up of a controller JavaScript file (.js) and at least
one Handlebars template (.hbt).
Hierarchy Diagram
The field components are loaded in the following manner:
Note: The Sugar application client type is "base". More information on the various client types can be found in the
Clients section.
Field Example
The bool field, located in ./clients/base/fields/bool/, is what handles the display for checkbox boolean values. The
sections below will outline the various files that render this field type.
Controller
The bool.js, shown below, overrides the base _render to disable the field. The format and unformat functions
handle the manipulation of the fields value.
./clients/base/fields/bool/bool.js
({
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/00_Introduction/
_render: function() {
app.view.Field.prototype._render.call(this);
if(this.tplName === 'disabled') {
this.$(this.fieldTag).attr("disabled", "disabled");
}
},
unformat:function(value){
value = this.$el.find(".checkbox").prop("checked") ? "1" : "0";
return value;
},
format:function(value){
value = (value=="1") ? true : false;
return value;
}
})
Attributes
Attribute
_render
unformat
format
Description
Function to render the field.
Function to dynamically check the checkbox based on the value.
Function to format the value for storing in the database.
Handlebar Templates
The edit.hbs file defines the display of the control when the edit view is used. This layout is for displaying the
editable form element that renders a clickable checkbox control for the user.
./clients/base/fields/bool/edit.hbs
{{#if def.text}}
<label>
<input type="checkbox" class="checkbox"{{#if value}} checked{{/if}}> {{str de
f.text this.module}}
</label>
{{else}}
<input type="checkbox" class="checkbox"{{#if value}} checked{{/if}}>
{{/if}}
Helpers
Helpers
str
Description
Handlebars helper to render the label string.
The detail.hbs file defines the display of the control when the detail view is used. This layout is for viewing purposes
only so the control is disabled by default.
./clients/base/fields/bool/detail.hbs
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/00_Introduction/
The list.hbs file defines the display of the control when the list view is used. This view is also for viewing purposes
only so the control is disabled by default.
./clients/base/fields/bool/list.hbs
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Examples
Field examples.
Field Examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/90_Examples/
Powered by TCPDF (www.tcpdf.org)
Controller
The first thing we will need to do is create our controller file. Since we are attempting to mimic the stock base field,
we can duplicate ./clients/base/fields/base/base.js to ./custom/clients/base/fields/my-field/my-field.js. This file will
contain the JavaScript needed to render the field and format the values.
./custom/clients/base/fields/my-field/my-field.js
({
_render: function() {
var action = "view";
if (this.def.link && this.def.route) {
action = this.def.route.action;
}
if (!app.acl.hasAccessToModel(action, this.model)) {
this.def.link = false;
}
if (this.def.link) {
this.href = this.buildHref();
}
app.view.Field.prototype._render.call(this);
},
/**
* Takes care of building href for when there's a def.link and also if is
* bwc enabled.
*
* Deprecated functionality:
* If `this.def.bwcLink` is set to `true` on metadata, we force the href
* to be in BWC.
*/
buildHref: function() {
var defRoute = this.def.route ? this.def.route : {},
module = this.model.module || this.context.get('module');
return '#' + app.router.buildRoute(module, this.model.id, defRoute.action, th
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/90_Examples/Creating_Custom_Fields/
Handlebar Templates
Next we will need to define our handlebar templates. The templates will match those found in
./clients/base/fields/base/ with the minor difference of adding and additional style of "background:blue; color:white"
to the detail and list views.
./custom/clients/base/fields/my-field/detail.hbs
{{#if value}}
<div class="ellipsis_inline" dataplacement="bottom" style="background:blue; color:white">
{{value}}
</div>
{{/if}}
The list view will also have the style applied as shown below:
./custom/clients/base/fields/my-field/list.hbs
The edit view will remain the same as the stock base fields edit view:
./custom/clients/base/fields/my-field/edit.hbs
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/90_Examples/Creating_Custom_Fields/
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/40_Fields/90_Examples/Creating_Custom_Fields/
Powered by TCPDF (www.tcpdf.org)
Dashlets
Dashlets are special view component plugins that render data from a context and make use of the Dashlet
plugin.
Dashlets Overview.
Introduction
An overview of how dashlet view components work.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
An overview of how dashlet view components work.
Dashlets
Dashlets are special view component plugins that render data from a context and make use of the Dashlet
plugin. They are typically made up of a controller JavaScript file (.js) and at least one Handlebars template (.hbt).
Hierarchy Diagram
The dashlet view components are loaded in the following manner:
Note: The Sugar application client type is "base". More information on the various client types can be found in the
Clients section.
Dashlet Views
The are 3 views when working with dashlets: Preview, Dashlet View, and Configuration View. More information on
these views is outlined in the following sections.
Preview
The preview view is used when selecting dashlets to add to your homepage. Preview variables in the metadata will
be assigned to the custom model variables.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
this.model.get("key1");
Dashlet View
The dashlet view will render the content for the dashlet. It will also contain the settings for editing, removing, and
refreshing the dashlet.
Configuration View
The configuration view is displayed when a user clicks the edit option on the dashlet frames
dropdown menu. Config variables in the metadata will be assigned to the custom model variables
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
this.model.get("key1");
Dashlet Example
The news view, located in ./clients/base/views/news/, is what handles the display for the news dashlet. The
sections below will outline the various files that render this dashlet.
Metadata
The Dashlet view will contain the dashlets metadata:
Parameters
Type
Description
name
String
description
String
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
Object
preview
Object
filter
Object
<?php
$viewdefs['base']['view']['news'] = array(
'dashlets' => array(
array(
'name' => 'LBL_DASHLET_NEWS_NAME',
'description' => 'LBL_DASHLET_NEWS_DESCRIPTION',
'config' => array(
'limit' => '3',
),
'preview' => array(
'limit' => '3',
),
'filter' => array(
'module' => array(
'Accounts',
),
'view' => 'record'
),
),
),
'config' => array(
'fields' => array(
array(
'name' => 'limit',
'label' => 'LBL_DASHLET_CONFIGURE_DISPLAY_ROWS',
'type' => 'enum',
'searchBarThreshold' => -1,
'options' => array(
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
),
),
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
Controller
The news.js controller file, shown below, contains the JavaScript to render the news articles on the dashlet. The
Dashlet view must include Dashlet plugin and can override initDashlet to add additional custom process
while it is initializing.
./clients/base/views/news/news.js
({
plugins: ['Dashlet'],
initDashlet: function() {
if(this.meta.config) {
var limit = this.settings.get("limit") || "5";
this.settings.set("limit", limit);
}
},
loadData: function (options) {
var name, limit;
if(_.isUndefined(this.model)){
return;
}
var name = this.model.get("account_name") || this.model.get('name') || this.m
odel.get('full_name'),
limit = parseInt(this.settings.get('limit') || 5, 10);
if (_.isEmpty(name)) {
return;
}
$.ajax({
url: 'https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=' + n
ame.toLowerCase() + '&rsz=' + limit,
dataType: 'jsonp',
success: function (data) {
if (this.disposed) {
return;
}
_.extend(this, data);
this.render();
},
context: this,
complete: options ? options.complete : null
});
}
})
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
Workflow
Retrieving Data
this.model - RecordView
this.context.parent.get(model) - RecordView
this.context.parent.get(collection) - ListView
this.settings.get(custom_key)
this.dashletConfig[metadata_key]
app.metadata.getModule(ModuleName)
Bean
new app.data.createBean(Module)
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
new app.data.createBeanCollection(Module)
RestAPI
Ajax Call
$.ajax()
Handlebar Template
The news.hbs template file defines the views content. This view is used for rendering the markup rendering in the
dashlet content.
./clients/base/views/news/news.hbs
{{#if responseData.results}}
{{#each responseData.results}}
<div class="news-article">
<h5><a href="{{this.unescapedUrl}}">{{{this.titleNoFormatting}}}</a>
</h5> ({{{this.publisher}}})
<p>{{{this.content}}}</p>
</div>
{{/each}}
{{else}}
<div class="block-footer">{{str "LBL_NO_DATA_AVAILABLE"}}</div>
{{/if}}
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/50_Dashlets/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Handlebars
Handlebars is a JavaScript library that allows for Sugar to create semantic templates.
Handlebars Overview.
Introduction
An overview of how Handlebars is used within Sugar.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/55_Handlebars/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
An overview of how Handlebars is used within Sugar.
Handlebars
The Handlebars library, located in ./sidecar/lib/handlebars/, is a JavaScript library that allows for Sugar to create
semantic templates. It is used to help render content for layouts, views, and fields for Sidecar. Using Handlebars,
you can make modifications to display of content such as adding HTML or CSS to your content. More information
on the Handlebars library can be found at http://handlebarsjs.com.
Templates
The Handlebars templates are stored in the filesystem as .hbs files. These files are stored along with the view,
layout, and field metadata and are loaded according to the inheritance you have selected in your controller. To view
the list of available templates, or to see if a custom created template is available, you can open up your browsers
console window and inspect the Handlebars.templates namespace.
Debugging Templates
When working with Handlebar templates, its sometimes difficult to identify where an issue is occurring or what a
variable contains. To assist with troubleshooting this, you can use the log helper. The log helper will output the
contents of this and the variable passed to it in your browsers console.
An example of using log in an hbs template is shown below:
{{log this}}
Helpers
Handlebar helpers are a way of adding custom functionality to the templates. By default, Sidecar uses the helpers
found in ./sidecar/src/view/hbs-helpers.js. Additional helpers used by the base client are found in
./include/javascript/sugar7/hbs-helpers.js. The unminified version of the base client helpers can be found in
./jssource/src_files/include/javascript/sugar7/hbs-helpers.js.
Creating Helpers
When working with Handlebar templates, you may find a need to create your own helper. To do this, you will need
to do the following:
Create your Handlebars helper file. This file should be located within your ./custom/ directory. For our purposes, we
will create two functions to convert a string to upper case or lower case:
./custom/JavaScript/my-handlebar-helpers.js
/**
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/55_Handlebars/00_Introduction/
<?php
//Loop through the groupings to find include/javascript/sugar_grp7.min.js
foreach ($js_groupings as $key => $groupings)
{
foreach ($groupings as $file => $target)
{
if ($target == 'include/javascript/sugar_grp7.min.js')
{
//append the custom helper file
$js_groupings[$key]['custom/JavaScript/my-handlebarhelpers.js'] = 'include/javascript/sugar_grp7.min.js';
}
break;
}
}
Once the files are in place, you will need to navigate to Admin > Repair > Quick Repair and Rebuild and then to
Admin > Repair > Rebuild JS Groupings. This will include your changes and you will be able to call your custom
helpers in the hbs files by doing:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/55_Handlebars/00_Introduction/
{{customUpperCase "MyString"}}
{{customLowerCase "MyString"}}
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/55_Handlebars/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Subpanels
Overview of the subpanel framework.
Subpanel Overview.
Introduction
How the new subpanel framework works.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
How the new subpanel framework works.
Hierarchy Diagram
When loading the Sidecar subpanel layouts, the system processes the layout in the following manner:
Note: The Sugar application client type is "base". More information on the various client types can be found in the
Clients section.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
<?php
$viewdefs['Bugs']['base']['layout']['subpanels'] = array (
'components' => array (
array (
'layout' => 'subpanel',
'label' => 'LBL_DOCUMENTS_SUBPANEL_TITLE',
'context' => array (
'link' => 'documents',
),
),
array (
'layout' => 'subpanel',
'label' => 'LBL_CONTACTS_SUBPANEL_TITLE',
'context' => array (
'link' => 'contacts',
),
),
array (
'layout' => 'subpanel',
'label' => 'LBL_ACCOUNTS_SUBPANEL_TITLE',
'context' => array (
'link' => 'accounts',
),
),
array (
'layout' => 'subpanel',
'label' => 'LBL_CASES_SUBPANEL_TITLE',
'context' => array (
'link' => 'cases',
),
),
),
'type' => 'subpanels',
'span' => 12,
);
You can see that the layout incorporates the use of the subpanel layout for each module. As most of the subpanel
data is similar, this approach allows us to use less duplicate code. The subpanel layout, shown below, shows the 3
views that make up the subpanel widgets users see.
./clients/base/layouts/subpanel/subpanel.php
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
<?php
$viewdefs['base']['layout']['subpanel']
'components' => array (
array (
'view' => 'panel-top',
)
array (
'view' => 'subpanel-list',
),
array (
'view' => 'list-bottom',
),
),
'span' => 12,
'last_state' => array(
'id' => 'subpanel'
),
);
= array (
Sidecar Layouts
Custom Sidecar layouts, located in ./custom/Extension/modules/<module>/Ext/clients/<client>/layouts/subpanels/,
are compiled into ./custom/modules/<module>/Ext/clients/<client>/layouts/subpanels/subpanels.ext.php using the
extension framework. When a relationship is saved, layout files are created for both the "base" and "mobile" client
types.
An example of this is when deploying a 1-M relationship from Bugs to Leads, the following Sidecar files are
generated:
./custom/Extension/modules/Bugs/Ext/clients/base/layouts/subpanels/bugs_leads_1_Bugs.php
<?php
$viewdefs['Bugs']['base']['layout']['subpanels']['components'][] = array (
'layout' => 'subpanel',
'label' => 'LBL_BUGS_LEADS_1_FROM_LEADS_TITLE',
'context' =>
array (
'link' => 'bugs_leads_1',
),
);
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
<?php
$viewdefs['Bugs']['mobile']['layout']['subpanels']['components'][] = array (
'layout' => 'subpanel',
'label' => 'LBL_BUGS_LEADS_1_FROM_LEADS_TITLE',
'context' =>
array (
'link' => 'bugs_leads_1',
),
);
Note: The additional legacy MVC layouts generated by a relationships deployment are described below.
<?php
$layout_defs["Bugs"]["subpanel_setup"]['bugs_leads_1'] = array (
'order' => 100,
'module' => 'Leads',
'subpanel_name' => 'default',
'sort_order' => 'asc',
'sort_by' => 'id',
'title_key' => 'LBL_BUGS_LEADS_1_FROM_LEADS_TITLE',
'get_subpanel_data' => 'bugs_leads_1',
'top_buttons' =>
array (
0 =>
array (
'widget_class' => 'SubPanelTopButtonQuickCreate',
),
1 =>
array (
'widget_class' => 'SubPanelTopSelectButton',
'mode' => 'MultiSelect',
),
),
);
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
<?php
$layout_defs["Bugs"]["subpanel_setup"]['bugs_leads_1'] = array (
'order' => 100,
'module' => 'Leads',
'subpanel_name' => 'default',
'title_key' => 'LBL_BUGS_LEADS_1_FROM_LEADS_TITLE',
'get_subpanel_data' => 'bugs_leads_1',
);
Fields Metadata
Sidecars subpanel field layouts are initially defined by the subpanel-list view metadata.
Hierarchy Diagram
The subpanel list metadata is loaded in the following manner:
Note: The Sugar application client type is "base". More information on the various client types can be found in the
Clients section.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
<?php
$subpanel_layout['list_fields'] = array (
'full_name' =>
array (
'type' => 'fullname',
'link' => true,
'studio' =>
array (
'listview' => false,
),
'vname' => 'LBL_NAME',
'width' => '10%%',
'default' => true,
),
'date_entered' =>
array (
'type' => 'datetime',
'studio' =>
array (
'portaleditview' => false,
),
'readonly' => true,
'vname' => 'LBL_DATE_ENTERED',
'width' => '10%%',
'default' => true,
),
'refered_by' =>
array (
'vname' => 'LBL_LIST_REFERED_BY',
'width' => '10%%',
'default' => true,
),
'lead_source' =>
array (
'vname' => 'LBL_LIST_LEAD_SOURCE',
'width' => '10%%',
'default' => true,
),
'phone_work' =>
array (
'vname' => 'LBL_LIST_PHONE',
'width' => '10%%',
'default' => true,
),
'lead_source_description' =>
array (
'name' => 'lead_source_description',
'vname' => 'LBL_LIST_LEAD_SOURCE_DESCRIPTION',
'width' => '10%%',
'sortable' => false,
'default' => true,
),
'assigned_user_name' =>
array (
'name' => 'assigned_user_name',
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
To modify this layout, you can navigate to Admin > Studio > {Parent Module} > Subpanels > Bugs and make your
changes. Once saved, Sugar will generate ./custom/modules/Bugs/clients/<client>/views/subpanelfor-<link>/subpanel-for-<link>.php which will be used for rendering the fields you selected.
You should note that just as Sugar mimics the Sidecar layouts in the legacy MVC framework for modules in
backward compatibility, it also mimics the field list in ./modules/<module>/metadata/subpanels/default.php and
./custom/modules/<module>/metadata/subpanels/default.php. This is done to ensure that any related modules,
whether in Sidecar or Backward Compatibility mode, display the same field list as expected.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/60_Subpanels/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Metadata
Overview of the metadata framework.
Metadata is defined as information about data. In SugarCRM, metadata refers to the framework of using files to
abstract the presentation and business logic found in the system. The metadata framework is described in
definition files that are processed using PHP.
Application Metadata
An overview of the application metadata framework.
Module Metadata
An overview of the Sidecar module metadata framework.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/
Powered by TCPDF (www.tcpdf.org)
Application Metadata
Overview
An overview of the application metadata framework.
Hierarchy Diagram
The modules metadata are loaded in the following manner:
$moduleList
The $moduleList is an array containing a list of modules in the system. The format of the array is to have a numeric
index and a value of the modules unique key.
$moduleList[] = 'Accounts';
$beanList
The $beanList variable is an array that stores a list of all active beans (modules) in the application. The format of
the array is array('<bean plural name>' => '<bean singular name>');. The $beanList key is used to lookup values in
the $beanFiles variable.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/00_Application_Metadata/
$beanFiles
The $beanFiles variable is an array used to reference the class files for a bean. The format of the array is
array('<bean singular name>' => '<relative class file>');. The bean name, stored in singular form, is a reference to
the class name of the object, which is looked up from the $beanList key.
$beanFiles['Account'] = 'modules/Accounts/Account.php';
$modInvisList
The $modInvisList variable makes modules invisible in the regular user interface (i.e., no tab appears for these
modules).
$modInvisList = array(
'Administration',
'Currencies',
'CustomFields',
'Connectors',
'Dropdown',
'Dynamic',
'DynamicFields',
'DynamicLayout',
'EditCustomFields',
'Help',
'Import',
'MySettings',
'EditCustomFields',
'FieldsMetaData',
'UpgradeWizard',
'Trackers',
'Connectors',
'Employees',
'Calendar',
'Manufacturers',
'ProductBundles',
'ProductBundleNotes',
'ProductCategories',
'ProductTemplates',
'ProductTypes',
'Shippers',
'TaxRates',
'TeamNotices',
'Teams',
'TimePeriods',
'ForecastOpportunities',
'Quotas',
'KBDocumentRevisions',
'KBDocumentKBTags',
'KBTags',
'KBContents',
'ContractTypes',
'ForecastSchedule',
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/00_Application_Metadata/
$adminOnlyList
The $adminOnlyList variable is an extra level of security for modules that are can be accessed only by
administrators through the Admin page.
$adminOnlyList = array(
// module => list of actions (all says all actions are admin only)
// 'Administration'=>array('all'=>1, 'SupportPortal'=>'allow'),
'Dropdown' => array(
'all' => 1
),
'Dynamic' => array(
'all' => 1
),
'DynamicFields' => array(
'all' => 1
),
'Currencies' => array(
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/00_Application_Metadata/
$bwcModules
The $bwcModules variable determines which modules are in backward compatibility mode. More information on
backward compatibility can be found in the Backward Compatibility section.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/00_Application_Metadata/
Powered by TCPDF (www.tcpdf.org)
Module Metadata
Overview
An overview of the Sidecar module metadata framework.
./modules/<module>/clients/<client>/views/<view>/<view>.php
Any edits made in Admin > Studio will be reflected in the file:
./custom/modules/<module>/clients/<client>/views/<view>/<view>.php
Note: The Sugar application client type is base. More information on the various client types can be found
in the Clients section.
Note: In the case of metadata, custom view metadata files are respected over the stock view metadata files.
View Metadata
The Sidecar views metadata is very similar to that of the MVC metadata, however, there are some basic
differences. All metadata for Sidecar follows the format:
$viewdefs['<module>']['base']['view']['<view>'] = array();
<?php
$viewdefs['Accounts']['base']['view']['record'] = array(
'panels' => array(
array(
'name' => 'panel_header',
'header' => true,
'fields' => array(
array(
'name'
=> 'picture',
'type'
=> 'avatar',
'width'
=> 42,
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/10_Module_Metadata/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/10_Module_Metadata/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/10_Module_Metadata/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/10_Module_Metadata/
You should note that this can also be accessed in your browsers console window by using the global App Identifier:
App.metadata.getView('Accounts', 'record');
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/70_Metadata/10_Module_Metadata/
Powered by TCPDF (www.tcpdf.org)
Routes
Overview
How routes are defined and used within the system.
Platform Routes
Routes are used for interpreting patterns in a URL to direct a user to a specific page. The hashtag ("#") in the URL
is what signifies the start of a pattern. An example URL for the sugar application is shown below:
http://{site url}/#<action>/
The current routes are defined in ./include/javascript/sugar7.js. At this time, you cannot add custom routes to the
sugar application in an upgrade safe way.
Route Definitions
The router accepts route definitions in the following format:
routes = [
{
name: "My First Route",
route: "pattern/to/match",
callback: function()
{
//handling logic here.
}
},
{
name: "My Second Route",
route: "pattern/:variable",
callback: "<callback name>"
}
]
A route takes in three properties: the name of the route, the route pattern to match, and the callback to be called
when the route is matched. If a default callback is desired, you can specify the callback name as a string.
Route Patterns
Route patterns determine where to direct the user. An example of routing is done when navigating to an account
record. When doing this you may notice that your URL is:
http://{site url}/#Accounts/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/80_Routes/
{
name: "record",
route: ":module/:id"
},
Variables in the route pattern will be prefixed with a colon (":variable"). The route pattern above contains two
variables:
module
id
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/80_Routes/
Powered by TCPDF (www.tcpdf.org)
Legacy MVC
Legacy MVC Overview.
Introduction
Introduction to the legacy MVC Architecture.
Model
An overview of the SugarBean model.
View
Displaying information to the browser.
Controller
The basic actions of a module.
Metadata
Legacy MVC Metadata Overview.
Examples
Provides an overview of example MVC customizations
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
Introduction to the legacy MVC Architecture.
You should note that the MVC architecture is being deprecated and is being replaced with sidecar. Until the
framework is fully deprecated, modules set in backward compatibility mode will still use the legacy MVC framework.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/00_Introduction/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Model
An overview of the SugarBean model.
Overview
The Sugar Model is represented by the SugarBean, and any subclass of the SugarBean. Many of the common
Sugar modules also use the SugarObjects class.
File Structure
./include/SugarObjects/interfaces
./include/SugarObjects/templates
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/10_Model/
Implementation
There are two things you need to do to take advantage of SugarObjects:
1) Your class needs to subclass the SugarObject class you wish to extend.
This tells the VardefManager to create a cache of the Contacts vardefs with the addition of all the default fields,
assignable fields, team security fields (Sugar Professional and Enterprise only), and all fields from the person class.
Performance Considerations
VardefManager caches the generated vardefs into a single file that will be loaded at run time. If that file is not
found, Sugar will load the vardefs.php file, located in your modules directory. The same is true for language files.
This caching also includes data for custom fields, and any vardef or language extensions that are dropped into the
extension framework.
Cache Files
./cache/modules/<module>/<object_name>vardefs.php
./cache/modules/<module>/languages/en_us.lang.php
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/10_Model/
Powered by TCPDF (www.tcpdf.org)
View
Overview
Displaying information to the browser.
Implementation
Class File Structure
./include/MVC/Views/SugarView.php
./include/MVC/Views/view.<view>.php
./custom/include/MVC/Views/view.<view>.php
./modules/<module>/views/view.<view>.php
./custom/modules/<module>/views/view.<view>.php
Class Loading
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/20_View/
Methods
There are two main methods to override within a view:
preDisplay(): This performs pre-processing within a view. This method is relevant only for extending
existing views. For example, the include/MVC/View/views/view.edit.php file uses it, and enables developers
who wishes to extend this view to leverage all of the logic done in preDisplay() and either override the
display() method completely or within your own display() method call parent::display().
display(): This method displays the data to the screen. Place the logic to display output to the screen here.
Creating Views
Creating a new/view action consists of a controller action and a view file. The first step is to define your controller
action. If the module does not contain a controller.php file in ./modules/<module>/ you will create the following file:
./custom/modules/<module>/controller.php
<?php
The next step is to define your view file. This example extends the ViewDetail class but you can extend any of the
classes you choose in ./include/MVC/View/views/.
./custom/modules/<module>/views/view.newview.php
<?php
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/20_View/
require_once('include/MVC/View/views/view.detail.php');
Overriding Views
The following section will demonstrate how to extend and override a view. When overriding existing actions and
views, you wont need to make any changes to the controller. This approach will be very similar for any view
you may choose to modify. If the module you are extending the view for does not contain an existing view in its
modules views directory ( ./modules/<module>/views/ ), you will need to extend the views base class. Otherwise,
you will extend the view class found within the file.
In the case of a detail view, you would check for the file ./modules/<module>/views/view.detail.php. If this file does
not exist, you will create ./custom/modules/<module>/views/view.detail.php and extend the base ViewDetail class
with the name <module>ViewDetail.
./custom/modules/<module>/views/view.detail.php
<?php
require_once('include/MVC/View/views/view.detail.php');
class <module>ViewDetail extends ViewDetail
{
function display()
{
echo 'This is my addition to the DetailView<br>';
//call parent display method
parent::display();
}
}
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/20_View/
<?php
require_once('modules/<module>/views/view.detail.php');
class Custom<module>ViewDetail extends <module>ViewDetail
{
function display()
{
echo 'This is my addition to the DetailView<br>';
//call parent display method
parent::display();
}
}
Implementation
The format of these files is as follows:
$view_config = array(
'actions' =>
array(
'popup' => array(
'show_header' => false,
'show_subpanels' => false,
'show_search' => false,
'show_footer' => false,
'show_JavaScript' => true,
),
),
'req_params' => array(
'to_pdf' => array(
'param_value' => true,
'config' => array(
'show_all' => false
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/20_View/
To illustrate this process, let us take a look at how the popup action is processed. In this case, the system
will go to the actions entry within the view_config and determine the proper configuration. If the request contains
the parameter to_pdf, and is set to be true, then it will automatically cause the show_all configuration parameter to
be set false, which means none of the options will be displayed.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/20_View/
Powered by TCPDF (www.tcpdf.org)
Controller
Overview
The basic actions of a module.
Controllers
The main controller, named SugarController, addresses the basic actions of a module from EditView and
DetailView to saving a record. Each module can override this SugarController by adding a controller.php file into its
directory. This file extends the SugarController, and the naming convention for the class is: <module>Controller
Inside the controller you define an action method. The naming convention for the method is: action_<action name>
There are more fine grained control mechanisms that a developer can use to override the controller processing. For
example if a developer wanted to create a new save action, there are three places where they could possibly
override.
action_save: This is the broadest specification and gives the user full control over the save process.
pre_save: A user could override the population of parameters from the form.
post_save: This is where the view is being setup. At this point the developer could set a redirect url, do
some post save processing, or set a different view.
Upgrade-Safe Implementation
You can also add a custom Controller that extends the modules Controller if such a Controller already exists.
For example, if you want to extend the Controller for a module, you should check if that module already has a
module-specific controller. If so, you extend from that controller class. Otherwise, you extend from SugarController
class. In both cases, you should place the custom controller class file in ./custom/modules/<module>/Controller.php
instead of the module directory. Doing so makes your customization upgrade-safe.
File Structure
./include/MVC/Controller/SugarController.php
./include/MVC/Controller/ControllerFactory.php
./modules/<module>/Controller.php
./custom/modules/<module>/controller.php
Implementation
If the module does not contain a controller.php file in ./modules/<module>/, you will create the following file:
./custom/modules/<module>/controller.php
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/30_Controller/
If the module does contain a controller.php file, you will need to extend it by doing the following:
./custom/modules/<module>/controller.php
require_once('modules/<module>/controller.php');
class Custom<module>Controller extends <module>Controller
{
function action_<action>()
{
$this->view = '<action lowercase>';
}
}
Note: When creating or moving files you will need to rebuild the file map.
More information on rebulding the file map can be found in the SugarAutoLoader .
$action_file_map['subpanelviewer'] = 'include/SubPanel/SubPanelViewer.php';
$action_file_map['save2'] = 'include/generic/Save2.php';
$action_file_map['deleterelationship'] = 'include/generic/DeleteRelationship.php';
$action_file_map['import'] = 'modules/Import/index.php';
Here the developer has the opportunity to map an action to a file. For example, Sugar uses a generic sub-panel file
for handling subpanel actions. You can see above that there is an entry mapping the action
subpanelviewer to ./include/SubPanel/SubPanelViewer.php.
The base SugarController class loads the action mappings in the following path sequence:
./include/MVC/Controller
./modules/<module>
./custom/modules/<module>
./custom/include/MVC/Controller
Each one loads and overrides the previous definition if in conflict. You can drop a new action_file_map in the later
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/30_Controller/
Upgrade-Safe Implementation
If you want to add custom action_file_map.php to an existing module that came with the SugarCRM release, you
should place the file at ./custom/modules/<module>/action_file_map.php
File Structure
./include/MVC/Controller/action_file_map.php
./modules/<module>/action_file_map.php
./custom/modules/<module>/action_file_map.php
Implementation
$action_file_map['soapRetrieve'] = 'custom/SoapRetrieve/soap.php';
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/30_Controller/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/30_Controller/
Powered by TCPDF (www.tcpdf.org)
Metadata
Legacy MVC Metadata Overview.
Introduction
An overview of the legacy MVC metadata framework.
SugarFields
Overview of the various SugarField Widgets.
Examples
Legacy MVC metadata examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
An overview of the legacy MVC metadata framework.
You should note that the MVC architecture is being deprecated and is being replaced with sidecar. Until the
framework is fully deprecated, modules set in backward compatibility mode will still use the legacy MVC
framework.
Metadata Framework
Background
Metadata is defined as information about data. In Sugar, metadata refers to the framework of using files to abstract
the presentation and business logic found in the system. The metadata framework is described in definition files
that are processed using PHP. The processing usually includes the use of Smarty templates for rendering the
presentation and JavaScript libraries to handle some business logic that affects conditional displays, input
validation, and so on.
Application Metadata
All application modules are defined in the modules.php file. It contains several variables that define which modules
are active and usable in the application.
The file is located under the <sugar root>/include folder. It contains the $moduleList() array variable which
contains the reference to the array key to look up the string to be used to display the module in the tabs at the top
of the application. The coding standard is for the value to be in the plural of the module name; for example,
Contacts, Accounts, Widgets, and so on.
The $beanList() array stores a list of all active beans (modules) in the application. The $beanList entries are stored
in a name => value fashion with the name value being in the plural and the value
being in the singular of the module name. The value of a $beanList() entry is used to lookup values in our
next modules.php variable, the $beanFiles() array.
The $beanFiles variable is also stored in a name => value fashion. The name, typically in
singular, is a reference to the class name of the object, which is looked up from the $beanList value, and
the value is a reference to the class file.
The remaining relevant variables in the modules.php file are the $modInvisList variable which makes modules
invisible in the regular user interface (i.e., no tab appears for these modules), and the $adminOnlyList which is an
extra level of security for modules that are accessible only by administrators through the Admin page.
Module Metadata
The following table lists the metadata definition files found in the modules/[module]/metadata directory, and a brief
description of their purpose within the system.
File
additionalDetails.php
Description
Used to render the popup information displayed when a user hovers
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
SearchForm Metadata
The search form layout for each module is defined in the modules metadata file searchdefs.php. A sample of
the Accounts searchdefs.php appears as:
<?php
$searchdefs['Accounts'] = array(
'templateMeta' => array(
'maxColumns' => '3',
'widths' => array(
'label' => '10',
'field' => '30'
)
),
'layout' => array(
'basic_search' => array(
'name',
'billing_address_city',
'phone_office',
array(
'name' => 'address_street',
'label' => 'LBL_BILLING_ADDRESS',
'type' => 'name',
'group' => 'billing_address_street'
),
array(
'name' => 'current_user_only',
'label' => 'LBL_CURRENT_USER_FILTER',
'type'=>'bool'
),
),
'advanced_search' => array(
'name',
array(
'name' => 'address_street',
'label' => 'LBL_ANY_ADDRESS',
'type' => 'name'
),
array(
'name' => 'phone',
'label' => 'LBL_ANY_PHONE',
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
The searchdefs.php file contains the Array variable $searchDefs with one entry. The key is the name of the module
as defined in $moduleList array defined in include/modules.php. The $searchDefsarray is another array that
describes the search form layout and fields.
The templateMeta key points to another array that controls the maximum number of columns in each row
of the search form (maxColumns), as well as layout spacing attributes as defined by widths. In
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
The following diagram highlights the process of how the application determines which Metadata file is to be used
when rendering a request for a view:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
The Classic Mode on the right hand side of the diagram represents the SugarCRM pre-5.x rendering of a
Detail/Editview. This section will focus on the MVC/Metadata mode.
When the view is first requested, the preDisplay method will attempt to find the correct Metadata file to use.
Typically, the Metadata file will exist in the [root level]/modules/[module]/metadata directory, but in the event of
edits to a layout through the Studio interface, a new Metadata file will be created and placed in the [root
level]/custom/modules/[module]/metadata directory. This is done so that changes to layouts may be restored to
their original state through Studio, and also to allow changes made to layouts to be upgrade-safe when new
patches and upgrades are applied to the application. The metafiles.php file that may be loaded allows for the
loading of Metadata files with alternate naming conventions or locations. An example of the metafiles.php contents
can be found for the Accounts module (though it is not used by default in the application).
$metafiles['Accounts'] = array(
'detailviewdefs' => 'modules/Accounts/metadata/detailviewdefs.php',
'editviewdefs' => 'modules/Accounts/metadata/editviewdefs.php',
'ListViewdefs' => 'modules/Accounts/metadata/ListViewdefs.php',
'searchdefs' => 'modules/Accounts/metadata/searchdefs.php',
'popupdefs' => 'modules/Accounts/metadata/popupdefs.php',
'searchfields' => 'modules/Accounts/metadata/SearchFields.php',
);
After the Metadata file is loaded, the preDisplay method also creates an EditView object and checks if a Smarty
template file needs to be built for the given Metadata file. The EditView object does the bulk of the processing for a
given Metadata file (creating the template, setting values, setting field level ACL controls if applicable, etc.). Please
see the EditView process diagram for more detailed information about these steps.
After the preDisplay method is called in the view code, the display method is called, resulting in a call to the
EditView objects process method, as well as the EditView objects display method.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
The following diagram highlights the EditView classs main responsibilities and their relationships with other
classes in the system. We will use the example of a DetailView request although the sequence will be similar for
other views that use the EditView class.
One thing to note is the EditView classs interaction with the TemplateHandler class. The TemplateHandler
class is responsible for generating a Smarty template in the cache/modules/<module> directory. For example, for
the Accounts module, the TemplateHandler will create the Smarty file, cache/modules/Accounts/DetailView.tpl,
based on the Metadata file definition and other supplementary information from the EditView class. The
TemplateHandler class actually uses Smarty itself to generate the resulting template that is placed in the
aforementioned cache directory.
Some of the modules that are available in the SugarCRM application also extend the ViewDetail class. One
example of this is the DetailView for the Projects module. As mentioned in the MVC section, it is possible to extend
the view classes by placing a file in the modules/<module>/views directory. In this case, a view.detail.php file exists
in the modules/Projects/views folder. This may serve as a useful example in studying how to extend a view and
apply additional field/layout settings not provided by the EditView class.
The following diagram shows the files involved with the DetailView example in more detail:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
When the setup method is invoked, a TemplateHandler instance (D) is created. A check is performed to determine
which detailviewdefs.php metadata file to used in creating the resulting DetailView. The first check is performed to
see if a metadata file was passed in as a parameter. The second check is performed against the
custom/studio/modules/[Module] directory to see if a metadata file exists. For the final option, the DetailView
constructor will use the modules default detailviewdefs.php metadata file located under the
modules/[Module]/metadata directory. If there is no detailviewdefs.php file in the modules/[Module]/metadata
directory, but a DetailView.html exists, then a "best guess" version is created using the metadata parser file in
include/SugarFields/Parsers/DetailViewMetaParser.php (not shown in diagram).
The TemplateHandler also handles creating the quick search (Ajax code to do look ahead typing) as well as
generating the JavaScript validation rules for the module. Both the quick search and JavaScript code should
remain static based on the definitions of the current definition of the metadata file. When fields are added or
removed from the file through Studio, this template and the resulting updated quick search and JavaScript code will
be rebuilt.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
function process()
{
//Format fields first
if($this->formatFields)
{
$this->focus->format_all_fields();
}
parent::process();
}
This, in turn, calls the EditView->process() method since DetailView extends from EditView. The
EditView->process() method will eventually call the EditView->render() method to calculate the width spacing for
the DetailView labels and values. The number of columns and the percentage of width to allocate to each column
may be defined in the metadata file. The actual values are rounded as a total percentage of 100%%. For example,
given the templateMeta sections maxColumns and widths values:
We can see that the labels and fields are mapped as a 1-to-3 ratio. The sum of the widths only equals a total of 80
(10 + 30 x 2) so the actual resulting values written to the Smarty template will be at a percentage ratio of
12.5-to-37.5. The resulting fields defined in the metadata file will be rendered as a table with the column widths as
defined:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
The actual metadata layout will allow for variable column lengths throughout the displayed table. For example, the
metadata portion defined as:
This specifies a default panel under the panels section with three rows. The first row has two fields (name and
amount). The amount field has some special formatting using the label override option. The second row contains
the account_name field and the third row contains the opportunity_type column.
Next, the process() method populates the $fieldDefs array variable with the vardefs.php file (G) definition and the $focus beans value. This
is done by calling the toArray () method on the $focus bean instance and combining these values with the field definition specified in the
vardefs.php file (G).
The display() method is then invoked on the generic DetailView instance for the final step.
When the display() method is invoked, variables to the DetailView.tpl Smarty template are assigned and the
modules HTML code is sent to the output buffer.
Before HTML code is sent back, the TemplateHandler (D) first performs a check to see if an existing DetailView
template already exists in the cache respository (H). In this case, it will look for file
cache/modules/Opportunity/DetailView.tpl. The operation of creating the Smarty template is expensive so this
operation ensures that the work will not have to be redone. As a side note, edits made to the DetailView or
EditView through the Studio application will clear the cache file and force the template to be rewritten so that the
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
SugarFields
Overview of the various SugarField Widgets.
SugarField Overview.
Introduction
Overview of the MVC SugarField widgets.
Widgets
The various SugarField widgets.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/
Powered by TCPDF (www.tcpdf.org)
Introduction
Overview
Overview of the MVC SugarField widgets.
You should note that the MVC architecture is being deprecated and is being replaced with sidecar. Until the
framework is fully deprecated, modules set in backward compatibility mode will still use the legacy MVC framework.
SugarField Widgets
SugarFields are the Objects that render the fields specified in the metadata (for example, your *viewdefs.php files).
They can be found in include/SugarFields/Fields. In the directory, include/SugarFields/Fields/Base, you will see the
files for the base templates for rendering a field for DetailView, EditView, ListView, and Search Forms, as well as
the base class called SugarFieldBase.
File Structure
./include/SugarFields/Fields/<fieldname>
./include/SugarFields/Fields/<fieldname>/DetailView.tpl
./modules/<module>/vardefs.php
./modules/<module>/metadata/<view>defs.php
Implementation
This section describes the SugarFields widgets that are found in the ./include/SugarFields/Fields directory.
Inside this folder you will find a set of directories that encapsulate the rendering of a field type (for example,
Boolean, Text, Enum, etc.). That is, there are user interface paradigms associated with a particular field type. For
example, a Boolean field type as defined in a modules vardef.php file can be displayed with a checkbox
indicating the boolean nature of the field value (on/off, yes/no, 0/1, etc.). Naturally there are some displays in which
the rendered user interface components are very specific to the modules logic. In this example, it is likely that
custom code was used in the metadata file definition. There are also SugarFields directories for grouped display
values (e.g. Address, Datetime, Parent, and Relate).
Any custom code called by the metadata will be passed as unformatted data for numeric entries, and that custom
code in the metadata will need individual handle formatting.
SugarFields widgets are rendered from the metadata framework whenever the MVC EditView, DetailView, or
ListView actions are invoked for a particular module. Each of the SugarFields will be discussed briefly.
Most SugarFields will contain a set of Smarty files for abstract rendering of the field contents and supporting HTML.
Some SugarFields will also contain a subclass of SugarFieldBase to override particular methods so as to control
additional processing and routing of the corresponding Smarty file to use. The subclass naming convention is
defined as SugarField[Sugar Field Type] where the first letter of the Sugar Field Type should be in uppercase. The
contents should also be placed in a corresponding .php file. For example, the contents of the enum type SugarField
(rendered as <select> in HTML) is defined in ./include/SugarFields/Fields/Enum/SugarFieldEnum.php. In that file,
you can see how the enum type will use one of six Smarty template files depending on the view (edit, detail or
search) and whether or not the enum vardef definition has a function attribute defined to invoke a PHP
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/00_Introduction/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/00_Introduction/
Powered by TCPDF (www.tcpdf.org)
Widgets
The various SugarField widgets.
Widget Overview.
Address
Renders various fields that together represent an address value.
Base
The default parent field.
Bool
Renders a checkbox to reflect the state of the value.
Currency
Renders a checkbox to reflect the state of the value.
Datetime
Renders an input text field along with an image to invoke the popup calendar picker.
Datetimecombo
Renders a Datetime field with additional support to render dropdown lists for the hours and minutes.
Download
Renders the ability for a user to download a file.
Enum
Renders an HTML select form element that allows for a single value to be chosen.
File
Renders a file upload field.
Float
Renders a field that is formatted as a floating point number.
Html
Renders read-only content.
Iframe
Renders an iFrame field.
Image
Renders an img tag where the src attribute points to the value of the field.
Int
Renders a field that is formatted as a whole number.
Link
Renders a hyperlink to a records detail view.
Multienum
Renders a bullet list of values for detail views.
Parent
Renders a dropdown for the parent module type.
Password
Renders an input text field for passwords.
Phone
Renders a call to trigger VOIP applications.
Radioenum
Renders a group of radio buttons.
Readonly
Directs edit view calls to use the SugarFields detail view display.
Relate
Combines a blend of a text field with code to allow quick search.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/
Powered by TCPDF (www.tcpdf.org)
Address
Overview
Renders various fields that together represent an address value.
Address
Use the section below to introduce the technology in relation to the product and describe its benefits.
By default SugarCRM renders address values in the United States format:
Street
City, State Zip
The Smarty template layout defined in DetailView.tpl reflects this. Should you wish to customize the layout,
depending on the $current_language global variable, you may need to add new files
[$current_language].DetailView.tpl or [$current_language].EditView.tpl to the Address directory that reflect the
language locales address formatting.
Within the metadata definition, the Address field can be rendered with the snippet:
array (
'name' => 'billing_address_street',
'hideLabel' => true,
'type' => 'address',
'displayParams' => array(
'key' => 'billing',
'rows' => 2,
'cols' => 30,
'maxlength' => 150
)
),
name
The vardefs.php entry to key field off of. Though not 100%% ideal, we use the
street value
hideLabel
type
displayParams key - This is the prefix for the address fields. The address field assumes there
are [key]_address_street, [key]_address_state, [key]_address_city,
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Address/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Address/
Powered by TCPDF (www.tcpdf.org)
Base
Overview
The default parent field.
Base
The Base field is the default parent field. It simply renders the value as is for detail views, and an HTML text field
<input type="text"> for edit views. All SugarFields that have a corresponding PHP file extend from
SugarFieldBase.php or from one of the other SugarFields.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Base/
Powered by TCPDF (www.tcpdf.org)
Bool
Overview
Renders a checkbox to reflect the state of the value.
Bool
The Bool field is responsible for rendering a checkbox to reflect the state of the value. All boolean fields are stored
as integer values. The Bool field will render a disabled checkbox for detail views. If the field value is "1" then the
checkbox field will be checked. There is no special parameter to pass into this field from the metadata definition. As
with any of the fields you have the option to override the label key string.
For example, in the metadata definition, the Boolean field do_not_call can be specified as:
'do_not_call'
or
array (
array(
'name' => 'do_not_call',
'label' => 'LBL_DO_NOT_CALL' // Overrides label as defined in vardefs.php
)
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Bool/
Powered by TCPDF (www.tcpdf.org)
Currency
Overview
Renders a checkbox to reflect the state of the value.
Currency
The Currency field is responsible for rendering a field that is formatted according to the users preferences for
currencies. This fields handles will format the field differently if the field name contains the text _usd,
this is used internally to map to the amount_usdollar fields which will always display the currency in the users
preferred currency (or the system currency if the user does not have one selected). If the field name does not
contain _usd, the formatting code will attempt to find a field in the same module called currency_id
and use that to figure out what currency symbol to display next to the formatted number. In order for this to work on
list views and sub-panels, you will need to add the currency_id column as a query_only field, for
further reference please see the Opportunities list view definitions.
Within the metadata definition, the Currency field can be rendered with the snippet:
or
array(
'name' => 'amount',
'displayParams' => array(
'required' => true
)
),
name
displayParams required (optional) - Marks the field as required and applies clients side
validation to ensure value is present when save operation is invoked from edit
view (Overrides the value set in vardefs.php).
showFormats (optional) - Displays the users date display preference as
retrieved from the global $timedate variables get_user_date_format()
method.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Currency/
Powered by TCPDF (www.tcpdf.org)
Datetime
Overview
Renders an input text field along with an image to invoke the popup calendar picker.
Datetime
The Datetime field is responsible for rendering an input text field along with an image to invoke the popup calendar
picker. This field differs from the Datetimecombo field in that there is no option to select the time values of a
datetime database field.
Within the metadata definition, the Datetime field can be rendered with the snippet:
or
array(
'name' => 'date_quote_expected_closed',
'displayParams' => array(
'required' => true,
'showFormats' => true
)
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Datetime/
Powered by TCPDF (www.tcpdf.org)
Datetimecombo
Overview
Renders a Datetime field with additional support to render dropdown lists for the hours and minutes.
Datetimecombo
The Datetimecombo field is similar to the Datetime field with additional support to render dropdown lists for the
hours and minutes values, as well as a checkbox to enable/disable the entire field. The date portion (e.g.
12/25/2007) and time portion (e.g. 23:45) of the database fields are consolidated. Hence, the developer must take
care to handle input from three HTML field values within the module class code. For example, in the vardefs.php
definition for the date_start field in the Calls module:
There is one database field, but when the Datetimecombo widget is rendered, it will produce three HTML fields for
display- a text box for the date portion, and two dropdown lists for the hours and minutes values. The
Datetimecombo widget will render the hours and menu dropdown portion in accordance to the users
$timedate preferences. An optional AM/PM meridiem drop down is also displayed should the user have selected a
12 hour base format (e.g. 11:00).
Within the metadata definition, the Datetimecombo field can be rendered with the snippet:
array(
'name' =>
'date_start',
'type' => 'datetimecombo',
'displayParams' => array(
'required' => true,
'updateCallback' => 'SugarWidgetScheduler.update_time();',
'showFormats' => true,
'showNoneCheckbox' => true
),
'label'=>'LBL_DATE_TIME'
),
name
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Datetimecombo/
displayParams
label (optional)
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Datetimecombo/
Powered by TCPDF (www.tcpdf.org)
Download
Overview
Renders the ability for a user to download a file.
Download
The File field renders a link that references the download.php file for the given displayParam[id] value
when in DetailView mode.
Within the metadata definition, the Download field can be rendered with the snippet:
array (
'name' => 'filename',
'displayParams' => array(
'link' => 'filename',
'id' => 'document_revision_id'
)
),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Download/
Powered by TCPDF (www.tcpdf.org)
Enum
Overview
Renders an HTML select form element that allows for a single value to be chosen.
Enum
The size attribute of the <select> element is not defined so the element will render as a dropdown field in the
EditView.
This field accepts the optional function override behavior that is defined at the vardefs.php file level. For example,
in the Bugs module we have for the found_in_release field:
The function override is not handled by the SugarFields library, but by the rendering code in
./include/EditView/EditView2.php.
Within the metadata definition, the Download field can be rendered with the snippet:
array (
'name' => 'my_enum_field',
'type' => 'enum',
'displayParams' => array(
'javascript' =>
'onchange="alert(\'hello world!\')";'
)
),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Enum/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Enum/
Powered by TCPDF (www.tcpdf.org)
File
Overview
Renders a file upload field.
File
The File field renders a file upload field in edit view, and a hyperlink to invoke download.php in detail view. Note
that you will need to override the HTML forms enctype attribute to be "multipart/form-data" when using this
field and handle the upload of the file contents in your code. This form enctype attribute should be set in the
editviewdefs.php file. For example, for the Documents module we have the form override:
$viewdefs['Documents']['EditView'] = array(
'templateMeta' => array(
'form' => array(
'enctype' => 'multipart/form-data', // <--- override the enctype
),
)
)
Within the metadata file, the File field can be rendered with the snippet:
array (
'name' => 'filename',
'displayParams' => array(
'link' => 'filename',
'id' => 'document_revision_id'
),
),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/File/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/File/
Powered by TCPDF (www.tcpdf.org)
Float
Overview
Renders a field that is formatted as a floating point number.
Float
The Float field is responsible for rendering a field that is formatted as a floating point number. The precision
specified will be followed, or the users default precision will take over.
Within the metadata definition, the Float field can be rendered with the snippet:
or
array(
'name' => 'weight',
'displayParams' => array(
'precision' => 1
)
),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Float/
Powered by TCPDF (www.tcpdf.org)
Html
Overview
Renders read-only content.
Html
The Html field is a simple field that renders read-only content after the content is run through the from_html method
of ./include/utils/db_utils.php to encode entity references to their HTML characters (i.e. ">" = ">"). The rendering
of the Html field type should be handled by the custom field logic within SugarCRM.
name
displayParams
none
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Html/
Powered by TCPDF (www.tcpdf.org)
Iframe
Overview
Renders an iFrame field.
iFrame
In the detail view, the iFrame field creates an HTML <iframe> element where the src attribute points to the given
URL value supplied in the edit view. Alternatively, the URL may be generated from the values of other fields, and
the base URL in the vardefs. If this is the case, the field is not editable in the edit view.
name
displayParams
None
Related
This section automatically lists related pages, such as child pages or pages related by tags. Remove this section if
you do not want to show related pages.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Iframe/
Powered by TCPDF (www.tcpdf.org)
Image
Overview
Renders an <img> tag where the src attribute points to the value of the field.
Image
Similar to the Html field, the Image field simply renders a <img> tag where the src attribute points to the value of
the field.
Within the metadata file, the Image field can be rendered with the snippet:
array (
// The value of this is assumed to be some URL to an image file
'name' => 'my_image_value',
'type' => 'image',
'displayParams' => array(
'width' => 100,
'length' => 100,
'link' => 'http://www.cnn.com',
'border' => 0
)
,),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Image/
Powered by TCPDF (www.tcpdf.org)
Int
Overview
Renders a field that is formatted as a whole number.
Int
The Int field is responsible for rendering a field that is formatted as a whole number. This will always be displayed
as a whole number, and any digits after the decimal point will be truncated.
Within the metadata definition, the Int field can be rendered with the snippet:
or
array(
)),
'required' => 1
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Int/
Powered by TCPDF (www.tcpdf.org)
Link
Overview
Renders a hyperlink to a records detail view.
Link
The link field simply generates an <a> HTML tag with a hyperlink to the value of the field for detail views. For edit
views, it provides the convenience of pre-filling the "http://" value. Alternatively, the URL may be generated from the
values of other fields, and the base URL in the vardefs. If this is the case, the field is not editable in edit view.
Within the metadata file, the Link field can be rendered with the snippet:
array (
// The value of this is assumed to be some URL to an image file
=> 'my_image_value',
'type' => 'link',
'displayParams' => array(
' => 'LBL_MY_TITLE'
),),
'name'
'title
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Link/
Powered by TCPDF (www.tcpdf.org)
Multienum
Overview
Renders a bullet list of values for detail views.
Multienum
The Multienum fields renders a bullet list of values for detail views, and renders a <select> form element for edit
views that allows multiple values to be chosen. Typically, the custom field handling in Sugar will map multienum
types created through Studio, so you do not need to declare metadata code to specify the type override.
Nevertheless, within the metadata file, the Multienum field can be rendered with the snippet:
array (
'name' => 'my_multienum_field',
'type' => 'multienum',
'displayParams' => array(
'javascript' => 'onchange="alert(\'hello world!\')";'
)
),
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Multienum/
Powered by TCPDF (www.tcpdf.org)
Parent
Overview
Renders a dropdown for the parent module type.
Parent
The parent field combines a blend of a dropdown for the parent module type, and a text field with code to allow
QuickSearch for quicksearch-enabled modules (see ./include/SugarFields/Fields/Parent/EditView.tpl file contents
and JavaScript code for more information on enabling Quicksearch). There are also buttons to invoke popups and
a button to clear the value. Because the parent field assumes proper relationships within the Sugar modules, it is
not a field you can add through Studio or attempt to type override in the metadata files.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Parent/
Powered by TCPDF (www.tcpdf.org)
Password
Overview
Renders an input text field for passwords.
Password
The password field simply renders an input text field with the type attribute set to "password" to hide user input
values. It is available to edit views only.
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Password/
Powered by TCPDF (www.tcpdf.org)
Phone
Overview
Renders a call to trigger VOIP applications.
Phone
The phone field simply invokes the callto:// URL references that could trigger Skype or other VOIP applications
installed on the users system. It is rendered for detail views only.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Phone/
Powered by TCPDF (www.tcpdf.org)
Radioenum
Overview
Renders a group of radio buttons.
Radioenum
The Radioenum field renders a group of radio buttons. Radioenum fields are similar to the enum field, but only one
value can be selected from the group.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Radioenum/
Powered by TCPDF (www.tcpdf.org)
Readonly
Overview
Directs edit view calls to use the SugarFields detail view display.
Readonly
The readonly field simply directs edit view calls to use the SugarFields detail view display. There are no
Smarty .tpl files associated with this field.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Readonly/
Powered by TCPDF (www.tcpdf.org)
Relate
Overview
Combines a blend of a text field with code to allow quick search.
Relate
The Relate field combines a blend of a text field with code to allow quick search. The quicksearch code is
generated for edit views (see ./include/TemplateHandler/TemplateHandler.php). There are also buttons to invoke
popups and a button to clear the value. For detail views, the Relate field creates a hyperlink that will bring up a
detail view request for the fields value.
Within the metadata file, the Relate field can be rendered with the snippet:
array (
array(
'name' => 'account_name',
'displayParams' => array(
'required' => true
This will create a relate field that allows the user to input a value not found in the quicksearch list.
name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Relate/
Powered by TCPDF (www.tcpdf.org)
Text
Overview
Renders an HTML textarea form element for edit views.
Text
The Text field renders a <textarea> HTML form element for edit views and displays the field value with newline
characters converted to HTML elements in detail views.
Name
displayParams
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Text/
Powered by TCPDF (www.tcpdf.org)
Username
Overview
A helper field that assumes a salutation, first_name and last_name.
Username
The Username field is a helper field that assumes a salutation, first_name and last_name field exists for the vardefs
of the module. It displays the three fields in the format:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/10_SugarFields/10_Widgets/Username/
Powered by TCPDF (www.tcpdf.org)
Examples
Legacy MVC metadata examples.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/
Powered by TCPDF (www.tcpdf.org)
Overview
How to add QuickSearch to a custom field.
Note: This customization is only applicable for modules in backward compatibility mode.
require_once('include/QuickSearchDefaults.php');
$qsd = new QuickSearchDefaults();
2. Then, set up the config for the input box you wish to have SQS. Account, Team, and User configs are
available. The following configures SQS for account search on an input box with an id of
parent_name, and user and team in a similar fashion with defaults.
$sqs_objects = array(
'parent_name' => $qsd->getQSParent(),
'assigned_user_name' => $qsd->getQSUser(),
'team_name' => $qsd->getQSTeam()
);
Notes on structure of config - replace the default parameters if they are different for the page.
method : Unless you make a new method on the JSON server, keep this as query.
populate_list : This defines the ids of the fields to be populated after a selection is made.
QuickSearch will map the first item of field_list to the first item of populate_list. ie. field_list[0] =
populate_list[0], field_list[1] = populate_list[1]. until the end of populate list.
limit : reduce from 30 if the query is a large hit, but never have this less than 12.
conditions : options are like_custom, contains, or default of starts with
if using like_custom also define begin/end for strings to prepend or
append to the user input
disable: set this to true to disable SQS (optional, useful for disabling SQS on parent types in calls for
example)
post_onblur_function : this is an optional function to be called after the user has made a selection.
It will be passed in an array with the items in field_list as keys and their corresponding values for the
selection as values.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Adding_QuickSearch_to_a_custom_field/
require_once('include/JSON.php');
$json = new JSON();
$quicksearch_js .= '<script type="text/javascript" language="javascript">
sqs_objects = ' . $json->encode($sqs_objects) . '</script>';
5. Add validation so that if there is no matching id for what the user has entered in an SQS field, an alert
shows. This is for fields such as assigned users where the form must submit a valid ID.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Adding_QuickSearch_to_a_custom_field/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Adding_QuickSearch_to_a_custom_field/
Powered by TCPDF (www.tcpdf.org)
1. Create a new TextField under Accounts named youtube_c. You can do this by navigating to Admin
> Studio > Accounts > Fields > Add Field.
2. Add this custom text field to both the edit view and detail view layouts. Save and deploy the updated
layouts.
3. Create the directory ./custom/include/SugarFields/Fields/YouTube/. The name of the directory (YouTube)
corresponds to the name of the field type you are creating.
4. In the ./include/SugarFields/Fields/YouTube/ directory, create the file DetailView.tpl. For the detail view we
will use the "embed" tag to display the video. In order to do this, you need to add the following to the
template file:
./include/SugarFields/Fields/YouTube/DetailView.tpl
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Creating_a_Custom_Sugar_Field/
You will notice that we use the "{{" and }} double brackets around our variables. This implies that that
section should be evaluated when we are creating the cache file. Remember that Smarty is used to generate the
cached templates so we need the double brackets to distinguish between the stage for generating the template file
and the stage for processing the runtime view.
Also note that will use the default edit view implementation that is provided by the base sugar field. This will give us
a text field where people can input the YouTube video ID, so you do not need to create EditView.tpl. Also, we do
not need to provide a PHP file to handle the SugarField processing since the defaults will suffice.
Note: It is important to set your system to Developer Mode or run a Quick Repair and Rebuild to rebuild the cache
directory.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Creating_a_Custom_Sugar_Field/
Powered by TCPDF (www.tcpdf.org)
Next, we will modify the custom detailviewdefs.php file to contain the includes array element in the
templateMeta array as follows:
./custom/modules/Quotes/metadata/detailviewdefs.php
$viewdefs['Quotes'] = array (
'DetailView' =>
array (
'templateMeta' =>
array (
'form' =>
array (
'closeFormBeforeCustomButtons' => true,
'buttons' =>
array (
0 => 'EDIT',
1 => 'SHARE',
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Hidding_the_Quotes_Module_PDF_Buttons/
type="hidden"
type="hidden"
type="hidden"
type="hidden"
name="module" value="Quotes">
name="record" value="{$fields.id.value}">
name="user_id" value="{$current_user->id}">
name="team_id" value="{$fields.team_id.value
}">
<input type="hidden" name="user_name" value="{$current_user->user
_name}">
<input type="hidden" name="action" value="QuoteToOpportunity">
<input type="hidden" name="opportunity_subject" value="{$fields.n
ame.value}">
<input type="hidden" name="opportunity_name" value="{$fields.name
.value}">
<input type="hidden" name="opportunity_id" value="{$fields.billin
g_account_id.value}">
<input type="hidden" name="amount" value="{$fields.total.value}">
<input type="hidden" name="valid_until" value="{$fields.date_quot
e_expected_closed.value}">
<input type="hidden" name="currency_id" value="{$fields.currency_
id.value}">
<input id="create_opp_from_quote_button" title="{$APP.LBL_QUOTE_T
O_OPPORTUNITY_TITLE}"
class="button" type="submit" name="opp_to_quote_button"
value="{$APP.LBL_QUOTE_TO_OPPORTUNITY_LABEL}" {$DISABLE_CONVE
RT}></form>',
),
),
'footerTpl' => 'modules/Quotes/tpls/DetailViewFooter.tpl',
),
'maxColumns' => '2',
'widths' =>
array (
0 =>
array (
'label' => '10',
'field' => '30',
),
1 =>
array (
'label' => '10',
'field' => '30',
),
),
'includes' =>
array (
0 =>
array (
'file' => 'custom/modules/Quotes/removePdfBtns.js',
),
),
'useTabs' => false,
'tabDefs' =>
array (
'LBL_QUOTE_INFORMATION' =>
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Hidding_the_Quotes_Module_PDF_Buttons/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Hidding_the_Quotes_Module_PDF_Buttons/
Powered by TCPDF (www.tcpdf.org)
Metadata
Before adding buttons to your layouts, you will need to understand how the metadata framework is used. Detailed
information on the metadata framework can be found in the Legacy Metadata section.
Custom Layouts
Before you can add a button to your layout, you will first need to make sure you have a custom layout present. The
stock layouts are located in ./modules/<module>/metadata/ and must be recreated in
./custom/modules/<module>/metadata/.
There are two ways to recreate a layout in the custom directory if it does not already exist. The first is to navigate
to:
Once there, you can click the "Save & Deploy" button. This will create the layoutdef for you. Alternatively, you can
also manually copy the layoutdef from the stock folder to the custom folder.
Editing Layouts
When editing layouts you have three options in having your changes reflected in the UI.
Developer Mode
You can turn on Developer Mode:
Developer Mode will remove the caching of the metadata framework. This will cause your changes to be reflected
when the page is refreshed. Make sure this setting is deactivatated when you are finished with your customization.
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
This process can be a bit confusing, however, once a layout is changed, you can then choose to load the layout in
studio and then click "Save & Deploy" . This will rebuild the cache for that specific layout. Please note that any time
you change the layout, you will have to reload the Studio layout view before deploying in order for this to work
correctly.
JavaScript Actions
If you are adding a button soley to execute JavaScript (no form submissions), you can do so by adding the button
HTML to:
$viewdefs['<Module>']['<View>']['templateMeta']['form']['buttons']
Example
<?php
$viewdefs['Accounts'] =
array (
'DetailView' =>
array (
'templateMeta' =>
array (
'form' =>
array (
'buttons' =>
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
array (
0 => 'EDIT',
1 => 'DUPLICATE',
2 => 'DELETE',
3 => 'FIND_DUPLICATES',
4 => 'CONNECTOR',
5 =>
array (
'customCode' => '<input id="JavaScriptButton" title="
JavaScript Button
" class="button" type="button" name="JavaScriptButton
" value="JavaScript Button" onclick="alert(\'Button JavaScript\')">',
),
),
),
$viewdefs['<Module>']['<View>']['templateMeta']['form']['buttons']
Example
<?php
$viewdefs['Accounts'] =
array (
'DetailView' =>
array (
'templateMeta' =>
array (
'form' =>
array (
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
'hidden' =>
array (
0 => '<input type="hidden" id="customFormField" name="customFormField" valu
e="">',
),
'buttons' =>
array (
0 => 'EDIT',
1 => 'DUPLICATE',
2 => 'DELETE',
3 => 'FIND_DUPLICATES',
4 => 'CONNECTOR',
5 =>
array (
'customCode' => '<input id="SubmitStockFormButton" title="Submit Stock Fo
rm Button" class="button" type="button" name="SubmitStockFormButton" value="Submit St
ock Form Button" onclick="var _form = document.getElementById(\'formDetailView\'); _f
orm.customFormField.value = \'CustomValue\'; _form.action.value = \'CustomAction\'; S
UGAR.ajaxUI.submitForm(_form);">',
),
),
),
You should note in this example that there is also a hidden index. This is where you should add any
custom hidden inputs:
$viewdefs['<Module>']['<View>']['templateMeta']['form']['hidden']
$viewdefs['<Module>']['<View>']['templateMeta']['form']['closeFormBeforeCustomButtons']
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
$viewdefs['<Module>']['<View>']['templateMeta']['form']['buttons']
Example
<?php
$viewdefs['Accounts'] =
array (
'DetailView' =>
array (
'templateMeta' =>
array (
'form' =>
array (
'closeFormBeforeCustomButtons' => true,
'buttons' =>
array (
0 => 'EDIT',
1 => 'DUPLICATE',
2 => 'DELETE',
3 => 'FIND_DUPLICATES',
4 => 'CONNECTOR',
5 =>
array (
'customCode' => '<form action="index.php" method="POST" name="CustomForm"
id="form"><input type="hidden" name="customFormField" name="customFormField" value="
CustomValue"><input id="SubmitCustomFormButton" title="Submit Custom Form Button" cla
ss="button" type="submit" name="SubmitCustomFormButton" value="Submit Custom Form But
ton"></form>',
),
),
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
Removing Buttons
To remove a button from the detail view will require modifying the
./modules/<module>/metadata/detailviewdefs.php.
The code is originally defined as:
$viewdefs[$module_name] = array (
'DetailView' => array (
'templateMeta' => array (
'form' => array (
'buttons' => array (
'EDIT',
'DUPLICATE',
'DELETE',
'FIND_DUPLICATES'
),
),
To remove one or more buttons, simply remove the buttons attribute(s) that you do not want on the view.
$viewdefs[$module_name] = array (
'DetailView' => array (
'templateMeta' => array (
'form' => array (
'buttons' => array (
'DELETE',
),
),
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Buttons_on_Layouts/
Powered by TCPDF (www.tcpdf.org)
The ParserFactory
The ParserFactory can be used to manipulate layouts such as editviewdefs or detailviewdefs. This is a handy when
creating custom plugins and needing to merge changes into an existing layout. The following example will
demonstrate how to add a button to the detail view:
<?php
//Instantiate the parser factory for the Accounts DetailView.
require_once('modules/ModuleBuilder/parsers/ParserFactory.php');
$parser = ParserFactory::getParser('detailview', 'Accounts');
//Button to add
$button = array(
'customCode'=>'<input type="button" name="customButton" value="Custom Button"
>'
);
//Add button into the parsed layout
array_push($parser->_viewdefs['templateMeta']['form']['buttons'], $button);
//Save the layout
$parser->handleSave(false);
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Manipulating_Layouts_Programmatically/
Powered by TCPDF (www.tcpdf.org)
Resolution
On-Demand
First, you will want to ensure your layouts are deployed in the custom directory. If you have not previously
customized your layouts via Studio, go to Admin > Studio > {Module Name} > Layouts. From there, select each
layout you wish to add additional columns to and click Save & Deploy. This action will create a
corresponding layout file under the ./custom/modules/{Module Name}/metadata/ directory. The files will be named
editviewdefs.php, detailviewdefs.php, and quickcreatedefs.php depending on the layouts deployed.
To access your custom files, go to Admin > Diagnostic Tool, uncheck all the boxes except for "SugarCRM Custom
directory" and then click "Execute Diagnostic". This will generate an archive of your instances custom directory
to download, and you will find the layout files in the above path. Open the custom layout file, locate the
maxColumns value, and change it to the number of columns you would like to have on screen:
Once that is updated, locate the widths array to define the spacing for your new column(s). You should
have a label and field entry for each column in your layout:
After this is completed, you will need to create a module-loadable package to install the changes on your OnDemand instance. More information on creating this package can be found in Creating an Installable Package
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Modifying_Layouts_to_Display_Additional_Columns
After you have added the desired fields in Studio, click Save & Deploy, and you are ready to go!
On-Site
First, you will want to ensure your layouts are deployed in the custom directory. If you have not previously
customized your layouts via Studio, go to Admin > Studio > {Module Name} > Layouts. From there, select each
layout you wish to add additional columns to and click Save & Deploy. This action will create a
corresponding layout file under the ./custom/modules/{Module Name}/metadata/ directory. The files will be named
editviewdefs.php, detailviewdefs.php, and quickcreatedefs.php depending on the layouts deployed.
Next, open the custom layout file, locate the maxColumns value, and change it to the number of columns
you would like to have on screen:
Once that is updated, locate the widths array to define the spacing for your new column(s). You should
have a label and field entry for each column in your layout:
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Modifying_Layouts_to_Display_Additional_Columns
Once this is completed, you can navigate to Studio and add fields to your new column in the layout. For any rows
that already contain two fields, the second field will automatically span the second and third column. Simply click
the minus (-) icon to contract the field to one column and expose the new column space:
After you have added the desired fields in Studio, click Save & Deploy, and you are ready to go!
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/40_Metadata/Examples/Modifying_Layouts_to_Display_Additional_Columns
Powered by TCPDF (www.tcpdf.org)
Examples
Provides an overview of example MVC customizations
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/50_Examples/
Powered by TCPDF (www.tcpdf.org)
Customization Information
This customization is only for modules in backward compatibility mode and involves creating custom files that
extend stock files. Please note that when creating or moving files you will need to rebuild the file map. More
information on rebulding the file map can be found in the SugarAutoLoader . You should also note that this
customization does not address all scenarios within the view that may assign a sort order.
<?php
require_once 'include/SearchForm/SearchForm2.php';
class CustomSearchForm extends SearchForm
{
/**
* displays the tabs (top of the search form)
*
* @param string $currentKey key in $this->tabs to show as the current tab
*
* @return string html
*/
function _displayTabs($currentKey)
{
//check and set the default sort order
if (!isset($_REQUEST['sortOrder']))
{
$_REQUEST['sortOrder'] = 'DESC';
}
return parent::_displayTabs($currentKey);;
}
}
?>
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/50_Examples/Changing_the_ListView_Default_Sort_Order/
<?php
require_once 'include/MVC/View/views/view.list.php';
class ViewCustomList extends ViewList
{
function prepareSearchForm()
{
$this->searchForm = null;
//search
$view = 'basic_search';
if(!empty($_REQUEST['search_form_view']) && $_REQUEST['search_form_view'] ==
'advanced_search')
$view = $_REQUEST['search_form_view'];
$this->headers = true;
if(!empty($_REQUEST['search_form_only']) && $_REQUEST['search_form_only'])
$this->headers = false;
elseif(!isset($_REQUEST['search_form']) || $_REQUEST['search_form'] != 'false
')
{
if(isset($_REQUEST['searchFormTab']) && $_REQUEST['searchFormTab'] == 'ad
vanced_search')
{
$view = 'advanced_search';
}
else
{
$view = 'basic_search';
}
}
$this->view = $view;
$this->use_old_search = true;
if (SugarAutoLoader::existingCustom('modules/' . $this->module . '/SearchForm
.html') &&
!SugarAutoLoader::existingCustom('modules/' . $this->module . '/metadata/
searchdefs.php')) {
require_once('include/SearchForm/SearchForm.php');
$this->searchForm = new SearchForm($this->module, $this->seed);
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/50_Examples/Changing_the_ListView_Default_Sort_Order/
else {
$this->use_old_search = false;
//Updated to require the extended CustomSearchForm class
require_once('custom/include/SearchForm/SearchForm2.php');
$searchMetaData = SearchForm::retrieveSearchDefs($this->module);
$this->searchForm = $this->getSearchForm2($this->seed, $this->module, $th
is->action);
$this->searchForm->setup($searchMetaData['searchdefs'], $searchMetaData['
searchFields'], 'SearchFormGeneric.tpl', $view, $this->listViewDefs);
$this->searchForm->lv = $this->lv;
}
}
/**
* Returns the search form object
*
* @return SearchForm
*/
protected function getSearchForm2($seed, $module, $action = "index")
{
//Updated to use the extended CustomSearchForm class
return new CustomSearchForm($seed, $module, $action);
}
}
?>
<?php
/**
* Custom SugarCRM controller
* @api
*/
class CustomSugarController extends SugarController
{
/**
* Perform the specified action.
* This can be overridde in a sub-class
*/
private function do_action()
{
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/50_Examples/Changing_the_ListView_Default_Sort_Order/
SugarCrmGuides/Sugar_Developer_Guide_7.2/20_UI_Model/90_Legacy_MVC/50_Examples/Changing_the_ListView_Default_Sort_Order/
Powered by TCPDF (www.tcpdf.org)