Module: View/ViewManager

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, and null 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 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 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 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 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 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 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, 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 Argument 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.

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.