Inter-field communication: dynamic states dropdown depending on a country dropdown

Inter-field communication: dynamic states dropdown depending on a country dropdown

Posted on February 09, 2012 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

Field controls are a powerful instrument when editing data in the Sitefinity backend. Sometimes however you need to change a list of possible choices in a field control depending on another field control. This blog post describes how to implement a Country and State dropdown field controls, where the State dropdown depends on the current selection of the Country dropdown. Since this is just a tutorial we will limit the countries to three - USA, Canada and Bulgaria. The first two allow the selection of states, while the last one doesn't.

Let's start by adding a multiple choice field for the Country. This will be a regular multiple choice field with three choices - the mentioned countries. Let's add this field to the News. In the "Add a field" dialog select Type - Multiple choice, Name - Country, leave the other choices intact and on the next screen enter the countries like this -

Country field settings

Click Done and Save changes. By default multiple choice fields are rendered as Radio button list. In this case we will need a Dropdown instead. To change this behaviour go to Administration -> Settings -> Advanced -> News -> Controls -> NewsBackend -> Views -> NewsBackendEdit -> Sections -> CustomFieldsSection -> Fields -> Country and there set RenderChoiceAs to DropDown. While we are here we will assing a unique ID for this control, that later on we'll use in the State field. For the sake of this tutorial let's set the ID property to Country. Save the changes and go back the News module.

Now we need a custom dropdown field for the states that will get refreshed when the currently selected country is changed. The StateField, StateFieldDefinition and StateFieldElement classes may be found in the attached project. The basic idea is that we preload a list of USA and Canadian states on the client side, as arrays, and later on we monitor the onchange event of the Country field. In thr initialize() function of the field client-side script we get a reference to the Country dropdown like this

this._countriesDropDown = jQuery("select[id*='Country']");

The select[id*='Country'] jQuery selector retrieves a select element that partially contains the string Country in its id attribute. If you have doubts there might be other select elements like this you can specify a more unique ID attribute in the step where we created the Country field.

The next step is to attach to the onchange event of the Country dropdown using this code

this._countriesDropDownChangedDelegate = Function.createDelegate(this, this._countriesDropDownChangedHandler);
this._countriesDropDown.change(this._countriesDropDownChangedDelegate);

The handler for the change event looks like this

_countriesDropDownChangedHandler: function (e) {
    this._fillStates();
}

where the _fillStates() method looks like this

_fillStates: function () {
    var selectedCountry = this._countriesDropDown.attr("value");
 
    this._dropDown.options.length = 0;
    this._dropDown.options[0] = new Option("[ Select a state ]", "");
 
    switch (selectedCountry) {
        case "USA":
            this._dropDown.disabled = false;
            for (var i = 0, l = this._usaStates.length; i < l; i++) {
                this._dropDown.options[this._dropDown.options.length] = new Option(this._usaStates[i], this._usaStates[i]);
            }
            break;
        case "Canada":
            this._dropDown.disabled = false;
            for (var i = 0, l = this._canadianStates.length; i < l; i++) {
                this._dropDown.options[this._dropDown.options.length] = new Option(this._canadianStates[i], this._canadianStates[i]);
            }
            break;
        default:
            this._dropDown.disabled = true;
    }
}
As you can see for countries other than USA and Canada we simply disable the States dropdown.

Now the only thing left to do is to implement the field control's set_value(value) client-side method, so it properly initializes the State dropdown, depending on the value in the Country dropdown. Here is the implementation of the method

set_value: function (value) {
    if (this._countriesDropDown) {
        this._fillStates();
        this._value = value;
 
        if (value)
            this._dropDown.value = value;
 
        this.raisePropertyChanged("value");
        this._valueChangedHandler();
    }
}
We verify if this._countriesDropDown has been properly initialized and if yes we prefill the possible states and then select the state that is actually selected.

Now we can go back to the custom fields in News and add the State field. In the Add a field dialog specify

Type - Multiple choice
Name - State
Interface widget for entering data - Custom...
Type or Virtual path of the custom widget - CustomFields.StateField

Click Continue and in the next screen leave just one possible choice - this choice will not be used anyway, but we need to have at least one here. Now we need to change again the rendering of this field to be DropDown instead of RadioButtons - again go to Administration -> Settings -> Advanced -> News -> Controls -> NewsBackend -> Views -> NewsBackendEdit -> Sections -> CustomFieldsSection -> Fields -> State and change the RenderChoiceAs property to DropDown. Save the changes and go to edit a News item. When you change the current country selection the States dropdown will dynamically preload or even disable if you pick a country without states

Bulgaria country states 

This concludes this blog post. And here is the project with the source code. Do not forget to register a virtual path with the following settings -

VirtualPath - ~/CustomFields/*
ResourceLocation - CustomFields
ResolverName - EmbeddedResourceResolver

State Field Control Project 

progress-logo

The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation