Author: Pavel Chumachenko, Software Engineer
We are repeatedly talking about the flexibility of SugarCRM for various modifications.
This time we will discuss SugarCRM customization for the implementation of the mechanism that hides or displays the subpanel on the detail view card of the record with a specific value of its attribute.
Conditions
The best way to show such SugarCRM customization is to demonstrate it through the example. So, let’s say, we have a Company. Each of the Companies in the system is characterized by a Category. “Investor” is one of the possible values of this attribute. Also, each company has 2 subpanels: “Investors” and “Investment Recipients” The task is to display “Investment Recipients” subpanel when [Company.Category] = “Investor”, and display “Investors” subpanel with another value of attribute Category. In other words, for any value of [Company.Category] we need to hide one of the subpanels: either «Investors» or «Investment Recipients»
Below you may find a description of the standard connection of 2 subpanels to the application block of the Company.
Path:
1 | \custom\modules\Accounts\clients\base\layouts\subpanels\subpanels.php |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $viewdefs['Accounts']['base']['layout']['subpanels']['components'][] = array ( 'layout' => 'subpanel', 'label' => 'LBL_INVESTORS_SUBPANEL_TITLE', 'context' => array ( 'link' => 'px_investors_link', ), ); $viewdefs['Accounts']['base']['layout']['subpanels']['components'][] = array ( 'layout' => 'subpanel', 'label' => 'LBL_INVESTMENT_RECIPIENTS_SUBPANEL_TITLE', 'context' => array ( 'link' => 'px_investment_recipients_link', ), ); |
Where px_investors_link is a link indicating all the investors of the Company;
px_investment_recipients_link is a link indicating all the companies receiving investments from the company in question.
Not every customization requires code changes. We took several practical tasks that seemed to involve coding and solved them without programming. These automations are very popular among CRM users, and can save you a lot of time and effort.
Reinventing the Wheel
The functional part of the system responsible for the display of subpanels is described in subpanels.js controller.
Path:
1 | \custom\modules\Accounts\clients\base\layouts\subpanels\subpanels.js |
To correct its operation in the module of the Company, we will be working in this file. Unless you have such a file, you should create it.
The first step is to indicate that we are inheriting from “SubpanelsLayout” and call a parent initialization method.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 | ({ extendsFrom: 'SubpanelsLayout', initialize: function (options) { app.view.invokeParent(this, { type: 'layout', name: 'subpanels', method: 'initialize', args: [options] }); } }) |
At the next step, let’s extend our class with properties needed to solve the main problem: “Do we have to hide the subpanel?”. We will specify at once that the subpanel to be hidden / displayed, will be determined by its link title.
New properties of the class:
- hide_subpanels is an array of subpanel records that can be hidden
- check_field is the name of the parent record attribute, the value of which affects the display of the subpanel(s)
- check_field_value is the value of the attribute of the parent record specified in the previous property
- hide_on_value is an object that consists of property-value pairs, where
- property is the name of the subpanel link
- value is an array of values where the subpanel will be hidden
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ({ extendsFrom: 'SubpanelsLayout', // subpanels to hide hide_subpanels: ['px_investors_link', 'px_investment_recipients_link'], // watched field in Parent Record check_field: 'px_category', check_field_value: '', // hide subpanel if it [check_field] is in specific array hide_on_value: { px_investors_link : ['Investor'], px_investment_recipients_link : ['Category 1', 'Category 2'] }, initialize: function (options) { app.view.invokeParent(this, { type: 'layout', name: 'subpanels', method: 'initialize', args: [options] }); } }) |
The preparatory work for our SugarCRM customization is done, so we can proceed to the main step – overriding of showSubpanel() method, which is responsible for displaying or hiding subpanels. In addition, we want to say that this is the only method to be overridden for the implementation of the current task. So, we need to change slightly the operation logic of showSubpanel() method. Namely, before calling show() method we need to add a new test: “Should the current subpanel be displayed?” If it turns out that the subpanel has to be hidden, call hide() method instead of show() method.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /** * Show the subpanel for the given linkName and hide all others * @param {String} linkName name of subpanel link */ showSubpanel: function (linkName) { var self = this, // this.layout is the filter layout which subpanels is child of; // we use it here as it has a last_state key in its meta cache_key = app.user.lastState.key('subpanels-last', this.layout); // wait for the model to load self.model.on(«change», function () { // fetch the value from the model of our targeted field self.check_field_value = this.get(self.check_field); if (linkName) { app.user.lastState.set(cache_key, linkName); } _.each(self._components, function (component) { var link = component.context.get('link'); // determine should we hide current subpanel var hide_subpanel = self._checkIfHideSubpanel(link); if (!hide_subpanel && ( !linkName || linkName === link )) { component.context.set(«hidden», false); component.show(); } else { component.context.set(«hidden», true); component.hide(); } }); }); } |
To check if the subpanel is available during the implementation of showSubpanel() method, _checkIfHideSubpanel() method shall be employed. It assumes one argument – subpanel, i.e. the name of the link of the current subpanel. It returns TRUE, if the subpanel is in hide_subpanels array, and if the value of the checked attribute of the parent record is in the property of hide_on_value[subpanel] object. Otherwise, _checkIfHideSubpanel() method returns FALSE.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * Check if the subpanel is on the hiding list * and if the watched field has a specific value. * @param {String} subpanel name of the module for the subpanel */ _checkIfHideSubpanel: function( subpanel ) { var self = this; var hide_subpanel = false; if ( jQuery.inArray(subpanel, self.hide_subpanels) !== -1 && jQuery.inArray(self.check_field_value, self.hide_on_value[subpanel]) !== -1 ) { hide_subpanel = true; } return hide_subpanel; } |
Conclusions
This tutorial shows how to customize SugarCRM for the implementation of the mechanism imposing additional restrictions on the display of the subpanel, depending on the value of the attribute of its parent record.
As usual, feel free to contact us if you need advice on how to customize SugarCRM to make it more convenient and efficient for your needs.
Other SugarCRM customization tutorials: