Let the platform do the work

Manually Creating Custom Fields

Overview

The most common way to create custom fields in Sugar is via Studio inside the application. This page describes how to use the ModuleInstaller class or vardef extensions as alternative methods of creating custom fields.

Note: Sugar Sell Essentials customers do not have the ability to upload custom file packages to Sugar using Module Loader.

Using ModuleInstaller to Create Custom Fields

There are two ways to create a field using the ModuleInstaller class: via installer package or programmatically. An example of creating a field from a module-loadable package is explained in the Module Loader documentation,, Creating an Installable Package that Creates New Fields. The following example shows how to programmatically add custom fields using the ModuleInstaller class with the install_custom_fields() method:

  <?php

    $fields = array (
        //Text
        array(
            'name' => 'text_field_example',
            'label' => 'LBL_TEXT_FIELD_EXAMPLE',
            'type' => 'varchar',
            'module' => 'Accounts',
            'help' => 'Text Field Help Text',
            'comment' => 'Text Field Comment Text',
            'default_value' => '',
            'max_size' => 255,
            'required' => false, // true or false
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'importable' => 'true', // 'true', 'false', 'required'
            'duplicate_merge' => false, // true or false
        ),
        //DropDown
        array(
            'name' => 'dropdown_field_example',
            'label' => 'LBL_DROPDOWN_FIELD_EXAMPLE',
            'type' => 'enum',
            'module' => 'Accounts',
            'help' => 'Enum Field Help Text',
            'comment' => 'Enum Field Comment Text',
            'ext1' => 'account_type_dom', //maps to options - specify list name
            'default_value' => 'Analyst', //key of entry in specified list
            'mass_update' => false, // true or false
            'required' => false, // true or false
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
            'duplicate_merge' => false, // true or false
        ),
        //MultiSelect
        array(
            'name' => 'multiselect_field_example',
            'label' => 'LBL_MULTISELECT_FIELD_EXAMPLE',
            'type' => 'multienum',
            'module' => 'Accounts',
            'help' => 'Multi-Enum Field Help Text',
            'comment' => 'Multi-Enum Field Comment Text',
            'ext1' => 'account_type_dom', //maps to options - specify list name
            'default_value' => 'Analyst', //key of entry in specified list
            'mass_update' => false, // true or false
            'required' => false, // true or false
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
            'duplicate_merge' => false, // true or false
        ),
        //Checkbox
        array(
            'name' => 'checkbox_field_example',
            'label' => 'LBL_CHECKBOX_FIELD_EXAMPLE',
            'type' => 'bool',
            'module' => 'Accounts',
            'default_value' => true, // true or false
            'help' => 'Bool Field Help Text',
            'comment' => 'Bool Field Comment',
            'audited' => false, // true or false
            'mass_update' => false, // true or false
            'duplicate_merge' => false, // true or false
            'reportable' => true, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
        ),
        //Date
        array(
            'name' => 'date_field_example',
            'label' => 'LBL_DATE_FIELD_EXAMPLE',
            'type' => 'date',
            'module' => 'Accounts',
            'default_value' => '',
            'help' => 'Date Field Help Text',
            'comment' => 'Date Field Comment',
            'mass_update' => false, // true or false
            'required' => false, // true or false
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'duplicate_merge' => false, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
        ),
        //DateTime
        array(
            'name' => 'datetime_field_example',
            'label' => 'LBL_DATETIME_FIELD_EXAMPLE',
            'type' => 'datetime',
            'module' => 'Accounts',
            'default_value' => '',
            'help' => 'DateTime Field Help Text',
            'comment' => 'DateTime Field Comment',
            'mass_update' => false, // true or false
            'enable_range_search' => false, // true or false
            'required' => false, // true or false
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'duplicate_merge' => false, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
        ),
        //Encrypt
        array(
            'name' => 'encrypt_field_example',
            'label' => 'LBL_ENCRYPT_FIELD_EXAMPLE',
            'type' => 'encrypt',
            'module' => 'Accounts',
            'default_value' => '',
            'help' => 'Encrypt Field Help Text',
            'comment' => 'Encrypt Field Comment',
            'reportable' => true, // true or false
            'audited' => false, // true or false
            'duplicate_merge' => false, // true or false
            'importable' => 'true', // 'true', 'false' or 'required'
        ),
    );

    require_once('ModuleInstall/ModuleInstaller.php');
    $moduleInstaller = new ModuleInstaller();
    $moduleInstaller->install_custom_fields($fields);

Add labels for custom fields by creating a corresponding language extension file:

./custom/Extension/modules/Accounts/Ext/Language/en_us.<name>.php

  <?php

    $mod_strings['LBL_TEXT_FIELD_EXAMPLE'] = 'Text Field Example';
    $mod_strings['LBL_DROPDOWN_FIELD_EXAMPLE'] = 'DropDown Field Example';
    $mod_strings['LBL_CHECKBOX_FIELD_EXAMPLE'] = 'Checkbox Field Example';
    $mod_strings['LBL_MULTISELECT_FIELD_EXAMPLE'] = 'Multi-Select Field Example';
    $mod_strings['LBL_DATE_FIELD_EXAMPLE'] = 'Date Field Example';
    $mod_strings['LBL_DATETIME_FIELD_EXAMPLE'] = 'DateTime Field Example';
    $mod_strings['LBL_ENCRYPT_FIELD_EXAMPLE'] = 'Encrypt Field Example';

Finally, navigate to Admin > Repair > Quick Repair and Rebuild to make the new field available for users.

Using the Vardef Extensions

You should try to avoid creating your own custom fields using the vardefs as there are several caveats:

  • If your installation does not already contain custom fields, you must manually create the custom table. Otherwise, the system will not recognize your field's custom vardef. This situation is outlined in the following section.
  • You must run a Quick Repair and Rebuild and then execute the generated SQL after the vardef is installed.
  • You must correctly define the properties of a vardef. If you miss any, the field may not work properly.
  • Your field name must end with "_c" and have the property 'source' set to 'custom_fields'. This is required as you should not modify core tables in Sugar and it is not permitted on Sugar's cloud service.
  • Your vardef must specify the exact indexes of the properties you want to set. For example, use:  $dictionary['<module singular>']['fields']['example_c']['name'] = 'myfield_c'; instead of $dictionary['<module singular>']['fields']['example_c'] = array(['name' => 'myfield_c');. This will help prevent the system from losing any properties when loading from the extension framework.

The initial challenge when creating your own custom vardef is getting the system to recognize the vardef and generate the database field. This issue is illustrated with the example below:

./custom/Extension/modules/<module>/Ext/Vardefs/<file>.php

  <?php

$dictionary['<module singular>']['fields']['example_c']['name'] = 'example_c';
$dictionary['<module singular>']['fields']['example_c']['vname'] = 'LBL_EXAMPLE_C';
$dictionary['<module singular>']['fields']['example_c']['type'] = 'varchar';
$dictionary['<module singular>']['fields']['example_c']['enforced'] = '';
$dictionary['<module singular>']['fields']['example_c']['dependency'] = '';
$dictionary['<module singular>']['fields']['example_c']['required'] = false;
$dictionary['<module singular>']['fields']['example_c']['massupdate'] = '0';
$dictionary['<module singular>']['fields']['example_c']['default'] = '';
$dictionary['<module singular>']['fields']['example_c']['no_default'] = false;
$dictionary['<module singular>']['fields']['example_c']['comments'] = 'Example Varchar Vardef';
$dictionary['<module singular>']['fields']['example_c']['help'] = '';
$dictionary['<module singular>']['fields']['example_c']['importable'] = 'true';
$dictionary['<module singular>']['fields']['example_c']['duplicate_merge'] = 'disabled';
$dictionary['<module singular>']['fields']['example_c']['duplicate_merge_dom_value'] = '0';
$dictionary['<module singular>']['fields']['example_c']['audited'] = false;
$dictionary['<module singular>']['fields']['example_c']['reportable'] = true;
$dictionary['<module singular>']['fields']['example_c']['unified_search'] = false;
$dictionary['<module singular>']['fields']['example_c']['merge_filter'] = 'disabled';
$dictionary['<module singular>']['fields']['example_c']['calculated'] = false;
$dictionary['<module singular>']['fields']['example_c']['len'] = '255';
$dictionary['<module singular>']['fields']['example_c']['size'] = '20';
$dictionary['<module singular>']['fields']['example_c']['id'] = 'example_c';
$dictionary['<module singular>']['fields']['example_c']['custom_module'] = '';
//required to create the field in the _cstm table
$dictionary['<module singular>']['fields']['example_c']['source'] = 'custom_fields';

Once the vardef is in place, determine whether the custom field's module already contains any other custom fields. If there are not any existing custom fields, create a corresponding record in fields_meta_data that will trigger the comparison process.

  INSERT INTO fields_meta_data (id, name, vname, comments, custom_module, type, len, required, deleted, audited, massupdate, duplicate_merge, reportable, importable) VALUES ('<module>example_c', 'example_c', 'LBL_EXAMPLE_C', 'Example Varchar Vardef', '<module>', 'varchar', 255, 0, 0, 0, 0, 0, 1, 'true');

Finally, navigate to Admin > Repair > Quick Repair and Rebuild. The system will then rebuild the extensions. After the repair, you will notice a section at the bottom stating that there are differences between the database and vardefs. Execute the scripts generated to create theSave custom field:

Missing <module>_cstm Table:

  /*Checking Custom Fields for module : <module>*/

CREATE TABLE <module>_cstm (id_c char(36)  NOT NULL  , PRIMARY KEY (id_c)) CHARACTER SET utf8 COLLATE utf8_general_ci;

Missing Columns:

  /*MISSING IN DATABASE - example_c -  ROW*/

ALTER TABLE <module>_cstm add COLUMN example_c varchar(255)  NULL ;