Custom Address Fields

sugarcrmdevelopers —  October 21, 2011

You can create a new set of Address fields for any particular module with relative ease via Sugar’s Studio tool, but there are a few extra steps if you want the true Address field-type in your Layouts.

Address Field Set

Generally, if you have an address field, your view definition should look like this:

$viewdefs['Cases']['EditView']['panels']['lbl_editview_panel1'][0] =
          array (
            'name' => 'primary_address_street',
            'hideLabel' => true,
            'type' => 'address',
            'displayParams' =>
            array (
              'key' => 'primary',
              'rows' => 2,
              'cols' => 30,
              'maxlength' => 150,
            ),
          ),
;

But go try that for your custom field (e.g. insurance_address_c) and you’ll be disappointed. The formatting will work, but the data entered won’t save. To see why, have a look at include/SugarFields/Fields/Address/EditView.tpl. Note that some of the first several lines handle variable assignment and reference what is essentially the prefix defined in the displayParams concatenated with the typical address fields

{{assign var="street" value=$displayParams.key|cat:'_address_street'}}
{{assign var="city" value=$displayParams.key|cat:'_address_city'}}
{{assign var="state" value=$displayParams.key|cat:'_address_state'}}
{{assign var="country" value=$displayParams.key|cat:'_address_country'}}
{{assign var="postalcode" value=$displayParams.key|cat:'_address_postalcode'}}

Of course, being a custom field, our insurance_address_c ends in _address_c instead of _address. Two options from here: re-factor the Address field type or re-factor your five fields to not use the _c suffix. Also note the naming of the field that holds the street address. The template files expects _address_street but our custom field is not named in this way. We’ll have to change that, too.

Let’s walk through the latter, as it will be much shorter to do in a single instance in an upgrade-safe way. In this example, I have created the address fields on the Cases module as

  • insurance_address_c
  • insurance_address_city_c
  • insurance_address_state_c
  • insurance_address_postalcode_c
  • insurance_address_country_c

You’ll be required to make a series of database changes that aren’t 100% generic. We need to update the relevant rows in fields_meta_data as well as update the column names in cases_cstm to rename these fields. Additionally, we need to adjust the view definitions to reference the new name.

For fields_meta_data, we simply update the rows:

update `fields_meta_data` set name = 'insurance_address_street' where name = 'insurance_address_c';
update `fields_meta_data` set name = 'insurance_address_city' where name = 'insurance_address_city_c';
update `fields_meta_data` set name = 'insurance_address_state' where name = 'insurance_address_state_c';
update `fields_meta_data` set name = 'insurance_address_postalcode' where name = 'insurance_address_postalcode_c';
update `fields_meta_data` set name = 'insurance_address_country' where name = 'insurance_address_country_c';

For cases_cstm we update the column names themselves:

ALTER TABLE `cases_cstm` CHANGE COLUMN `insurance_address_city_c` `insurance_address_city` VARCHAR(100) NULL DEFAULT NULL  , CHANGE COLUMN `insurance_address_state_c` `insurance_address_state` VARCHAR(100) NULL DEFAULT NULL  , CHANGE COLUMN `insurance_address_postalcode_c` `insurance_address_postalcode` VARCHAR(20) NULL DEFAULT NULL  , CHANGE COLUMN `insurance_address_country_c` `insurance_address_country` VARCHAR(100) NULL DEFAULT NULL  , CHANGE COLUMN `insurance_address_c` `insurance_address_street` VARCHAR(255) NULL DEFAULT NULL;

For some, it will also be necessary to also update the vardefs. In this example, there are five files in custom/Extension/modules/Cases/Ext/Vardefs/. The file names themselves don’t need to change, but any references within them need to drop the _c. For example,

$dictionary['Case']['fields']['insurance_address_country_c']['dependency']='';

becomes

$dictionary['Case']['fields']['insurance_address_country']['dependency']='';

If you do adjust vardefs, you’ll need to run a Repair and Rebuild.

Finally, we adjust the view definitions. Anywhere that you’ve referenced the field will need to be adjusted. Here’s the original EditView definition for the field:

$viewdefs['Cases']['EditView']['panels']['lbl_editview_panel1'][0] =
          array (
            'name' => 'insurance_address_c',
            'label' => 'LBL_INSURANCE_ADDRESS',
          ),
;

From Studio, it didn’t even use the Address field type. Here’s the adjusted version (don’t forget that we renamed it from insurance_address_c to insurance_address_street)

$viewdefs['Cases']['EditView']['panels']['lbl_editview_panel1'][0] =
          array (
            'name' => 'insurance_address_street',
            'label' => 'LBL_INSURANCE_ADDRESS',
            'hideLabel' => true,
            'type' => 'address',
            'displayParams' =>
            array (
              'key' => 'insurance',
              'rows' => 2,
              'cols' => 30,
              'maxlength' => 150,
            ),
          ),
;

This one uses the one field reference to call the Address sugar field template, which actually calls all of the relevant address fields. The view definition above works for Edit and Quick Create views. For Detail views, it is the same except that the ‘hideLabel’ parameter is not necessary (in fact, it’s probably not desirable).

In summary, we’ve changed database fields, database columns, vardefs, and view definitions to reflect a renaming scheme. It works, it is upgrade-safe, and it allows our users to handle a fieldset of address fields instead of having the address-related fields strewn throughout multiple table rows on the page.