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的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse wtp project dependent project facets问题
C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)
C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)