Is there a way to group options in a selectList

Is there a way to group options in an apex:selectList

I have in my page

      <apex:selectList styleclass="form-control rec" size="1" id="country"  >
              <apex:selectOption itemValue="" itemLabel="--Please Select--"/>
              <apex:selectOptions value="{!CountryName}" />
              <apex:actionSupport event="onchange"  reRender=""/>
      </apex:selectList>

In the controller I have

   public List<SelectOption> getCountryName(){
      List<SelectOption> options = new List<SelectOption>();

      for(Country__c con :[select Id,Name from Country__c where Region__c=:'Americas' order by Name]){
      options.add(new SelectOption(con.Name,con.Name));
      }

Is there a way I can group the selectOptions based on region like with a grouping label
similar to html <optgroup label="Americas">

Also is it possible to do something like the below code in case I’m not able to group them using salesforce

 <select id="country" >
    <option value="">--Please Select--</option>
    <optgroup label="Americas">
    <apex:selectOptions value="{!CountryName}" />
     </optgroup>
  </select>

Answer

If you make a small change to your controller’s getter method so that the Label value of the option element includes the region in each label, you can then use javascript to build the <optgroup /> elements for you in the page:

public List<SelectOption> getCountryName(){
    List<SelectOption> options = new List<SelectOption>();

    for(Country__c country : [SELECT Id
                                    , Name 
                                    , Region__c
                                FROM Country__c 
                                ORDER BY country.Region__c, Name 
                                LIMIT 1000]) {
        options.add(new SelectOption(country.Name, String.format('{0}_{1}', country.Region__c, country.Name})));
    }

    return options;
}

Using the jQuery library in your page you can use markup like this and achieve your result.

<apex:includeScript value="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" />

<apex:selectList styleclass="form-control rec" size="1" id="country"  >
    <apex:selectOption itemValue="" itemLabel="--Please Select--"/>
    <apex:selectOptions value="{!CountryName}" />
</apex:selectList>
<script>
    // Relinquish jQuery's control of the $ variable
    jQuery.noConflict();

    (function (componentName) {
        // get a reference to the select component in the page
        var selectList = jQuery('[id="' + componentName + '"]');

        // a javascript object to collect the elements in each region
        var regions = {};

        // iterate all of the options and collect them by region
        jQuery('option', selectList).each(function (i) {
            if (i === 0) {
                return; // skip the first element in the list
            }
            var oElement = jQuery(this);
            var regionCountryArray = oElement.text().split('_');

            // create an array entry for the region name if there is not one
            if (!regions[regionCountryArray[0]]) {
                regions[regionCountryArray[0]] = [];
            }

            // add the item to the array for this region
            regions[regionCountryArray[0]].push(oElement);
        });

        // iterate all of the names in the regions object
        for (var region in regions) {

            // make sure the name did not come from the prototype
            if (regions.hasOwnProperty(region)) {

                // turn the array of items into a single jQuery collection
                var groupElements = jQuery(regions[region]).map(function () {
                    return this.toArray();
                });

                // create the group and set the label
                var optgroup = jQuery('<optgroup/>');
                optgroup.attr('label', region);

                // wrap the option elements in an optgroup
                groupElements.wrapAll(optgroup);

                // remove the region text from the label
                groupElements.each(function () {
                    jQuery(this).text(function () {
                        return jQuery(this).text().replace(region + '_', '');
                    });
                });
            }
        }
    })('{!$Component.country}'); // immediate function execution - pass in the id of the select list
</script>

Before & After (using country and state/province)


Before After

Attribution
Source : Link , Question Author : raym0nd , Answer Author : Mark Pond

Leave a Comment