关于Salesforce存在至于项目的选择List的取值问题
概要:
我们在做项目的时候,经常会遇到一个问题:
一个选择List字段的可选项被另一个选择List制约,这种情况如何在后台取得这两者的对应关系。
原文在这里(侵删):
Apexで連動項目の選択肢を取得する方法(改善版) - Qiita
之前第一个博文看不懂,看了第二个之后才明白大概原理。
所以才有了这篇随笔:
·Example.apxc
public class Example {
private static String INITIAL_VALUE = '';
// 選択リストで選択された値が格納される変数
public SomeObject objectInstance {get; set;} public List<SelectOption> DependentPickListOptions{
get{
List<SelectOption> options = new List<SelectOption>(); // 選択リストの一番上にデフォルトの選択値を設定
options.add(new SelectOption(INITIAL_VALUE, '-- なし --')); // 制御項目ctrlPicklistが選択されている時に連動項目depPicklistで選べる選択肢を取得する。
if( this.objectInstance.ctrlPicklist != null || this.objectInstance.ctrlPicklist != INITIAL_VALUE ){
List<DepPickListCtrl.TPicklistEntry> tPicklistEntries =
DepPickListCtrl.GetDependentOptions('SomeObject','ctrlPicklist','depPicklist').get(this.objectInstance.ctrlPicklist); for( DepPickListCtrl.TPicklistEntry e : tPicklistEntries ){
options.add(new SelectOption(e.value, e.label));
}
}
return options;
}
} // コンストラクタ
public Example(){
this.objectInstance = new SomeObject();
}
}
这个部分,相信大部分人都能查看文档弄清楚。
最关键的下面这个方法(GetDependentOptions):DepPickListCtrl.apxc
/* Reference
* Great thanks to Neel
* http://titancronus.com/blog/2014/05/01/salesforce-acquiring-dependent-picklists-in-apex/
*/ public class DepPickListCtrl {
public static Map<String,List<DepPickListCtrl.TPicklistEntry>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
Map<String,List<DepPickListCtrl.TPicklistEntry>> objResults = new Map<String,List<DepPickListCtrl.TPicklistEntry>>();
//get the string to sobject global map
// 拿到Schema命名空间的描述
Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
if (!objGlobalMap.containsKey(pObjName))
return objResults;
//get the type being dealt with
Schema.SObjectType pType = objGlobalMap.get(pObjName);
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选项对应关系
List<Schema.PicklistEntry> ctrl_ple = objFieldMap.get(pControllingFieldName).getDescribe().getPicklistValues();
//get the dependent values
// 拿到被控制的List选项对应关系
List<Schema.PicklistEntry> dep_ple = objFieldMap.get(pDependentFieldName).getDescribe().getPicklistValues();
//iterate through the values and get the ones valid for the controlling field name
// 这个Validfor我实在不知道是干嘛的。官方文档上也没找打,但是这个值很重要
DepPickListCtrl.DependentValidFor dvf=new DepPickListCtrl.DependentValidFor(); //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<DepPickListCtrl.TPicklistEntry>());
}
//cater for null and empty
objResults.put('',new List<DepPickListCtrl.TPicklistEntry>());
objResults.put(null,new List<DepPickListCtrl.TPicklistEntry>());
//check the dependent values
for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){
//get the pointer to the dependent index
Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
//get the valid for
// 不转换成Json,你是拿不到validfor这个值的
String pEntryStructure = JSON.serialize(dep_entry);
DepPickListCtrl.TPicklistEntry objDepPLE = (DepPickListCtrl.TPicklistEntry)JSON.deserialize(pEntryStructure, DepPickListCtrl.TPicklistEntry.class);
//if valid for is empty, skip
if (objDepPLE.validFor==null || objDepPLE.validFor==''){
continue;
}
//iterate through the controlling values
// 【getControlIndexes】这个方法就是取得被控制选择List的选项的Index的方法
// 实现原理看在下面
for(Integer idx : dvf.getControlIndexes(objDepPLE.validFor)){
//get the label
String pControllingValue = ctrl_ple[idx].getValue();
objResults.get(pControllingValue).add(objDepPLE);
}
}
return objResults;
}
public class TPicklistEntry{
public string active {get;set;}
public string defaultValue {get;set;}
public string label {get;set;}
public string value {get;set;}
public string validFor {get;set;}
public TPicklistEntry(){
}
}
private class DependentValidFor {
private Map<String,Set<Integer>> mapValidForIndexes=new Map<String,Set<Integer>>();
public Set<Integer> getControlIndexes(String validFor){
if(mapValidForIndexes.containsKey(validFor))
return mapValidForIndexes.get(validFor);
// 将validfor从Base64转化成16进制格式
// 对,也就是说,validfor是Base64格式的数据
// 而官方只提供了转化成16进制格式的方法(convertToHex),这样才将validfor变为可读数据
String hex=EncodingUtil.convertToHex(EncodingUtil.base64Decode(validFor));
Set<Integer> result=new Set<Integer>();
// 循环遍历16进制数的每一位
for(Integer i=0; i<hex.length(); i++){
String b=hex.substring(i, i+1);
Integer off=i*4;
// 每一位都当成二进制数据
switch on b { //0123(index)
when '0'{ //0000
}
// 第一次循环时i=0
// 当0010的时候,意味着被控制选择List的选项的Index2的选项是可选的
// 当0100的时候,意味着被控制选择List的选项的Index3的选项是可选的
// 。。。。
// 也就是说决定那个Index的选项可选不是看值的大小,
// 而是看值的位置,1处在那个位置上,index几就是可选项。
// 因为每一个16进制数可以表示n~n+4(index),
// 所以当i+1时,index就是从n+4开始的,
// 例子: i=0时,“f” → 0,1,2,3
// 例子: i=1时, “f” → 4,5,6,7
// 所以off每次都要*4
when '1'{ //0001
result.add(off+3);
}
when '2'{ //0010
result.add(off+2);
}
when '3'{ //0011
result.add(off+2);
result.add(off+3);
}
when '4'{ //0100
result.add(off+1);
}
when '5'{ //0101
result.add(off+1);
result.add(off+3);
}
when '6'{ //0110
result.add(off+1);
result.add(off+2);
}
when '7'{ //0111
result.add(off+1);
result.add(off+2);
result.add(off+3);
}
when '8'{ //1000
result.add(off+0);
}
when '9'{ //1001
result.add(off+0);
result.add(off+3);
}
when 'a'{ //1010
result.add(off+0);
result.add(off+2);
}
when 'b'{ //1011
result.add(off+0);
result.add(off+2);
result.add(off+3);
}
when 'c'{ //1100
result.add(off+0);
result.add(off+1);
}
when 'd'{ //1101
result.add(off+0);
result.add(off+1);
result.add(off+3);
}
when 'e'{ //1110
result.add(off+0);
result.add(off+1);
result.add(off+2);
}
when 'f'{ //1111
result.add(off+0);
result.add(off+1);
result.add(off+2);
result.add(off+3);
}
}
}
mapValidForIndexes.put(validFor,result);
return result;
}
}
}
/* Reference
* Great thanks to Neel
* http://titancronus.com/blog/2014/05/01/salesforce-acquiring-dependent-picklists-in-apex/
*/
public class DepPickListCtrl {
public static Map<String,List<DepPickListCtrl.TPicklistEntry>> GetDependentOptions(String pObjName, String pControllingFieldName, String pDependentFieldName){
Map<String,List<DepPickListCtrl.TPicklistEntry>> objResults = new Map<String,List<DepPickListCtrl.TPicklistEntry>>();
//get the string to sobject global map
Map<String,Schema.SObjectType> objGlobalMap = Schema.getGlobalDescribe();
if (!objGlobalMap.containsKey(pObjName))
return objResults;
//get the type being dealt with
Schema.SObjectType pType = objGlobalMap.get(pObjName);
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();
//iterate through the values and get the ones valid for the controlling field name
DepPickListCtrl.DependentValidFor dvf=new DepPickListCtrl.DependentValidFor();
//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<DepPickListCtrl.TPicklistEntry>());
}
//cater for null and empty
objResults.put('',new List<DepPickListCtrl.TPicklistEntry>());
objResults.put(null,new List<DepPickListCtrl.TPicklistEntry>());
//check the dependent values
for(Integer pDependentIndex=0; pDependentIndex<dep_ple.size(); pDependentIndex++){
//get the pointer to the dependent index
Schema.PicklistEntry dep_entry = dep_ple[pDependentIndex];
//get the valid for
String pEntryStructure = JSON.serialize(dep_entry);
DepPickListCtrl.TPicklistEntry objDepPLE = (DepPickListCtrl.TPicklistEntry)JSON.deserialize(pEntryStructure, DepPickListCtrl.TPicklistEntry.class);
//if valid for is empty, skip
if (objDepPLE.validFor==null || objDepPLE.validFor==''){
continue;
}
//iterate through the controlling values
for(Integer idx : dvf.getControlIndexes(objDepPLE.validFor)){
//get the label
String pControllingValue = ctrl_ple[idx].getValue();
objResults.get(pControllingValue).add(objDepPLE);
}
}
return objResults;
}
public class TPicklistEntry{
public string active {get;set;}
public string defaultValue {get;set;}
public string label {get;set;}
public string value {get;set;}
public string validFor {get;set;}
public TPicklistEntry(){
}
}
private class DependentValidFor {
private Map<String,Set<Integer>> mapValidForIndexes=new Map<String,Set<Integer>>();
public Set<Integer> getControlIndexes(String validFor){
if(mapValidForIndexes.containsKey(validFor))
return mapValidForIndexes.get(validFor);
String hex=EncodingUtil.convertToHex(EncodingUtil.base64Decode(validFor));
Set<Integer> result=new Set<Integer>();
for(Integer i=0; i<hex.length(); i++){
String b=hex.substring(i, i+1);
Integer off=i*4;
switch on b { //0123(index)
when '0'{ //0000
}
when '1'{ //0001
result.add(off+3);
}
when '2'{ //0010
result.add(off+2);
}
when '3'{ //0011
result.add(off+2);
result.add(off+3);
}
when '4'{ //0100
result.add(off+1);
}
when '5'{ //0101
result.add(off+1);
result.add(off+3);
}
when '6'{ //0110
result.add(off+1);
result.add(off+2);
}
when '7'{ //0111
result.add(off+1);
result.add(off+2);
result.add(off+3);
}
when '8'{ //1000
result.add(off+0);
}
when '9'{ //1001
result.add(off+0);
result.add(off+3);
}
when 'a'{ //1010
result.add(off+0);
result.add(off+2);
}
when 'b'{ //1011
result.add(off+0);
result.add(off+2);
result.add(off+3);
}
when 'c'{ //1100
result.add(off+0);
result.add(off+1);
}
when 'd'{ //1101
result.add(off+0);
result.add(off+1);
result.add(off+3);
}
when 'e'{ //1110
result.add(off+0);
result.add(off+1);
result.add(off+2);
}
when 'f'{ //1111
result.add(off+0);
result.add(off+1);
result.add(off+2);
result.add(off+3);
}
}
}
mapValidForIndexes.put(validFor,result);
return result;
}
}
}
关于Salesforce存在至于项目的选择List的取值问题的更多相关文章
- pycharm新建项目时选择virtualenv的说明
虚拟环境及venv和virtualenv介绍:https://www.cnblogs.com/mind18/p/13877170.html pip介绍:https://www.cnblogs.com/ ...
- git的使用学习笔记3---关于项目分支创建克隆拉取推送
一.创建项目 1.打开官网 2.填写相关内容 查看新创建的项目 3.选择方式 4.在git上新建文件夹 1)克隆: mkdir workspace 将代码克隆到本地,取本地配置的.ssh的文件 git ...
- jQuery取得select选择的文本与值
jquery获取select选择的文本与值获取select :获取select 选中的 text :$("#ddlregtype").find("option:selec ...
- springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序
springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...
- Android项目,从web上取下汉字,中文部分乱码
Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...
- [荐] jQuery取得select选择的文本与值
csdn:http://blog.csdn.net/tiemufeng1122/article/details/44154571 jquery获取select选择的文本与值获取select :获取se ...
- Salesforce中所有常用类型字段的取值与赋值
Salesforce中所有常用字段类型的定义以及如何用代码进行取值和赋值: Field Type的定义: http://www.salesforce.com/us/developer/docs/api ...
- Xamarin.iOS项目提示error MSB3174:”TargetFrameworkVersion”的值无效
Xamarin.iOS项目提示error MSB3174:”TargetFrameworkVersion”的值无效 错误信息:MSBulid\14.0\bin\Microsoft.Common.Cur ...
- jquery获取select选择的文本与值
jquery获取select选择的文本与值获取select :获取select 选中的 text : $("#ddlregtype").find("option:s ...
- bootstrap select 多选的用法,取值和赋值(取消默认选择第一个的对勾)
h5自带的select标签可以实现按住ctrl键多选的功能,但是样式及其难看. bootstrap select是很好用的前端插件 首先引入bootstrap和bootstrap-select的c ...
随机推荐
- 详解神经网络基础部件BN层
摘要:在深度神经网络训练的过程中,由于网络中参数变化而引起网络中间层数据分布发生变化的这一过程被称为内部协变量偏移(Internal Covariate Shift),而 BN 可以解决这个问题. 本 ...
- JZOJ 5460. 士兵训练
题目 \(1\le n,q \le 2\cdot {10}^5,0\le b_i,l_i \le {10}^9,b_i \ge 1,1 \le S_i \le n\) \(Solution\) 这题很 ...
- Python:Excel自动化实践入门篇 甲【留言点赞领图书门票】
*以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s?__biz=MzUxMTgxMzExNQ==&mid=22 ...
- js中的for循环,循环次数会多出一次。当循环到最后一个的时候,循环还会继续,并且此时i就变成remove?
for (i in points) 改成 for(var i = 0; i < points,length; i++)
- observObservableCollection改变model属性UI不更新
使模型类实现INotifyPropertyChanged即可 public class ResDepartmentData : INotifyPropertyChanged { //需要更新UI的属性 ...
- 2.4 在DispatcherServlet的service方法中,通过ServletPath获取对应的Controller对象
@Override protected void service(HttpServletRequest request, HttpServletResponse response) throws Se ...
- flannel 关闭SNAT
flannel 关闭SNAT 默认情况下,flannel 访问集群外网络是通过 SNAT 成宿主机 ip 方式,在一些金融客户环境中为了能实现防火墙规则,需要直接针对 POD ip 进行进行规则配置, ...
- element ui中table动态列切换时,表格样式变形
现象:定义多个头部和多个数据体,可以自由切换不同的头部和相应的数据体,但是切换过程表格会变形. 解决办法:table增加索引,切换头部和数据时,修改为不同的索引,即可解决 重点:表格标签上的 key ...
- mybatis面试资料
1.#{}和${}的区别 #{} 数据类型检查: 若检测到字符串类型,就加上引号: 若检测到数值类型,就不加引号. 安全检查: 若变量的值带有引号,会对引号进行转义处理,这样可以防止sql注入. ${ ...
- consul剔除某个服务
curl --request PUT http://ip:端口/v1/agent/service/deregister/服务对应的id地址