get lightning object layout by current user and recordtypeid

目录

 

应用场景

参数说明

缺点限制

展示页面示例

组件源码

Page

getSessionId.page

Controller

ResponseBody.cls

GetRecordLayout.cls

Aura

ElementChangeEvent.evt

GetRecordLayout.cmp

GetRecordLayout.css

GetRecordLayoutController.js

GetRecordLayoutHelper.js

源码链接



应用场景

  • 重写对象的新建和编辑页面时,动态拉去系统配置的标准页面布局元素

参数说明

  • <c:GetRecordLayout sobjectAPI="Case" recordMap="{!v.recordMap}" layout="{!v.layout}" fieldChange="{!c.fieldChange}" mode="create" recordTypeId="{!v.recordTypeId}" displayDensity="Comfy"/>
  • sobjectAPI对象API
  • recordMap封装初始值,可设置value(字段值)type(字段类型)formatter(字段格式)standard(是否使用inputField展示字段)helptext(帮助文本,自动拉取) despatchChange(是否监听字段变化)checkError(是否出错,默认false)errorMsg(报错消息)apiName(字段API)
  • Layout为记录字段的信息,由子组件返回至主组件中进行校验数据,保存数据等操作
  • fieldChange为字段变更事件
  • Mode默认为create,表示拉去页面布局的类型(vieweditcreateview暂不支持,有标准的组件可用。
  • recordTypeId记录类型id,为空的话,取当前用户的默认记录类型
  • displayDensity布局类型(comfyCompact

缺点限制

  • 查找字段没有新建记录页面
  • 字段依赖关系的链接无法显示(或可优化)
  • DateTime类型字段不会显示Date Time标签(或可优化)
  • 必填的选项列表字段初始化时页面会显示字段必填提示(还未找到解决方案)
  • 未知缺点

展示页面示例

组件源码

Page

getSessionId.page

<apex:page >
    Start_Of_Session_Id{!$Api.Session_ID}End_Of_Session_Id
</apex:page>

Controller

ResponseBody.cls

public class ResponseBody {
  @AuraEnabled
  public String Status{get;set;}
  @AuraEnabled
  public String Msg{get;set;}
  @AuraEnabled
  public Object Entity{get;set;}

  public ResponseBody(String Status, String Msg, Object Entity){
    this.Status = Status;
    this.Msg = Msg;
    this.Entity = Entity;
  }
}

GetRecordLayout.cls

public with sharing class GetRecordLayout 
{
    /**
     * [getRecordLayoutInformation 通过请求rest获取layout布局元素]
     * @Author      Faith
     * @DateTime    2019-05-15T12:01:03+0800
     * @Description
     * @param       condition                [请求rest的参数]
     * @return                               [description]
     */
  @AuraEnabled
  public static ResponseBody getRecordLayoutInformation(String condition)
  {
      try
      {
          Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setTimeout(120000);
            request.setMethod('GET'); 
            request.setHeader('Authorization', 'Bearer '+getUserSessionId());
            request.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+condition);
            HttpResponse response=http.send(request);
            return new ResponseBody('SUCCESS','',response.getBody());
      }catch(Exception e)
      {
          return new ResponseBody('ERROR',e.getMessage(),'');
      }
  }
    /**
     * [getUserSessionId 获取当前用户的sessionid]
     * @Author      Faith
     * @DateTime    2019-05-15T12:03:18+0800
     * @Description
     * @return      [description]
     */
  public static String getUserSessionId()
  {
    return Page.GetSessionId.getContent().toString().substringBetween('Start_Of_Session_Id', 'End_Of_Session_Id');
    }
    /**
     * [getFieldMap 获取字段信息并封装实体类]
     * @Author      Faith
     * @DateTime    2019-05-15T14:18:51+0800
     * @Description
     * @param       sObjectName              [description]
     * @return                               [description]
     */
    public static Map<String,FieldEntry> getFieldMap(String sObjectName)
    {
        Map<String, FieldEntry> fieldEntryMap=new Map<String, FieldEntry>();
    if (Schema.getGlobalDescribe().containsKey(sObjectName)) 
    {
      Map<String, Schema.SobjectField> sObjectFieldsMap=Schema.getGlobalDescribe().get(sObjectName).getDescribe().fields.getMap();
      for(String fieldName:sObjectFieldsMap.keySet())
            {
                Schema.DescribeFieldResult fieldDescribe=sObjectFieldsMap.get(fieldName).getDescribe();
                fieldEntryMap.put(fieldDescribe.getName(),new FieldEntry(fieldDescribe.getName(),fieldDescribe.getMaskType(),fieldDescribe.getInlineHelpText()));
            }
    }
        return fieldEntryMap;
    }
    /**
     * 字段信息封装实体类
     */
    public class FieldEntry
    {
        @AuraEnabled
        private String value{get;set;}
        @AuraEnabled
        private String type{get;set;}
        @AuraEnabled
        private String formatter{get;set;}
        @AuraEnabled
        private Boolean standard{get;set;}
        @AuraEnabled
        private String helptext{get;set;}
        @AuraEnabled
        private Boolean despatchChange{get;set;}
        @AuraEnabled
        private Boolean checkError{get;set;}
        @AuraEnabled
        private String errorMsg{get;set;}
        @AuraEnabled
        private String apiName{get;set;}
        public FieldEntry(String apiName,String type,String helptext)
        {
            this.value=null;
            this.apiName=apiName;
            this.errorMsg=null;
            this.formatter=null;
            this.standard=true;
            this.checkError=false;
            this.despatchChange=false;
            this.type=type;
            this.helptext=helptext;
        }
    }
}

Aura

ElementChangeEvent.evt

<aura:event type="APPLICATION" description="ElementChangeEvent">
    <aura:attribute name="element" type="Object" access="public"/>
</aura:event>

GetRecordLayout.cmp

<aura:component implements="flexipage:availableForAllPageTypes" controller="GetRecordLayout">
<!-- SobjectAPI -->
<aura:attribute name="sobjectAPI" type="String" default="Case"/>
<!-- The access mode for the record(create,edit,view) -->
<aura:attribute name="mode" type="String" default="create"/>
<!-- The ID of the record type (RecordType object) for the new record,If not provided, the default record type is used. -->
<aura:attribute name="recordTypeId" type="String"/>
<!-- The layout type for the record. One of these values(Compact,Full) -->
<aura:attribute name="layoutType" type="String" default="Full"/>
<!-- The layout display size for the record. One of these values:Large,Medium,Small -->
<aura:attribute name="formFactor" type="String" default="Large"/>
<!-- layout information -->
<aura:attribute name="layout" type="Object" />
<!-- the record init values(fieldAPI=>values) -->
<aura:attribute name="recordMap" type="Map"/>
<!-- loading -->
<aura:attribute name="showSpinner" type="Boolean" default="true" />
<!-- DISPLAY DENSITY(Comfy,Compact) -->
<aura:attribute name="displayDensity" type="String" default="Comfy"/>
<!-- registerEvent -->
<aura:registerEvent name="fieldChange" type="c:ElementChangeEvent" />
<!-- init method -->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:if isTrue="{!v.showSpinner}"><lightning:spinner /></aura:if>
<div style="background-color:white;padding:5px;">
    <lightning:recordEditForm objectApiName="{!v.sobjectAPI}" recordTypeId="{!v.recordTypeId}">
        <aura:iteration items="{!v.layout.sections}" var="section" indexVar="sectionIndex">
            <div class="slds-section slds-is-open">
                <aura:if isTrue="{!section.useHeading}">
                  <h3 class="slds-section__title slds-theme_shade">
                    <span class="slds-truncate slds-p-horizontal_small" title="{!section.heading}">{!section.heading}</span>
                  </h3>
                </aura:if>
              <div aria-hidden="false" class="slds-section__content">
                <div class="slds-form" role="list">
                    <aura:iteration items="{!section.layoutRows}" var="row" indexVar="rowIndex">
                          <div class="slds-form__row">
                              <aura:iteration items="{!row.layoutItems}" var="item" indexVar="itemIndex">
                                <div class="slds-form__item" role="listitem">
                                  <div class="{!'slds-form-element slds-form-element_'+if(v.displayDensity=='Comfy','stacked','horizontal')+' slds-is-editing'}">
                                      <aura:if isTrue="{!and(item.layoutComponents.length>1)}">{!item.label}<br/></aura:if>
                                    <aura:iteration items="{!item.layoutComponents}" var="element" indexVar="elementIndex">
                                        <aura:if isTrue="{!and(element.apiName!=null,element.componentType=='Field')}">
                                            <label class="slds-form-element__label">
                                                <aura:if isTrue="{!item.required}"><abbr class="slds-required" title="required">*</abbr></aura:if>
                                                {!if(item.layoutComponents.length==1,item.label,element.label)}
                                            </label>
                                            <aura:if isTrue="{!element.helptext!=null}">
                                                <lightning:helptext content="{!element.helptext}"/>
                                            </aura:if>
                                            <aura:if isTrue="{!element.standard}">
                                                <lightning:inputField fieldName="{!element.apiName}" disabled="{!if(mode=='create',element.editableForNew,element.editableForUpdate)}" variant="label-hidden" class="{!'InputFieldLabelHide'+if(element.checkError,' slds-has-error','')}" value="{!element.value}" οnchange="{!c.changeHandler}" title="{!sectionIndex+'#'+rowIndex+'#'+itemIndex+'#'+elementIndex}"/>
                                                <aura:set attribute="else">
                                                    <lightning:input type="{!element.type}" formatter="{!element.formatter}" value="{!element.value}" class="if(element.checkError,' slds-has-error','')}" οnchange="{!c.changeHandler}" title="{!sectionIndex+'#'+rowIndex+'#'+itemIndex+'#'+elementIndex}" variant="label-hidden"/>
                                                </aura:set>
                                            </aura:if>
                                            <aura:if isTrue="{!element.checkError}">
                                                <div class="slds-form-element__help" style="color:#DC143C;">{!element.errorMsg}</div>
                                            </aura:if>
                                        </aura:if>
                                      </aura:iteration>
                                  </div>
                                </div>
                            </aura:iteration>
                          </div>
                      </aura:iteration>
                    </div>
              </div>
            </div>
        </aura:iteration>
    </lightning:recordEditForm>
</div>
</aura:component>

GetRecordLayout.css

.THIS {}
.THIS .InputFieldLabelHide .slds-form-element__label,.THIS .InputFieldLabelHide lightning-helptext{display:none}
.THIS input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  margin: 0; 
}
.THIS input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  margin: 0; 
}
.THIS input[type=number]::-webkit-inner-spin-button, 
.THIS input[type=number]::-webkit-outer-spin-button { 
  -webkit-appearance: none; 
  margin: 0; 
}

GetRecordLayoutController.js

({
  doInit:function(cmp, event, helper) 
  {
      helper.getRecordLayoutInformation(cmp, event, helper);
  },
  changeHandler:function(cmp,event,helper)
  {
      var layout=cmp.get("v.layout");
      var indexInformation=event.getSource().get("v.title");
      var result=indexInformation.split("#");
      var sectionIndex=result[0],rowIndex=result[1],itemIndex=result[2],elementIndex=result[3];
      var value=event.getSource().get("v.value");
      if(layout.sections[sectionIndex].layoutRows[rowIndex].layoutItems[itemIndex].required&&(value==null||value==""))
      {
          layout.sections[sectionIndex].layoutRows[rowIndex].layoutItems[itemIndex].layoutComponents[elementIndex].checkError=true;
      }
      else
      {
          layout.sections[sectionIndex].layoutRows[rowIndex].layoutItems[itemIndex].layoutComponents[elementIndex].checkError=false;
    }
    if(layout.sections[sectionIndex].layoutRows[rowIndex].layoutItems[itemIndex].layoutComponents[elementIndex].despatchChange)
    {
      helper.despatchFieldChangeEvent(cmp,result);
    }
      cmp.set("v.layout", layout);
  },
})

GetRecordLayoutHelper.js

({
  getRecordLayoutInformation:function(cmp, event, helper) 
  {
      console.log("getRecordLayoutInformation");
      var action=cmp.get("c.getRecordLayoutInformation");
    var condition="/services/data/v45.0/ui-api/layout/"+cmp.get("v.sobjectAPI")+"?mode="+cmp.get("v.mode");
    var recordTypeId=cmp.get("v.recordTypeId");
    if(recordTypeId!=null&&recordTypeId!='') condition+="&recordTypeId="+recordTypeId;
    action.setParams({"condition":condition});
    action.setCallback(this, function (response)
    {
      if (cmp.isValid()&&response.getState()==="SUCCESS") 
      {
          var ResponseBody = response.getReturnValue();
          console.log(ResponseBody);
        var Entity = ResponseBody.Entity;
        var Msg = ResponseBody.Msg;
        var Status = ResponseBody.Status;
        if(Status=="SUCCESS")
        {
          var layout = JSON.parse(Entity);
          var recordMap=cmp.get("v.recordMap");
          var sections=layout.sections;
          for(var i=0; i<sections.length;i++) 
          {
            var layoutRows=sections[i].layoutRows;
            for(var j=0;j<layoutRows.length;j++) 
            {
              var layoutItems=layoutRows[j].layoutItems;
              for(var n=0;n<layoutItems.length;n++) 
              {
                var layoutComponents=layoutItems[n].layoutComponents;
                for(var m=0;m<layoutComponents.length;m++) 
                {
                  if(layoutComponents[m].apiName==null||layoutComponents[m].componentType!='Field') continue;
                  if(recordMap!=null&&recordMap[layoutComponents[m].apiName]!=undefined)
                  {
                    layoutComponents[m].value=recordMap[layoutComponents[m].apiName].value;
                    layoutComponents[m].type=recordMap[layoutComponents[m].apiName].type;
                    layoutComponents[m].formatter=recordMap[layoutComponents[m].apiName].formatter;
                    layoutComponents[m].standard=recordMap[layoutComponents[m].apiName].standard;
                    layoutComponents[m].helptext=recordMap[layoutComponents[m].apiName].helptext;
                  }
                  else
                  {
                    layoutComponents[m].value=null;
                    layoutComponents[m].type="inputField";
                    layoutComponents[m].formatter=null;
                    layoutComponents[m].standard=true;
                    layoutComponents[m].helptext=null;
                    layoutComponents[m].despatchChange=false;
                  }
                  layoutComponents[m].checkError=false;
                  layoutComponents[m].errorMsg="This field is required";
                }
                layoutItems[n].layoutComponents=layoutComponents;
              }
              layoutRows[j].layoutItems=layoutItems;
            }
            sections[i].layoutRows=layoutRows;
          }
          layout.sections=sections;
          console.log(layout);
          cmp.set("v.layout", layout);
          cmp.set("v.showSpinner", false);
        }
        else alert(Msg);
      }
      else alert(response.getErrors());
    });
    $A.enqueueAction(action);
  },
  despatchFieldChangeEvent: function(cmp,element){
    var compEvent = cmp.getEvent("fieldChange");
    compEvent.setParams({"element": element});
    compEvent.fire();
  },
  /*despatchSearchChangeEvent: function(cmp,element){
    var compEvent = cmp.getEvent("searchChange");
    compEvent.setParams({"element": element});
    compEvent.fire();
  }*/
})

源码链接

链接: https://pan.baidu.com/s/1GUwPaS44ELFLN6wbmudhmw 提取码: nkhr 

CreateRecord.cmp为调用示例

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值