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)
Attribution
Source : Link , Question Author : raym0nd , Answer Author : Mark Pond