The Dependent Picklist feature in Salesforce is an incredibly powerful tool for keeping data clean and organized. Through setting up relationships between different fields, an Admin can filter available values in certain picklists based on the value of other fields.
Unfortunately, many Admins discover that, despite configuring dependent picklists for objects like Leads, that functionality disappears as soon as they generate a Web-to-Lead form.
Wouldn’t it be great to maintain that data cleanliness in the Leads generated by those that fill out your HTML forms? Turns out the code necessary for this is pretty straightforward.
Let’s assume that our Lead data model includes a dependent custom picklist called “Lead Source Detail”, and the controlling field is the standard “Lead Source” field. Our goal is to make it so that when a user selects a specific value from “Lead Source”, we want the available values in “Lead Source Detail” to be filtered. We’d also like Other
to show up as an option in each of the different Lead Source buckets.
This will be accomplished with some simple JavaScript. But, let’s take a look at the HTML first.
Note: The hidden fields for things like “Org ID” and “Return URL” have been left off for brevity’s sake. Just know that this form won’t work without including your specific Org ID field and Return URL field.
<form action="https://webto.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">
<div class="field">
<label for="lead_source">Lead Source</label>
<select id="lead_source" name="lead_source" title="Lead Source">
<option value="">--None--</option>
<option value="Conference">Conference</option>
<option value="Referral">Referral</option>
<option value="Web">Web</option>
<option value="Other">Other</option>
</select>
</div>
<div class="field">
<label for="00N6g00000TPCXY">Lead Source Detail</label>
<select id="00N6g00000TPCXY" name="00N6g00000TPCXY" title="Lead Source Detail">
<option value="">--None--</option>
<option value="Dreamforce">Dreamforce</option>
<option value="SnowForce">SnowForce</option>
<option value="Advisor">Advisor</option>
<option value="Customer">Customer</option>
<option value="Employee">Employee</option>
<option value="Partner">Partner</option>
<option value="Recruiter">Recruiter</option>
<option value="VC">VC</option>
<option value="Previous Customer">Previous Customer</option>
<option value="Contact Us">Contact Us</option>
<option value="Demo">Demo</option>
<option value="Trial">Trial</option>
<option value="Webinar">Webinar</option>
<option value="LinkedIn">LinkedIn</option>
<option value="Other">Other</option>
</select>
</div>
<input type="submit" name="submit" />
</form>
Note: The groupings for the option values in the Lead Source Detail select list are separated by a new line.
The brains of the filtering can be found in this small JavaScript snippet.
<script>
const leadSourceDetailOptions = {
Conference: ['Dreamforce', 'SnowForce', 'Other'],
Referral: [
'Advisor',
'Customer',
'Employee',
'Partner',
'Recruiter',
'VC',
'Previous Customer',
'Other',
],
Web: ['Contact Us', 'Demo', 'Trial', 'Webinar', 'LinkedIn', 'Other'],
Other: ['Other'],
};
function removeLeadSourceDetailOptions() {
const detailSelect = document.getElementById('00N6g00000TPCXY');
const options = detailSelect.querySelectorAll('option');
if (options && options.length > 0) {
options.forEach((option) => {
option.remove();
});
}
}
function createNoneOption() {
const option = document.createElement('option');
option.textContent = '--None--';
option.value = '';
return option;
}
function filterOptions() {
removeLeadSourceDetailOptions();
const leadSourceSelect = document.getElementById('lead_source');
const leadSourceSelectOptions = leadSourceSelect.options;
const selectedOption = leadSourceSelectOptions[leadSourceSelect.selectedIndex];
if (selectedOption && selectedOption.value && leadSourceDetailOptions[selectedOption.value]) {
let options = leadSourceDetailOptions[selectedOption.value].map((opt) => {
const el = document.createElement('option');
el.textContent = opt;
el.value = opt;
return el;
});
options = [createNoneOption()].concat(options);
const leadSourceDetailSelect = document.getElementById('00N6g00000TPCXY');
options.forEach((opt) => {
leadSourceDetailSelect.appendChild(opt);
});
}
}
document.getElementById('lead_source').addEventListener('change', () => {
filterOptions();
});
removeLeadSourceDetailOptions();
</script>
The main points to note here are the following:
- You need to know your buckets beforehand (which can be found in the
leadSourceDetailOptions
object declared at the top of the script) - We attach an
onchange
event listener to the “Lead Source” select list, which runs thefilterOptions
function each time the value for “Lead Source” changes. - Using those predefined buckets, the
filterOptions
function removes and rebuilds the options for the “Lead Source Detail” select list - Though the "Lead Source Detail" select list is pre-populated with all of the options, we remove all options on page load via the
removeLeadSourceDetailOptions
function- We also use this function whenever the value in the "Lead Source" select list changes.
Hi There,
Awesome article, thanks for sharing. I have couple questions. How do I use the Java Script to pass values? I`m new to developer side of Salesforce and not proficient with Apex.