[SalesForce] reuse the dependency logic of State and Country picklists from Account/Contact in a Apex Classes

I have enabled the State and Country picklists in Salesforce and
I was trying to get/create the same kind of country and state picklist with dependency from Contact in a visual force page.

I have done the below steps:

From the controller i tried to create the country and state picklists in the custom visual force page.

Add Contact Visual force Page:

<apex:page StandardController="CustomObject__c" extensions="AddContactController">
<apex:form >
    <apex:pageBlock title="Add Contact" mode="edit">
        <apex:pageBlockButtons >
            <apex:commandButton action="{!save}" value="Save"/>
        </apex:pageBlockButtons>
        <apex:pageBlockSection title="Contact Details" columns="2">
              <apex:selectList id="states" value="{!myContact.MailingState}" size="1" required="false">
              <apex:selectOptions value="{!states}"/>
            </apex:selectList>
              <apex:selectList id="countries" value="{!myContact.MailingCountry}" size="1" required="true">
              <apex:selectOptions value="{!countries}"/>
            </apex:selectList>
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:form>

AddContactController Apex Class

public class AddContactController {
ApexPages.StandardController stdCtrl;
public Contact myContact{ get; private set;}

public AddContactController(ApexPages.StandardController std) {
    stdCtrl = std;
    myContact = new Contact();
}   
public List<SelectOption> countries { get{ return getCountries(); }set; }
public List<SelectOption> states{ get{ return getStates(); }set; }

public List<SelectOption> getCountries()
{
  Schema.sObjectType objType = Contact.getSObjectType();
  Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
  map<String, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();
  list<Schema.PicklistEntry> values = fieldMap.get('MailingCountryCode').getDescribe().getPickListValues();

  List<SelectOption> options = new List<SelectOption>();
  for (Schema.PicklistEntry v : values){
    options.add(new SelectOption(v.getValue(), v.getLabel()));
  };
  return options;
}

public List<SelectOption> getStates()
{
  Schema.sObjectType objType = Contact.getSObjectType();
  Schema.DescribeSObjectResult objDescribe = objType.getDescribe();
  map<String, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();
  list<Schema.PicklistEntry> values = fieldMap.get('MailingStateCode').getDescribe().getPickListValues();
  List<SelectOption> options = new List<SelectOption>();
  for (Schema.PicklistEntry v : values){
    options.add(new SelectOption(v.getLabel(), v.getvalue()));
  };
  return options;
}}

The above code populates the entire countries and states in the custom visual force page from the Contact State/Country picklists but doesn't have dependency on the country and state.

Is there any way to get the dependency and by country onchange i could show respective states in custom visual force page instead of manually configuring the dependency or using external packages(Provenworks).

Thanks in advance .

Best Answer

State and Country picklist metadata is only available as of Winter 17 via the MetaData API

Documentation on the metadata API for the object AddressSettings is here.

Apex wrapper for the Metadata API is available on GitHub

Idea to make this more accessible from APEX directly without requrinig a callout can be found here. SFDC has announced they are starting to develop this!

So, you have a bit of work to do to query this and exploit in a VF page