Experience has taught me not to trust users to make the right selections. So, while initialFilter provides the ability to pre-define some selection criteria in a Relate Field popup, it does not provide the ability to restrict the user to this criteria on any subsequent search.
Note: Relate fields can also be used to restrict relationships. See this Developer Tutorial for that functionality: http://www.sugarcrm.com/forums/showthread.php?t=47776
For limited related record sets, I can change the relate id field to an enum (dropdown) and source it with a function that returns an array of record ids and names that are pushed into options for the select field on the editview form. This solution does not work well when the related record set is potentially large that could use some additional search criteria. Thus, the need for a custom popup that also restricts the related fields to pre-defined criteria.
To create a custom popup for a relate field that restricts the records a user can select, follow these steps:
1) Create a javascript file that contains the code to change the onlick function to call your custom popup for the relate field select button.
2) Add the javascript file to 'includes' parameter of a custom editviews.def.
3) create the custom popupdefs file for the related module with the restricted selection criteria in the WhereStatement and reference your custom popup_picker template.
4) create the custom popup_picker file for the related module with the custom metadata filename value as a hidden field.
In the following example, I created a custom Keyword module that is related to Mobile Marketing Campaign with a many-to-one relationship. The related campaign must be restricted to campaign types of 'Mobile' only. To make this work, I needed to restrict the related Campaign popup to only select campaigns with that campaign_type value - both intially and on any subsequent user searches.
First, the javascript code - which is added to a file called pkg_Keywords.js in the custom module.
Second, modify or create a custom editviews.def file. In this example, this is a custom module from modulebuilder, so we just can just modify the editviewdefs.php file in the metadata directory to add the include values in the templateMeta.Code:function custom_onload() { set_campaign_search(); } function set_campaign_search() { form = document.getElementById('EditView'); for (i = 0; i < form.elements.length; i++) { if(form.elements[i].name == 'btn_campaign') { elem = form.elements[i]; // note we use a function pointer here and not a quoted function call if(window.addEventListener) { elem.addEventListener("click", campaign_search, false); } else if (window.attachEvent) { // IE requires both actions to actually reset the onlick value elem.attributes['onclick'].value = null; elem.attachEvent('onclick', campaign_search); } else if (document.getElementById) { // fail over - assign the quoted javascript function call elem.attributes['onclick'].value = "campaign_search();"; } } } } function campaign_search(){ // the last value in the open_popup is the name of the popupdefs file (leave off the .php) // the field_to_name array assigns id and name to respective relate field values (campaign_id_c and campaign) return open_popup("Campaigns", 600, 400, "", true, false, {"call_back_function":"set_return","form_name":"EditView", "field_to_name_array":{"id":"campaign_id_c","name":"campaign"}}, "single", true, "keyword_popupdefs"); }
Third, create the custom popup defs file and add the necessary record selection criteria to the whereStatement and add the templateForm to point to your custom popup_picker html file. SugarCRM expects that this file exist in the module's metadata directory (i.e. "modules/<MODULE_NAME>/metadata"). I'm working on how to modify that reference in an upgrade safe manner to look at the customs directory and will post a followup on that issue.Code:<?php $module_name = 'pkg_Keywords'; $viewdefs [$module_name] = array ( 'EditView' => array ( 'templateMeta' => array ( 'includes' => array( array('file' => 'modules/pkg_Keywords/pkg_Keywords.js'), ), 'maxColumns' => '2', 'widths' => array ( 0 => array ( 'label' => '10', 'field' => '30', ), 1 => array ( 'label' => '10', 'field' => '30', ), ), ), ....[code snipped] ?>
The example whereStatement includes a very limited record selection. While I have not tested this with a complex statement, I see no reason why this could not contain subselect statements to allow for cross-module or relationship based selection criteria.
Finally, create the custom Popup_picker file. The most significant change to this file is the addition of a hidden metadata field with the same value as the last paramter in the custom open_popup function. This forces each subsequent search to use the same custom popupdefs file. Without this value, the standardCode:$popupMeta = array('moduleMain' => 'Campaign', 'varName' => 'CAMPAIGN', 'orderBy' => 'name', 'whereClauses' => array('name' => 'campaigns.name', ), 'whereStatement' => "campaign_type='Mobile'", 'searchInputs' => array('name'), 'listviewdefs' => array( 'NAME' => array( 'width' => '20', 'label' => 'LBL_LIST_CAMPAIGN_NAME', 'link' => true, 'default' => true), 'CAMPAIGN_TYPE' => array( 'width' => '10', 'label' => 'LBL_LIST_TYPE', 'default' => true), 'STATUS' => array( 'width' => '10', 'label' => 'LBL_LIST_STATUS', 'default' => true), 'START_DATE' => array( 'width' => '10', 'label' => 'LBL_LIST_START_DATE', 'default' => true), 'END_DATE' => array( 'width' => '10', 'label' => 'LBL_LIST_END_DATE', 'default' => true), ), 'searchdefs' => array( 'name', 'campaign_type', 'status', 'start_date', 'end_date' ), 'templateForm' => 'custom/modules/Campaigns/Popup_keyword_picker.html', );
popupdefs file would be referenced and you'd lose the restrictive record selection in the whereStatement.
In the example, I'm including just the form section of the template. If you compare it to the standard campaign popup, you'll see that I removed the campaign_type for the obvious reason that I did not want the user selecting a different campaign type. Also note the addition of the hidden metadata field.
Code:<form action="index.php" method="post" name="popup_query_form" id="popup_query_form"> <tr> <td class="dataLabel" nowrap="nowrap">{MOD.LBL_CAMPAIGN_NAME}</td> <td class="dataField" nowrap="nowrap"><input type="text" size="20" name="name" class="dataField" value="{NAME}"/></td> <td valign="top" align="right"> <input type="submit" name="button" class="button" title="{APP.LBL_SEARCH_BUTTON_TITLE}" accessKey="{APP.LBL_SEARCH_BUTTON_KEY}" value="{APP.LBL_SEARCH_BUTTON_LABEL}" /> </td> <td align="right"><input type="hidden" name="action" value="Popup"/> <input type="hidden" name="metadata" value="keyword_popupdefs"/> <input type="hidden" name="query" value="true"/> <input type="hidden" name="record" value="{RECORD_VALUE}"/> <input type="hidden" name="module" value="{MODULE_NAME}" /> <input type="hidden" name="form_submit" value="{FORM_SUBMIT}" /> <input type="hidden" name="request_data" value="{request_data}" /> <input type="hidden" name="form" value="{FORM}" /> </form>


LinkBack URL
About LinkBacks



Reply With Quote

Bookmarks