HOWTO: Have a dropdown field that get's it's options from a function.

bsoremsugar —  August 24, 2011 — 62 Comments

Typically in the app, most of the dropdown fields options are driven by array strings defined in the various language files for the application. But what if you are looking to have your dropdowns be more dynamic, you can also have functions which grab this data and pass it into the field as the dropdown options. Here’s how:

First, you’ll want to pull together your dropdown options from a function. It should return back an associative array of values, with the array key as the value to be stored in the database field and the value to be what is displayed to the user. So for example, if you wanted your dropdown to have a list of Active Releases, you could build a function like this:

<?php

function getActiveReleases()
{
    $query = "SELECT id, name FROM releases where deleted=0 and status='Active' order by list_order asc";
    $result = $GLOBALS['db']->query($query, false);

    $list = array();
    $list['']='';
    while (($row = $GLOBALS['db']->fetchByAssoc($result)) != null) {
        $list[$row['id']] = $row['name'];
    }

    return $list;
}

Next, change the field def for the field, and remove the ‘options’ attribute and instead a ‘function’ attribute, as shown below:

unset($dictionary['MODULENAME']['fields']['FIELDNAME']['options']);
$dictionary['MODULENAME']['fields']['FIELDNAME']['function'] = 'getActiveReleases';

With that, your dropdown will be powered by a dynamic database table instead of a static array. You can use the same technique to have it powered by a web service, a relative calculation ( such as today, tomorrow, 3 days from now ), or something else just by returning an associative array of items from a function.

62 responses to HOWTO: Have a dropdown field that get's it's options from a function.

  1. 

    Ha, this will make an upcoming project much easier for us. Thanks, John. I knew this was possible but I thought it would be a hack; this is a very nice and straight-forward solution.

  2. 

    Looks nice, but where to put that code?

    • 

      One place would be custom/include/custom_utils.php, or you could also stick it in a .php file in the custom/Extension/application/Ext/Utils/ directory and do and do a quick rebuild and repair.

      • 

        Where is the documentation for custom/Extension/application/Ext/Utils/ or custom/include/custom_utils.php

        Do function in either both of these get included automatically?
        neither is referenced in any document!

        • 

          Functions in these files do get pulled in automatically. You are right, this isn’t documented, but should be. Sounds like another great developer blog post :-).

          • 

            I added a directory custom/Extension/application/Ext/Utils (using 6.2.1) and did a Repair and Rebuild and the file did not put the file anywhere.

            • 

              Try again in 6.3.1 or later, should work there.

              • 

                Iam using 6.4.1. I created a file “custom_utils.php” in “custom/include/” and added the function. It worked fine. My dropdown populated its items from the database. Now the problem is, all the remaining dropdowns have become empty. I guess , since i created custom_utils.php, i must customize all the pre-defined fields. Is there any other way i can achieve my goal (Populating dropdown values from databse)? in between, what is the name of the .php file i have to create in custom/Extension/application/Ext/Utils/ directory.

          • 

            A couple of years ago I asked on forum for both Application and Developer Guides sources (I guess SugarCRM uses DocBook/XML to build guides) to let community create translations in different languages. May be it is a time to place sources on GitHub to fill guides with some still un-covered details?

  3. 

    very much like the functionality for EditView and DetailView, but it looks like on the ListView and via the Portal, the value isn’t re-evaluated to the language-file, but the database value (the array’s hash) is being displayed. Suggestions?

  4. 

    This is not working for me in Sugar Pro 6.4.2.

    I created the function in the ..customincludecustom_utils.php files:<?phpfunction getActiveTeams(){    $query = "select id, name from teams where private = '0' and name ‘Global'”;    $result = $this->db->query($query, false);    $list = array();    $list['']=”;    while (($row = $this->db->fetchByAssoc($result)) != null) {        $list[$row['id']] = $row['name'];    }    return $list;}?>

    I then created a new file called ..customExtensionmodulesCasesExtVardefsaction_team_c_function.php:

    When I run a Quick Repair I get this error:
    Fatal error: Cannot unset string offsets in ..custommodulesCasesExtVardefsvardefs.ext.php on line 5 

    If I comment that line out I can Repair successfully, but when I try to edit my case I get this error:
    Fatal error: Using $this when not in object context in C:xampplitehtdocsSugarPro642customincludecustom_utils.php on line 6 

    Am I putting my code in the wrong spot or does it no longer work in 6.2.4?

    Thank you,
    Justin

    • 

       The code above is a bit manged; could you post a Gist or pastebin link with the code instead?

      • 
        Justin Kuehlthau March 20, 2012 at 3:54 pm

        ..customincludecustom_utils.php:
        git://gist.github.com/2140563.git 
        and
        ..customExtensionmodulesCasesExtVardefsaction_team_c_function.php:
        git://gist.github.com/2140584.git 

        • 

          Try wrapping an if ( is_array($dictionary['Case']['fields']['action_team_c']) && isset($dictionary['Case']['fields']['action_team_c']['options']) ) { … } around the unset() call to test for the setting being set first.

          • 
            Justin Kuehlthau March 21, 2012 at 12:14 pm

            That code was still giving me an error:
            Fatal error: Cannot use string offset as an array in C:xampplitehtdocsSugarPro642custommodulesCasesExtVardefsvardefs.ext.php on line 5

            The only way it works is to use the single line to call the function.  See https://gist.github.com/2140584.

            I was getting this error with the custom_utils.php code:
            Fatal error: Using $this when not in object context in C:xampplitehtdocsSugarPro642customincludecustom_utils.php on line 6

            I was able to fix it by finding other examples where people used $focus instead of $this.  See https://gist.github.com/2140563.

            The dropdown on the edit and quickcreate screens seem to be working now.  Is there any issue with the way I have the code?

            An issue I’ve found is when you add the field to the Sugar Dashlet Search screen it displays the incorrect dropdown list.  The incorrect dropdown list is also displayed when creating a filter for a report.  Are these bugs in Sugar or does more customizations need to be done?

            Thank you!

  5. 
    Athanasios Alekizoglou March 21, 2012 at 1:51 pm

    Great post

  6. 
    Athanasios Alekizoglou March 21, 2012 at 1:53 pm

    Great post.
    The $this in  $this->db->query($query, false);
    is not a know variable. 
    On other question is where do you put the $dictionary['MODULENAME']['fields']['FIELDNAME']['function'] = ‘getActiveReleases';
    if you put this in module’s vardef.ext.php this will be overridden every time you do a rebuild, or add/remove a field.

  7. 

    where to define this function ?? in which file

  8. 

    Could such a thing be accomplished for multi-select fields too?

  9. 

    Used this method to customize a custom field in the Leads module (v6.3.1 CE). Works great!! BUT, how can I use this same function I created in the Leads Import Wizard to select a default value for my custom field? That dropdown is still using the edited text file, not my Sugar function DB select.

    Thanks!!

    • 

      Hard to say without seeing the code. Could you share it?

      • 

        I created a function in custom/Extention/application/Ext/Utils/ called Dropdowns.php containing the function (as described above):

        function getSourceCodes()
        {
        $query = “SELECT code, description FROM abd_dropdowns where dropdown = ‘source_code’ and active = 1 order by description”;
        $result = $GLOBALS['db']->query($query, false);

        $list = array();
        $list['']=”;
        while (($row = $GLOBALS['db']->fetchByAssoc($result)) != null) {
        $list[$row['code']] = $row['description'];
        }

        return $list;
        }

        I created custom/Extention/modules/Leads/Ext/Vardefs/vardef.ext.php with the following line of code:

        $dictionary["Lead"]["fields"]["source_code_c"]["function"] = ‘getSourceCodes';

        This works great in Search and Editview, but is not being used in the Import Wizard. Ideas?

        Thanks!!!

  10. 
    gaëlle fernandez October 15, 2012 at 5:44 am

    hi!
    Great Post, thanks John!

    where do we put the unset($dictionary[])? i have a custom field which i want to use a dynamic dropdown… (not with a database but, well, if we can use functions, i believe everything possible)

    Thanks!

    • 

      Add it in a new .php file in the custom/Extention/modules/<>/Ext/Vardefs/ directory.

      • 
        gaëlle fernandez October 15, 2012 at 9:55 am

        thank you!! :) i wrote it into custom/modules/myModule/Ext/Vardefs/vardefs.ext.php and it works reaally great!
        now, another question, please : my function filling the dropdown returns an array. when i click on a choice on my dropdown, i would like to get the value and not the key, to register in base…do you know how i can do that, please?

        • 

          As long as you return an associative array, the key should be the DB value and the value what is displayed.

          • 
            gaëlle fernandez October 15, 2012 at 10:31 am

            okay, i understand.. but my dropdown is made like this : i use RecursiveDirectoryIterator to browse a folder and get the different subfolders. It is always changing. So, how can i always get the value instead of the keys, which will ever change?

  11. 

    Hi, just came across this article. This is exactly what I want to do. But the problem I have is that after I create a customincludeutilscustom_utils.php and define my getPidDropdown function, then put
    unset($dictionary['MODULENAME']['fields']['FIELDNAME']['options']);

    $dictionary['MODULENAME']['fields']['FIELDNAME']['function'] = ‘getPidDropdown';

    in my customextensionmodulesmy moduleextvardefsvardefs.php

    repair and rebuild. then if I click on my module, there is no listview, click on create, no editview either. Anyone has any idea what I did wrong?

  12. 

    Works like a charm but when I use the dropdown in massupdate it won’t display any values. Any thoughts on how to fix that? Thanks.

  13. 

    I <3 it……….. ThaNk YOu So MuCh… :)

  14. 

    These will not work in Dashlet SearchFields. Bug reported: http://www.sugarcrm.com/support/bugs.html#issue_60823

  15. 

    pleaseeeee say me where i can add this function and how can i relationship with my array in editview.

    • 

      The function can be anywhere in the include path, but ideally you should look to stick in in a new php file in the custom/application/Ext/Utils/ folder

      • 

        thanks John, but i search this code:

        ‘function’ => array(‘name’=>’myFunctionName’, ‘returns’=>’html’,
        ‘include’=>’modules/myModuleOrMyOtherModule/my_file_name.php’),

        my_file_name.php

        this lane is for add a external function in your field. :)

        And other question is how can i insert my load data in enum I have this code:

        function getCategorias($focus, $name, $value, $view = ‘EditView’)

        {

        $array_final = array();

        $array_final = getDataCategory(“act_Category”, “”, “admin”, “adminadmin”); // this method obtain all categories of my category modules.

        for ($i = 0; $i < sizeof($array_final['entry_list']); $i++) {
        $array_name_categorias .= $array_final['entry_list'][$i]['name_value_list'][0]['value'];
        }

        return encodeMultienumValue($array_name_categorias);

        }

        When i use this code i obtain blank multienum :( what it is wrong in this code?

        • 

          this is the function:

        • 

          I have the solution :), but a lot of thanks.

          $html = ”;

          $html = ”;

          for ($i = 0; $i < sizeof($array_final['entry_list']); $i++) {

          $html .= '’

          .$array_final['entry_list'][$i]['name_value_list'][0]['value'].”;

          }

          $html .= ”;

          return $html;

  16. 

    please answer myyyyy

  17. 

    IMPORTANT:

    After hours and hours of struggle:

    $dictionary["Lead"]["fields"]["source_code_c"]["function"] = ‘getSourceCodes’;

    See the interesting thing? The module name MUST be in Singular, not plural. Thus “Lead” not “Leads”.

  18. 

    Great post.

    Do you know if we can have a parameter passed to this function?

    Essentially, I have two dropdowns in a custom module which should have a parent child relation. Right now both dropdowns work great, but it will be awesome if we can filter the second dropdown based on the first one’s value.

Trackbacks and Pingbacks:

  1. How to remove drop-down choices... wisely? - SugarCRM Forums - August 29, 2011

    [...] [...]

  2. SugarCRM Developer Blog » Blog Archive » HOWTO: Adding your own global functions - September 6, 2011

    [...] love it when one blog post leads to another. This time, it was a post about having a dropdown powered by a function rather than the normal array of static option, where [...]

  3. Programmatically change the content of dropdown - SugarCRM Forums - January 18, 2012

    [...] [...]

  4. Accessing Field Data on Current Record - SugarCRM Forums - January 20, 2012

    [...] [...]

  5. SugarCRM Developer Blog » Blog Archive » HOWTO: More options with dropdown fields that get values from a function - March 8, 2012

    [...] summer I thru together this post which talked about using a function to supply the values for a dropdown rather than having them come [...]

  6. Multienum search field in related module - April 16, 2012

    [...] [...]

  7. Function to populate enum values from a database table - July 2, 2012

    [...] [...]

  8. Custom multiselect problem - August 2, 2012

    [...] [...]

  9. What's the best way to relate to a Target List? - August 14, 2012

    [...] [...]

  10. Create a product list in custom module - October 9, 2012

    [...] [...]

  11. One dropdown effect another dropdown values - March 24, 2013

    [...] [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s