Field Dependent 在Apex里使用control 和 dependent list-Picklist

Posted xiaobiubiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Field Dependent 在Apex里使用control 和 dependent list-Picklist相关的知识,希望对你有一定的参考价值。

当联动选择时,如第一个 checkbox or picklist选择后,自动筛选第二个对应的联动选项,如下两种方法(未实测):

 

 1 /*
 2 * Apex doesn‘t expose dependent picklist info directly, but it‘s possible to expose.
 3 * Approach:
 4 * * Schema.PicklistEntry doesn‘t expose validFor tokens, but they are there, and can be accessed by serializing to JSON
 5 * (and then for convenience, deserializing back into an Apex POJO)
 6 * * validFor tokens are converted from base64 representations (e.g. gAAA) to binary (100000000000000000000)
 7 * each character corresponds to 6 bits, determined by normal base64 encoding rules.
 8 * * The binary bits correspond to controlling values that are active - e.g. in the example above, this dependent option
 9 * is available for the first controlling field only.
10 * 
11 * by Benj Kamm, 2017
12 * CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0/us/)
13 */
14 public class HL_FieldDescribeUtil {
15 
16 public static Map<String, List<String>> getDependentOptionsImpl(Schema.SObjectField theField, Schema.SObjectField ctrlField) {
17 // validFor property cannot be accessed via a method or a property,
18 // so we need to serialize the PicklistEntry object and then deserialize into a wrapper.
19 List<Schema.PicklistEntry> contrEntries = ctrlField.getDescribe().getPicklistValues();
20 List<PicklistEntryWrapper> depEntries =
21 HL_FieldDescribeUtil.wrapPicklistEntries(theField.getDescribe().getPicklistValues());
22 
23 // Set up the return container - Map<ControllingValue, List<DependentValues>>
24 Map<String, List<String>> objResults = new Map<String, List<String>>();
25 List<String> controllingValues = new List<String>();
26 
27 for (Schema.PicklistEntry ple : contrEntries) {
28 String label = ple.getLabel();
29 objResults.put(label, new List<String>());
30 controllingValues.add(label);
31 }
32 
33 for (PicklistEntryWrapper plew : depEntries) {
34 String label = plew.label;
35 String validForBits = base64ToBits(plew.validFor);
36 for (Integer i = 0; i < validForBits.length(); i++) {
37 // For each bit, in order: if it‘s a 1, add this label to the dependent list for the corresponding controlling value
38 String bit = validForBits.mid(i, 1);
39 if (bit == ‘1‘) {
40 objResults.get(controllingValues.get(i)).add(label);
41 }
42 }
43 }
44 
45 return objResults;
46 }
47 
48 // Convert decimal to binary representation (alas, Apex has no native method :-(
49 // eg. 4 => ‘100‘, 19 => ‘10011‘, etc.
50 // Method: Divide by 2 repeatedly until 0. At each step note the remainder (0 or 1).
51 // These, in reverse order, are the binary.
52 public static String decimalToBinary(Integer val) {
53 String bits = ‘‘;
54 while (val > 0) {
55 Integer remainder = Math.mod(val, 2);
56 val = Integer.valueOf(Math.floor(val / 2));
57 bits = String.valueOf(remainder) + bits;
58 }
59 return bits;
60 }
61 
62 // Convert a base64 token into a binary/bits representation
63 // e.g. ‘gAAA‘ => ‘100000000000000000000‘
64 public static String base64ToBits(String validFor) {
65 if (String.isEmpty(validFor)) return ‘‘;
66 
67 String validForBits = ‘‘;
68 
69 for (Integer i = 0; i < validFor.length(); i++) {
70 String thisChar = validFor.mid(i, 1);
71 Integer val = base64Chars.indexOf(thisChar);
72 String bits = decimalToBinary(val).leftPad(6, ‘0‘);
73 validForBits += bits;
74 }
75 
76 return validForBits;
77 }
78 
79 
80 private static final String base64Chars = ‘‘ +
81 ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ‘ +
82 ‘abcdefghijklmnopqrstuvwxyz‘ +
83 ‘0123456789+/‘;
84 
85 
86 private static List<PicklistEntryWrapper> wrapPicklistEntries(List<Schema.PicklistEntry> PLEs) {
87 return (List<PicklistEntryWrapper>)
88 JSON.deserialize(JSON.serialize(PLEs), List<PicklistEntryWrapper>.class);
89 }
90 
91 public class PicklistEntryWrapper {
92 public String active {get; set;}
93 public String defaultValue {get; set;}
94 public String label {get; set;}
95 public String value {get; set;}
96 public String validFor {get; set;}
97 }
98 
99 }


 二:

/*
    Effect: Method takes a validFor string and tests it against a set of controlling indexes
    Postcondition: Returns a list of all controlling indexes for which the validFor string test True
*/
public List<Integer> testBits(String pValidFor,List<Integer> nList){
    List<Integer> results = new List<Integer>();
    //the list of bytes (not derived from n)
    List<Integer> pBytes = new List<Integer>();
    //multiply by 6 since base 64 uses 6 bits (not derived form n)
    Integer bytesBeingUsed = (pValidFor.length() * 6)/8;
    //will be used to hold the full decimal value (not derived from n)
    Integer pFullValue = 0;
    //must be more than 1 byte
    if (bytesBeingUsed <= 1)
        return results;
    //get the base64bytes
    for(Integer i=0;i<pValidFor.length();i++){
        //get currenct character value
        pBytes.Add((Base64CharCodes.get((pValidFor.Substring(i, i+1)))));
    }   
    //calculate the full decimal value
    for (Integer i = 0; i < pBytes.size(); i++)
    {
        Integer pShiftAmount = (pBytes.size()-(i+1))*6;//used to shift by a factor 6 bits to get the value
        pFullValue = pFullValue + (pBytes[i] << (pShiftAmount));
    }
    //now we don‘t want to always be declaring memory, so let‘s set the initial 
    //variables
    Integer bit;
    Integer targetOctet;
    Integer shiftBits;
    Integer tBitVal;
    Integer n;
    Integer nListSize = nList.size();
    for(Integer i=0; i<nListSize; i++){
        n = nList[i];
        //calculate the target bit for comparison
        bit = 7 - (Math.mod(n,8)); 
        //calculate the octet that has in the target bit
        targetOctet = (bytesBeingUsed - 1) - (n >> bytesBeingUsed); 
        //the number of bits to shift by until we find the bit to compare for true or false
        shiftBits = (targetOctet * 8) + bit;
        //& is to set the same set of bits for testing
        //shift to the bit which will dictate true or false
        //Math.Pow(2, shiftBits) == 2 << (shiftBits+1)
        tBitVal = ((Integer)(2 << (shiftBits-1)) & pFullValue) >> shiftBits;
        if (tBitVal==1)
            results.add(n);
    }
    return results;
}
public static Map<String,List<String>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        //get the string to sobject global map
        Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
        if (!Schema.getGlobalDescribe().containsKey(pObjName))
            return objResults;
        //get the type being dealt with
        Schema.SObjectType pType = Schema.getGlobalDescribe().get(pObjName);
        return GetDependentOptionsImpl(pType,pControllingFieldName,pDependentFieldName);        
    }
    public static Map<String,List<String>> GetDependentOptionsImpl(Schema.SObjectType pType, String pControllingFieldName, String pDependentFieldName){
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        if (pType==null)
            return objResults;
        TStringUtils.Bitset BitSetInstance = new TStringUtils.Bitset();
        Map<String, Schema.SObjectField> objFieldMap = pType.getDescribe().fields.getMap();
        //verify field names
        if (!objFieldMap.containsKey(pControllingFieldName) || !objFieldMap.containsKey(pDependentFieldName))
            return objResults;     
        //get the control values   
        List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues();
        //get the dependent values
        List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues();
        objFieldMap = null;
        List<Integer> lstControllingIndexes = new List<Integer>();
        //iterate through the values and get the ones valid for the controlling field name
        //set up the results
        for(Integer pControllingIndex=0; pControllingIndex<ctrl_ple.size(); pControllingIndex++){            
            //get the pointer to the entry
            Schema.PicklistEntry ctrl_entry = ctrl_ple[pControllingIndex];
            //get the label
            String pControllingLabel = ctrl_entry.getLabel();
            //create the entry with the label
            objResults.put(pControllingLabel,new List<String>());
            //keep track of the controlling indexes
            lstControllingIndexes.add(pControllingIndex);
        }
        //cater for null and empty
        objResults.put(‘‘,new List<String>());
        objResults.put(null,new List<String>());
        //load all dep entries
        List<Schema.PicklistEntry> objEntries = new List<Schema.PicklistEntry>();
        List<TStringUtils.TPicklistEntry> objDS_Entries = new List<TStringUtils.TPicklistEntry>();
        //add all entries
        for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){            
            //get the pointer to the dependent index
               Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
               objEntries.add(dep_entry);
               
        } 
        //serialize once        
        objDS_Entries = (List<TStringUtils.TPicklistEntry>)JSON.deserialize(JSON.serialize(objEntries), List<TStringUtils.TPicklistEntry>.class);
        List<Integer> validIndexes;
        for (TStringUtils.TPicklistEntry objDepPLE : objDS_Entries){
            //if valid for is empty, skip    
            if (objDepPLE.validFor==null || objDepPLE.validFor==‘‘){
                continue;
            }
            //get the test for the controlling indexes
            validIndexes = BitSetInstance.testBits(objDepPLE.validFor,lstControllingIndexes);
            for (Integer validIndex : validIndexes){                
                //get the label
                String pControllingLabel = ctrl_ple[validIndex].getLabel();
                objResults.get(pControllingLabel).add(objDepPLE.label);
            }
        }
        objEntries = null;
        objDS_Entries = null;
        return objResults;
    }

 

  




以上是关于Field Dependent 在Apex里使用control 和 dependent list-Picklist的主要内容,如果未能解决你的问题,请参考以下文章

057_Apex 开发中的问题

APEX 3.2 空值和空白的文本验证

Eclipse wtp project dependent project facets问题

C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)

C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)

使用dependent: :destroy 在rails 上不起作用