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
#
(static) layouts
#
(static) views
Methods
#
(static) componentHasPlugin(params) → {boolean|null}
Checks if a component has a certain plugin.
Parameters:
Name |
Type |
Description |
params |
Object
|
Set of parameters passed to function.
Properties
Name |
Type |
Attributes |
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, and null
if incorrect arguments were passed.
-
Type
-
boolean
|
null
#
(static) createField(params) → {View/Field}
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 the
createField
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 |
Attributes |
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. |
|
#
(static) createLayout(params) → {View/Layout}
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 in
sugarcrm/clients/<platform>/layouts
in which case the metadata
manager will take care of namespacing your controller by platform
name for you (e.g. MyCustomLayout becomes
ViewManager.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 |
Attributes |
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. |
|
#
(static) createView(params) → {View/View}
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 like
createView
, createField
, or createLayout
. 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 |
Attributes |
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. |
|
#
(static) declareComponent(type, name, moduleopt, controlleropt, overwriteopt, platformopt) → {function}
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, if SUGAR.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 of ViewManager.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
or ColumnsLayout
including their module specific
counterparts like ContactsListView
and ContactsColumnsLayout
.
The "named" class name is checked first.
Parameters:
Name |
Type |
Attributes |
Description |
type |
string
|
|
Lower-cased component type: layout , view , or
field . |
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. |
#
(static) getFieldId() → {number}
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.