通过


在预测中自定义基础记录网格

作为开发人员,使用此参考文档了解事件和上下文对象,以自定义预测中的基础记录网格。 可以使用上下文对象执行自定义,如让整个网格或特定字段只读、禁用字段、显示错误通知等。

基础记录网格的事件

预测支持以下事件:

以下示例场景基于支持的事件处理程序创建:

OnRowLoad 事件

针对网格中加载的每个基础记录触发 OnRowLoad 事件。 传递给 OnRowLoad 事件处理程序的上下文对象包含特定于基础记录的 API。

下面是可以使用 OnRowLoad 处理程序执行的示例场景:

注释

对于预测配置,可以通过在基础记录网格中选择 Groupby 属性来查看不同实体的基础记录。 若要基于这些实体处理逻辑,请参阅示例基于实体始终仅启用几个字段基于逻辑和实体禁用字段编辑

OnChange 事件

当基础记录网格中的单元格值更新且单元格在焦点之外时,将触发 OnChange 事件。

注释

下面是可以使用 OnChange 处理程序执行的示例场景:

OnSave 事件

当基础记录网格单元格中的值更改且单元格在焦点之外时,将触发 OnSave 事件。 但是,如果同一预测配置存在 OnChange 处理程序,OnSave 处理程序在 OnChange 处理程序之后调用。

OnSave 处理程序在字段实际保存之前调用。

注释

下面是可以使用 OnSave 处理程序执行的示例场景:

基础记录网格中事件处理程序的上下文对象

上下文对象包含一组 API,用于执行特定于预测中基础记录的操作。 此上下文对象作为参数传递给基础记录网格视图中的事件处理程序。

以下 API 受支持:

context.getFormContext 方法

返回对基础记录网格上的记录的引用。

context.getFormContext().data.entity

这会返回一个实体对象,并具有以下方法:

方法 返回类型 Description
getEntityName() String 返回一个字符串,表示记录的实体的逻辑名称。
getId() String 返回一个字符串,表示记录的 GUID 值。
attributes 列出 返回与视图相关的属性列表,以及作为基础记录网格一部分加载的实体。 您可以执行以下操作:
- context.getFormContext().data.entity.attributes.forEach
- context.getFormContext().data.entity.attributes.getByName(arg)
- context.getFormContext().data.entity.attributes.get(index)

context.getFormContext().data.entity.attributes.getByName("Attribute Name")

这会返回一个属性对象,并具有以下方法:

方法 返回类型 Description
getName() String 返回一个表示属性的逻辑名称的字符串。
getValue() -- 检索属性的数据值。
getIsDirty() 布尔 返回一个布尔值,指示属性值是否有任何未保存的更改。
controls 列出 返回每个属性对象的控件列表。
注意controls 对象列表长度始终为 1,get(0) 可直接使用。

context.getFormContext().data.entity.attributes.getByName("Attribute Name").controls.get(0)

这会返回与属性的控件对象映射,并具有以下方法:

方法 返回类型 Description
getDisabled() 布尔 返回控件是否已禁用。
setDisabled(bool) -- 将禁用的值(true 或 false)设置为控件。
setNotification(message: string, uniqueId?: string) 布尔 显示控件的错误消息,指示数据无效。 使用此方法时,单元格中控件旁边会显示一个红色十字图标。 将鼠标悬停在错误图标上将显示提供的消息。 选择错误图标将重新加载行并撤消任何更改。 使用 clearNotification 方法时,uniqueId 用于清除此消息。
clearNotification(uniqueId?: string) 布尔 删除已为控件显示的消息。 如果未提供唯一 ID,则会删除该控件的所有通知。

注释

我们建议 JavaScript 文件中的函数名称必须与事件名称相匹配,并且必须接受上下文对象参数。

示例 1:

我们来创建 JavaScript 代码,将基础记录网格中的所有字段设为只读。 此外,在成功加载和保存网格时,我们将为每个行调用 OnRowLoad 函数。

function OnRowLoad(executionContext) {
    // Iterating through all attributes and disabling it.
    executionContext.getFormContext().data.entity.attributes.forEach(
        attribute => {
            attribute.controls.get(0).setDisabled(true);
        }
    )
}

示例 2:

我们来创建 JavaScript 代码来禁用除商机实体的一些字段以外的所有字段。 此外,在成功加载和保存网格时,我们将为每个行调用 OnRowLoad 函数。

function OnRowLoad(executionContext) {

    // Get the logical name of the loaded entity as part of underlying records grid.
    var entityName = executionContext.getFormContext().data.entity.getEntityName();

    if (entityName === "opportunity") {

        // Defining the attributes list from opportunity that has to be enabled if loaded as part of view.
        var OPTY_ENABLE_ATTRS_LIST = ["name", "msdyn_forecastcategory", "actualvalue", "actualclosedate", "estimatedvalue", "estimatedclosedate"];

        executionContext.getFormContext().data.entity.attributes.forEach(
            attribute => {
                // Disabling all attributes other than OPTY_ENABLE_ATTRS_LIST
                if (!OPTY_ENABLE_ATTRS_LIST.includes(attribute.getName())) {
                    attribute.controls.get(0).setDisabled(true);
                }
            }
        )        
    }
}

示例 3:

我们来创建 JavaScript 代码来处理加载的预测配置的不同实体。

对于商机实体,脚本将禁用以下内容:

  • 名称列
  • actualRevenueactualCloseData(如果 forecastCategory 值是最理想情况,则为已提交、已忽略或管道)。
  • estimatedRevenueestimatedCloseDate(如果 forecastCategory 值是赢单或丢单)。

同样,该脚本将禁用客户实体的名称列,并为其他实体禁用所有列。

此外,在成功加载和保存网格时,我们将为每个行调用 OnRowLoad 函数。


function OnRowLoad(executionContext) {
		 
    // Get the logical name of the loaded entity as part of underlying records grid.
    var entityName = executionContext.getFormContext().data.entity.getEntityName();
    
    // If loaded logical name of entity in underlying records grid is opportunity.
    if (entityName === "opportunity") {
        
       var allAttrs = executionContext.getFormContext().data.entity.attributes;

       // Disable column name for all records if exists in the view.
       var nameAttr = allAttrs.getByName("name");
       if (nameAttr) {
           nameAttr.controls.get(0).setDisabled(true);
       }

       var fcatAttr = allAttrs.getByName("msdyn_forecastcategory");
       if (fcatAttr) {
           // Disable actualRevenue, actualCloseDate for forecastcategory Bestcase, committed, omitted, or pipeline.
           if (fcatAttr.getValue() <= 100000004 && fcatAttr.getValue() >= 100000001) {
                   var actualRevenueAttr = allAttrs.getByName("actualvalue");
                   var actualCloseDateAttr = allAttrs.getByName("actualclosedate");
                   if (actualRevenueAttr) actualRevenueAttr.controls.get(0).setDisabled(true);
                   if (actualCloseDateAttr) actualCloseDateAttr.controls.get(0).setDisabled(true);
           }
           // Disable estimatedRevenue, estimatedCloseDate for forecastCategory won or lost.
           else if (fcatAttr.getValue() == 100000005 || fcatAttr.getValue() == 100000006) {
                   var estimatedRevenueAttr = allAttrs.getByName("estimatedvalue");
                   var estimatedCloseDateAttr = allAttrs.getByName("estimatedclosedate");
                   if (estimatedRevenueAttr) estimatedRevenueAttr.controls.get(0).setDisabled(true);
                   if (estimatedCloseDateAttr) estimatedCloseDateAttr.controls.get(0).setDisabled(true);
           }
       }
   } 
   
   // Else disable name column, if loaded logical name of entity is Account.
   else if (entityName === "account"){
       var attrNameObj = executionContext.getFormContext().data.entity.attributes.getByName("name");
       if (attrNameObj) {
               attrNameObj.controls.get(0).setDisabled(true);
       }
   } 
   
   // For all other entities
   else {
       executionContext.getFormContext().data.entity.attributes.forEach(
           attribute => {
               attribute.controls.get(0).setDisabled(true);
           }
       )
   }
}

示例 4:

我们来创建一个验证 JavaScript 文件,在值小于 10 时阻止保存和显示有关估计收入列的错误通知。 此外,我们将删除错误通知,并允许在将估计收入列值更正为大于或等于 10 时保存。 在此处,在预测的基础记录网格上更新任何字段的值时,将调用 OnChange 函数。


// OnChange function is invoked when any field's value is updated on the underlying records grid of the forecast
function OnChange(executionContext) {

    let entity = executionContext.getFormContext().data.entity;

    // Verify the logical name of the entity and load as part of the underlying records grid.
    if (entity.getEntityName() === "opportunity") {

        // Verify estimated revenue value
        let estValAttr = entity.attributes.get("estimatedvalue");

        // Verify if this attribute exists within the grid view and changed
        if(estValAttr && estValAttr.getIsDirty()) 
        {
            if(estValAttr.getValue() < 10){

                // This will show an error icon next to the estimated revenue field. On hovering over the icon, the below provided message is displayed.
                // Any save attempts are blocked by the system until all notifications are cleared from the columns.
                estValAttr.controls.get(0).setNotification("Estimated revenue cannot be less than 10");
            }
            else{
                // Clearing notifications to save.
                estValAttr.controls.get(0).clearNotification();
            }
        }
    }
}

context.getWebApiContext()

这会返回一个 webApiContext 对象,并具有以下方法:

方法 Description
retrieveRecord(entityLogicalName, id, options)
then (successCallback, errorCallback);
检索实体记录。 详细信息:retrieveRecord(客户端 API 参考)
updateRecord(entityLogicalName, id, data)
then(successCallback, errorCallback);
更新实体记录。 详细信息:updateRecord(客户端 API 参考)
createRecord(entityLogicalName, data)
then(successCallback, errorCallback);
创建实体记录。 详细信息:createRecord(客户端 API 参考)
deleteRecord(entityLogicalName, id)
then(successCallback, errorCallback);
删除实体记录。 详细信息:deleteRecord(客户端 API 参考)

context.getEventArgs().preventDefault()

preventDefault() 方法仅在 OnSave 事件中可用。 在 OnSave 中调用此方法将阻止保存事件继续。

示例:

我们创建示例 JavaScript 来打开商机网格,并在估计收入值小于 10 时阻止自动保存事件并打开窗口警报。 此外,如果估计的收入值大于或等于 10,我们将允许自动保存事件。

// OnSave function will be invoked whenever grid attempts to save changes made to any field. 
function OnSave(executionContext){

    let entity = executionContext.getFormContext().data.entity;

    // Verify the logical name of the entity and load as part of the underlying records grid.
    if (entity.getEntityName() === "opportunity") {

        // Verify estimated revenue value
        var estValAttr = entity.attributes.get("estimatedvalue");

        if(estValAttr && estValAttr.getIsDirty() && estValAttr.getValue() < 10){

            // This call will prevent the save event from proceeding
            executionContext.getEventArgs().preventDefault(); 
            alert("Estimated revenue cannot be less than 10");

        }
    }
}

自定义基础记录网格