As far as your entities go, you should make sure of the following:
Your City Entity, should contain a lookup to the State Entity
Your State Entity, should contain a lookup to the Country Entity.
This means that when your users select the city and click on state, only the available state will appear there. After the state is selected, only the country of that state will appear there.
In order for this to work, you need to set the Related Records Filtering of the State and Country lookup controls on your form:
In the State field, click on Change Properties, and on the Display Tab in the Related Records Filtering click on Only Show records where, and select City (Accounts) contains City (State).
Follow the same logic for country field.
If you need to do this dynamically, you probably need to use webapi.
You can use the following webapi library and add it as a web resource to your solution and account form:
www.zacrmguy.com/js-crud-operations-with-web-api-in-crm-2016
The following is just sample code on how you can achieve that. You will need to modify it as needed, but it should work.
In the cityOnChangeEvent
var cityId = removeBraces(getLookupId("new_cityid"));
getStateId(cityId);
function getStateId(cityId)
{
var query = "_newstateid_value";
Sdk.WebApi.retrieveRecord(cityId, "new_city", query, "",
function (result) {
var stateId = result._newstateid_value;
retrieveState(stateid);
},
function (error) {
alert(error);
})
}
function retrieveState(stateId)
{
var query = "new_stateid,new_statename,_newcountryid_value";
Sdk.WebApi.retrieveRecord(stateId, "new_state", query, "",
function (result) {
var stateName = result.new_statename;
setLookupField("new_stateid", stateId, stateName, "new_state");
var countryId = result._newcountryid_value;
retrieveCountry(countryid);
},
function (error) {
alert(error);
})
}
function retrieveCountry(countryId)
{
var query = "new_countryid,new_countryname,_newcountryid_value";
Sdk.WebApi.retrieveRecord(stateId, "new_state", query, "",
function (result) {
var countryName = result.new_countryname;
setLookupField("new_countryid", countryId, countryName, "new_country");
},
function (error) {
alert(error);
})
}
function getLookupId(fieldName) {
var field = Xrm.Page.getAttribute(fieldName);
if (field != null) {
var fieldId = field.getValue();
if (fieldId != null)
return fieldId[0].id.toString();
else
return '';
}
}
function setLookupField(fieldName, lookupId, lookupName, entityName) {
var lookupData = new Array();
var lookupItem = new Object();
lookupItem.id = lookupId;
lookupItem.name = lookupName;
lookupItem.entityType = entityName;
lookupData[0] = lookupItem;
Xrm.Page.getAttribute(fieldName).setValue(lookupData);
}
function removeBraces(str) {
str = str.replace(/[{}]/g, "");
return str;
}