4

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?

Example

Controlling_Field__c

Fruit, Vegetable, Dairy

Dependent_Field__c

(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?

2 Answers 2

6

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.

0
2

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
} ?? []

print(asStringOfBits)
//prints Optional("100000000010000000000000")

print(asIndexes)
//prints [0, 10]

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .