Similar to this question, but instead of in C#, I need it in Javascript:

Get lists of dependent picklist options in Apex

I already have the list of both the dependent values and the control values. How do I decode the validFor so I can use it?



Fruit, Vegetable, Dairy


(Fruit): Apple, Banana, Pear

(Vegetable): Tomato, Egglant, Lettuce

(Dairy): Milk, Cheese, Yogurt

What I'm Looking For

let picklistValues = [
    "active": true,
    "defaultValue": false,
    "label": "1111111111111",
    "validFor": "gfAA",
    "value": "1111111111111"
  ..... // many more
let controlValues = [
    "active": true,
    "defaultValue": false,
    "label": "aaaaaaaaaaaa",
    "validFor": null,
    "value": "aaaaaaaaaaaa"
let controlValue = "aaaaaaaaaaaa";
let validPicklistValues = getValidPicklistValues(controlValue, picklistValues, controlValues );

How do I decode validFor into a map that I can understand in Javascript?


To process them, you can use the same type of code you see in the documentation. Here's how I'd write this in ES5:

function testBit(bitmap, index) {
  // Given an 8-bit binary string, get the index / 8 character,
  // And convert the index % 8 bit to true or false
  return !!(bitmap.charCodeAt(index >> 3) & (128 >> (index % 8)));
function getValidPicklistValues(controlValue, dependentListValues, controllingValues) {
  // Figure out the index of the controlValue
  var index = controllingValues.indexOf(controllingValues.find(
      function(item) { return controlValue === item.value; }
  // Return a list of matching options given the control value
  return dependentListValues.filter(function(item) {
        // atob is base64-decoding.
        return testBit(atob(item.validFor), index);

Note that atob is a built-in for web browsers; if you're using a version of JavaScript that doesn't have a Window object, you'll need to base-64 decode the data yourself.


To whoever (like me) comes here from a similar question asking for the swift implementation, since that question is marked as duplicate and locked, here it goes in case it's useful to someone:

extension String {
    func leftPadding(toLength: Int, withPad character: Character) -> String {
        let stringLength = self.count
        if stringLength < toLength {
            return String(repeatElement(character, count: toLength - stringLength)) + self
        } else {
            return String(self.suffix(toLength))

var validFor = "gCAA"

let data = Data(base64Encoded: validFor)

let asStringOfBits = data?.reduce("") { (res, byte) -> String in
    let binaryRepresentation = String(byte, radix: 2)
    let padded = binaryRepresentation.leftPadding(toLength: 8, withPad: "0")
    return res + padded

let asIndexes: [Int] = asStringOfBits?.enumerated().compactMap { (e) -> Int? in
    return e.element == "1" ? e.offset : nil
} ?? []

//prints Optional("100000000010000000000000")

//prints [0, 10]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.