-
Notifications
You must be signed in to change notification settings - Fork 6
Customizing An Existing Application
It is recommended that you read through the Creating An Application Module guide, the Creating A List View guide, and the Creating A Detail View guide, as we will be expanding on the information presented.
There are essentially three types of customizations: registered customizations, prototype customizations, and complete customizations. The first, registered customizations, are customizations that are registered with the application and are applied to the layout of the detail and edit views. Support for this type of customization for list views is planned for a future release.
The second type of customization, prototype customizations, are customizations that are applied to a class's, generally a view's, prototype, and either extend the functionality of the view, or override it.
The last type of customization, complete customizations, are complete custom views that live on their own. This type of customization will be discussed later.
The most common type of customization, registered customizations, are most commonly registered with the application, via the registerCustomization method, as part of a module's initialization process, specifically in the loadCustomizations method, e.g.:
Mobile.Sample.ApplicationModule = Ext.extend(Sage.Platform.Mobile.ApplicationModule, {
loadCustomizations: function() {
Mobile.Sample.ApplicationModule.superclass.loadCustomizations.apply(this, arguments);
this.registerCustomization('detail', 'account_detail', {
at: function(row) { return row.name == 'Type'; },
type: 'insert',
where: 'before',
value: {
name: 'Region',
label: 'region'
}
});
}
});The registerCustomization method takes three parameters: the customization set, the view id, and the customization object. The first parameter, the customization set, is a well known string for each base view type that supports registered customizations, i.e., detail, edit, and later list. The customization set name is also exposed as the customizationSet property on instances of supported view types. The second parameter is the identifier of the view to be modified. A falsy can be passed for this parameter in order to register a customization for all views in a given set, though this use case is uncommon.
The last parameter to the registerCustomization method, is the customization object and it describes where the change should be made, how it should be made, and what to use for the change. The at parameter defines where the change shoudl be made. The value of this property should always be a function that returns a truthy value when a layout row of interest is found. When customizations are being applied, the view's layout is processed top to bottom, with each row of the layout being passed to the at method, in sequence, and nested sections after all surrounding rows. For example, consider the following layout:
+ layout
+ sectionA
- rowA
+ sectionB
- rowB
- rowC
- rowD
+ sectionC
- rowE
The at method for any customization would then receive the layout rows in the following order:
sectionA -> rowA -> rowC -> rowD -> sectionB -> rowB -> sectionC -> rowE
After the location for the change has been determined, the type of change to make is specified by the type property on the customization object and can be one of four values: remove, replace, modify, insert.
The first type, remove, is fairly self explanatory; It will remove the matched layout row. It is worth noting that remove is a "full stop" operation, i.e. any other change to that specific layout row will be ignored.
this.registerCustomization('detail', 'account_detail', {
at: function(row) { return row.name == 'LeadSource.Description'; },
type: 'remove'
});The second type, replace, is also a "full stop" operation, but instead of removing the row from the layout, it completely replaces the layout row with the value specified in the customization object's value property.
The third type, modify, takes the value, and applies it on top of the layout row, overwriting any properties with the same name.
this.registerCustomization('detail', 'account_detail', {
at: function(row) { return row.name == 'Fax'; },
type: 'modify',
value: {
label: 'fax num'
}
});The last type, insert, does exactly that; it inserts the value as a completely new row in the layout. Also, with this type, some additional control as to where the change should be made is provided, via the where property, which accepts the values before or after, the latter of which is the default if none is specified. With the value of before, the new row will be inserted before the row matched by at, and with after, it will be inserted after the matched row.
this.registerCustomization('detail', 'account_detail', {
at: function(row) { return row.name == 'Type'; },
type: 'insert',
where: 'before',
value: {
name: 'Region',
label: 'region'
}
});The second type of customization, prototype customizations, are customizations that are applied to a class's prototype in order to extend the functionality of the view or override it. This type of customization is usually accomplished by use of the Ext.override function, e.g.:
Ext.override(Mobile.SalesLogix.Contact.List, {
contentTemplate: new Simplate([
'<h3>{%: $.NameLF %}</h3>',
'<h4>{%: $.AccountName %}</h4>',
'<h4>{%: Mobile.SalesLogix.Format.phone($.WorkPhone, false) %}</h4>'
])
});The Ext.override function takes two parameters, the class to operate on, and an object containing properties to be added to the class's prototype. In the exampe above, we are overriding, i.e. replacing, the contentTemplate property of the Mobile.SalesLogix.Contact.List view in order to include the WorkPhone for the contact. If you used the code above directly, there would be a small issue; the WorkPhone isn't being included in the SData results. In order to do that, we need to override another property on the view, querySelect, but do so in a manner that doesn't replace what's already there. We can do so by adding the following:
Ext.override(Mobile.SalesLogix.Contact.List, {
//First, make sure WorkPhone is included in the SData query.
querySelect: Mobile.SalesLogix.Contact.List.prototype.querySelect.concat([
'WorkPhone'
]),
contentTemplate: new Simplate([
'<h3>{%: $.NameLF %}</h3>',
'<h4>{%: $.AccountName %}</h4>',
'<h4>{%: Mobile.SalesLogix.Format.phone($.WorkPhone, false) %}</h4>'
])
});As you can see, we added the querySelect property. Now, this syntax may look a bit strange, but what we are doing here is taking the existing querySelect array, Mobile.SalesLogix.Contact.List.prototype.querySelect, and adding the WorkPhone value to it, and replacing it on the prototype. Notice that while we pass Mobile.SalesLogix.Contact.List to the Ext.override function, when referring to the prototype directly in our code, we have to use Mobile.SalesLogix.Contact.List.prototype. The reason for the difference is that the Ext.override function takes care of referencing the prototype internally when applying our overrides.
The previous example showed that we can safely add values to an array defined on a prototype, but what about an object, as is the case with hashTagQueries. In this case, you apply a similar approach, but instead of using the concat method of an array, you use the Ext.apply function, e.g.:
Ext.override(Mobile.SalesLogix.Account.List, {
hashTagQueries: Ext.apply(Mobile.SalesLogix.Account.List.prototype.hashTagQueries || {}, {
'linked': '$uuid ne null'
})
});The Ext.apply function, in this example, takes two arguments. The first argument is the object we are copying properties to, which in this case is the hashTagQueries property of the prototype or an emtpy object if the hashTagQueries property has not be set. The second argument is the object we are copying properties from. It is worth noting that if the hashTagQueries property of the prototype already contains a key/value pair with the same key as one in the second argument, the value will be overwritten.
As mentioned previously, the topic of complete customizations are beyond the scope of this document, but will be covered at a later date. These are the more advanced custom views that are outside the realm of a standard List, Detail, or Edit view, and generally inherit from the View class directly.
If you are interested in creating custom List or Detail views, please refer to the Creating A List View and Creating A Detail View guides.