View manager is used to create views, layouts, and fields based on optional metadata inputs.
The view manager's factory methods (createView
, createLayout
, and
createField
) first check views
, layouts
, and fields
hashes
respectively for custom class declaration before falling back the base class.
Note the following is deprecated in favor of putting these controllers in the
sugarcrm/clients/<platform>
directory, or using one of the appropriate
factory methods like createView
, createField
, or createLayout
. Using
either of these idioms, your components will be internally namespaced by
platform for you. If you do choose to use the following idiom of defining
your controller directly on ViewManager.view.<type>
, please be forewarned
that you will lose any automatic namespacing benefits and possibly encounter
naming collisions if your controller names are not unique. If you must
define directly, you may choose to prefix your controller name by your
application or platform e.g. MyappMyCustom<Type>
where 'Myapp' is the
platform prefix.
Put declarations of your custom views, layouts, fields in the corresponding hash (see note above; this is deprecated):
const ViewManager = require('view/view-manager');
ViewManager.views.MyappMyCustomView = ViewManager.View.extend({
// Put your custom logic here
});
ViewManager.layouts.MyappMyCustomLayout = ViewManager.Layout.extend({
// Put your custom logic here
});
ViewManager.view.fields.MyappMyCustomField = ViewManager.Field.extend({
// Put your custom logic here
});
Members
-
<static> fields
-
Hash of field classes.
-
<static> layouts
-
Hash of layout classes.
-
<static> views
-
Hash of view classes.
Methods
-
<static> componentHasPlugin(params)
-
Checks if a component has a certain plugin.
Parameters:
Name Type Description params
Object Set of parameters passed to function.
Properties
Name Type Argument Default Description type
string Type of component to check.
name
string Name of component to check.
plugin
string Name of plugin to check.
module
string <optional>
'' Name of module to check for custom components in.
Returns:
true
if the specified component exists and has that plugin,false
if the component does not exist or lacks that plugin, andnull
if incorrect arguments were passed.- Type
- boolean | null
-
<static> createField(params)
-
Creates an instance of a field and registers it with the parent view (
params.view
).The parameters define creation rules as well as field properties.
For example,
var params = { view: new Backbone.View, def: { type: 'text', name: 'first_name', label: 'LBL_FIRST_NAME' }, context: optional context, model: optional model, meta: optional custom metadata, viewName: optional }
The view manager queries the metadata manager for field type specific metadata (templates and JS controller) unless custom metadata is passed in the
params
hash.Note the following is deprecated in favor of placing custom field controllers in
sugarcrm/clients/<platform>/fields
or using thecreateField
factory.To create instances of custom fields, first declare its class in the
ViewManager.fields
hash:// might cause collision if MyCustomField already exists! ViewManager.fields.MyCustomField = ViewManager.Field.extend({ // Put your custom logic here }); // if you must define directly on ViewManager.fields // you may instead prefer to do: ViewManager.fields.<YOUR_PLATFORM>MyCustomField = ViewManager.Field.extend({ ... var myCustomField = ViewManager.createField({ view: someView, def: { type: 'myCustom', name: 'my_custom' } });
Parameters:
Name Type Description params
Object Field parameters.
Properties
Name Type Argument Default Description view
Backbone.View Backbone View object.
def
Object Field definition.
context
Object <optional>
`SUGAR.App.controller.context` The context.
model
Object <optional>
The model to use. If not specified, the model which is set on the context is used.
viewName
string <optional>
params.view.name View name to determine the field template.
nested
boolean <optional>
Set to
true
if the field is nested. This means it already has a life cycle handler, and should not be added to the view's list of fields.Returns:
A new instance of field.
- Type
- View/Field
-
<static> createLayout(params)
-
Creates an instance of a layout.
Parameters define creation rules as well as layout properties. The factory needs either layout name or type. Also, the layout type must be specified. The layout type is retrieved either from the
params
hash or layout metadata.Examples:
Create a list layout. The view manager will use metadata for the
list
layout defined in the Contacts module. The controller's current context will be set on the new layout instance.var listLayout = ViewManager.createLayout({ type: 'list', module: 'Contacts' });
Create a custom layout class. Note that following is deprecated in favor of using the
createLayout
factory or placing controller insugarcrm/clients/<platform>/layouts
in which case the metadata manager will take care of namespacing your controller by platform name for you (e.g. MyCustomLayout becomesViewManager.layouts.MyappMyCustomLayout
).// Declare your custom layout class. // might cause collisions if already a MyCustomLayout! ViewManager.layouts.MyCustomLayout = ViewManager.Layout.extend({ // Put your custom logic here }); // if you must define directly on ViewManager.layouts, // you may instead prefer to do: ViewManager.layouts.<YOUR_PLATFORM>MyCustomLayout = ViewManager.Layout.extend({ // Put your custom logic here }); var myCustomLayout = ViewManager.createLayout({ type: 'myCustom' });
Create a layout with custom metadata payload.
var layout = ViewManager.createLayout({ type: 'detail', meta: { ... your custom metadata ... } });
Parameters:
Name Type Description params
Object layout parameters.
Properties
Name Type Argument Default Description type
string <optional>
Layout identifier (
default
,base
, etc.).name
string <optional>
params.type Layout name that distinguishes between multiple instances of the same layout type.
context
Object <optional>
SUGAR.App.controller.context Context to associate the newly created layout with.
module
string Module name.
loadModule
string <optional>
The module to load the Layout from. Defaults to
params.module
or the context's module, in that order.meta
Object <optional>
Custom metadata.
Returns:
New instance of the layout.
- Type
- View/Layout
-
<static> createView(params)
-
Creates an instance of a view.
Examples:
Create a list view. The view manager will use metadata for the view named 'list' defined in Contacts module. The controller's current context will be set on the new view instance.
var listView = ViewManager.createView({ type: 'list', module: 'Contacts' });
Create a custom view class. Note the following is deprecated in favor of putting these controllers in the
sugarcrm/clients/<platform>
directory, or using one of the appropriate factory methods likecreateView
,createField
, orcreateLayout
. Using that idiom, the metadata manager will declare these components and take care of namespacing by platform for you. If you do choose to use the following idiom please be forewarned that you will lose any namespacing benefits and possibly encounter naming collisions!// Declare your custom view class. // might cause collisions if another MyCustomView! ViewManager.views.MyCustomView = ViewManager.View.extend({ // Put your custom logic here }); // if you must define directly on ViewManager.views, you may instead // prefer to do: ViewManager.views.<YOUR_PLATFORM>MyCustomView = ViewManager.View.extend({ // Put your custom logic here }); var myCustomView = ViewManager.createView({ type: 'myCustom' });
Create a view with custom metadata payload.
var view = ViewManager.createView({ type: 'detail', meta: { ... your custom metadata ... } });
Look at View/View, particularly View/View#_loadTemplate for more information on how the
meta.template
property can be used.Parameters:
Name Type Description params
Object View parameters.
Properties
Name Type Argument Default Description type
string The view identifier (
default
,base
, etc.). Matches the controller to be used.name
string <optional>
params.type View name that distinguishes between multiple instances of the same view type. This matches the metadata to read from Core.MetadataManager and it is the easier way to reuse view types with different configurations.
context
Object <optional>
SUGAR.App.controller.context Context to associate the newly created view with.
module
string <optional>
Module name.
loadModule
string <optional>
The module that should be considered the base.
meta
Object <optional>
Custom metadata.
Returns:
New instance of view.
- Type
- View/View
-
<static> declareComponent(type, name [, module] [, controller] [, overwrite] [, platform])
-
Retrieves class declaration for a component or creates a new component class.
This method creates a subclass of the base class if controller parameter is not null and such subclass hasn't been created yet. Otherwise, the method tries to retrieve the most appropriate class by searching in the following order:
-
Custom class name:
<module><component-name><component-type>
. For example, for Contacts module one could have:ContactsDetailLayout
,ContactsFluidLayout
,ContactsListView
. -
Class name:
<component-name><component-type>
. For example:ListLayout
,ColumnsLayout
,DetailView
,IntField
. -
Custom base class:
<capitalized-appId><component-type>
For example, ifSUGAR.App.config.appId == 'portal'
, custom base classes would be:PortalLayout
,PortalView
,PortalField
.
Declarations of such classes must be in the
ViewManager
namespace. There are use cases when an app has some common component code. In such cases, using custom base classes is beneficial. For example, any app may need to override validation error handling for fields:// Assuming SUGAR.App.config.appId === 'portal': ViewManager.PortalField = ViewManager.Field.extend({ initialize: function(options) { // Call super ViewManager.Field.prototype.initialize.call(this, options); // Custom initialization code... }, handleValidationError: function(errors) { // Custom validation logic } });
The above declaration will make all field controllers extend
ViewManager.PortalField
instead ofViewManager.Field
.- Base class:
<component-type>
-Layout
,View
,Field
.
Note 1. Although the view manager supports module specific fields like
ContactsIntField
, the server does not provide such customization.Note 2. The layouts is a special case because their class name is built both from layout name and layout type. One could have
ListLayout
orColumnsLayout
including their module specific counterparts likeContactsListView
andContactsColumnsLayout
. The "named" class name is checked first.Parameters:
Name Type Argument Description type
string Lower-cased component type:
layout
,view
, orfield
.name
string Lower-cased component name. For example, 'list' (layout or view), or 'bool' (field).
module
string <optional>
Module name.
controller
string <optional>
Controller source code string.
overwrite
boolean <optional>
Will overwrite if duplicate custom class or layout is cached. Note that if no controller is passed, overwrite is ignored since we can't create a meaningful component without a controller.
platform
string <optional>
The platform e.g. 'base', 'portal', etc.
Returns:
Component class.
- Type
- function
-
-
<static> getFieldId()
-
Gets the ID of the most recently created field.
Returns:
ID of the last created field.
- Type
- number
-
<static> reset()
-
Resets class declarations of custom components.