自适应核心组件中的自定义函数Forms

本文介绍了如何使用最新的自适应表单核心组件创建自定义函数,这些组件具有最新的功能,例如:

  • 自定义函数的缓存功能
  • 自定义函数的全局范围对象和字段对象支持
  • 支持现代JavaScript功能,如左键和箭头功能(支持ES10)

请确保在AEM Forms核心组件环境中设置最新表单版本以使用自定义函数中的最新功能。

版本
文章链接
AEM 6.5
本文
AEM as a Cloud Service
单击此处

简介

AEM Forms 6.5包括JavaScript函数,这些函数允许您使用规则编辑器定义复杂的业务规则。 虽然AEM Forms提供了多种现成的自定义函数,但许多用例需要定义您自己的自定义函数才能在多个表单中使用。 这些自定义函数允许根据特定要求处理输入的数据,从而增强表单的功能。 此外,它们允许根据预定义标准动态更改表单行为。

自定义函数的使用 uses-of-custom-function

在自适应Forms核心组件中使用自定义函数的优点包括:

  • 管理数据:自定义函数管理并处理输入到表单字段中的数据。
  • 正在处理数据:自定义函数可帮助处理输入到表单字段中的数据。
  • 数据验证:自定义函数允许您对表单输入执行自定义检查并提供指定的错误消息。
  • 动态行为:自定义函数允许您根据特定条件控制表单的动态行为。 例如,您可以显示/隐藏字段、修改字段值或动态调整表单逻辑。
  • 集成:您可以使用自定义函数与外部API或服务集成。 它有助于从外部源获取数据,将数据发送到外部Rest端点,或根据外部事件执行自定义操作。

自定义函数本质上是添加到JavaScript文件中的客户端库。 创建自定义函数后,该函数即可在规则编辑器中供用户在自适应表单中选择。 自定义函数由规则编辑器中的JavaScript注释标识。

自定义函数支持的JavaScript批注 js-annotations

JavaScript注释为JavaScript代码 ​提供元数据。 它包含以特定符号(例如,/**@)开头的注释。 注释提供了有关代码中的函数、变量和其他元素的重要信息。 自适应表单支持自定义函数的以下JavaScript注释:

名称

Name ​用于标识自适应表单的规则编辑器中的自定义函数。 以下语法用于命名自定义函数:

  • @name [functionName] <Function Name>
  • @function [functionName] <Function Name>
  • @func [functionName] <Function Name>
NOTE
[functionName]是函数的名称。 不允许使用空格。
<Function Name> 是自适应Forms的规则编辑器中函数的显示名称。
如果函数名称与函数本身的名称相同,则可以在语法中省略[functionName]

参数

参数 ​是自定义函数使用的参数列表。 函数可以支持多个参数。 以下语法用于定义自定义函数中的参数:

  • @param {type} name <Parameter Description>

  • @argument {type} name <Parameter Description>

  • @arg {type} name <Parameter Description>

    {type}表示参数类型。 允许的参数类型包括:

    • string:表示单个字符串值。
    • 数字:表示单个数值。
    • 布尔值:表示单个布尔值(true或false)。
    • string[]:表示字符串值的数组。
    • number[]:表示数值的数组。
    • 布尔值[]:表示布尔值的数组。
    • 日期:表示单个日期值。
    • date[]:表示日期值的数组。
    • array:表示包含各种类型值的泛型数组。
    • 对象:表示传递到自定义函数的表单对象,而不是直接传递其值。
    • 范围:表示全局对象,其中包含只读变量,如表单实例、目标字段实例以及在自定义函数中执行表单修改的方法。 此变量声明为JavaScript注释中的最后一个参数,对自适应表单的规则编辑器不可见。 scope参数可访问表单或组件的对象,以触发表单处理所需的规则或事件。 有关Globals对象及其使用方法的详细信息,单击此处

参数类型为​ 不区分大小写,参数名称中不允许有空格。

<Parameter Description>包含有关参数用途的详细信息。 它可以有多个单词。

返回类型

返回类型指定自定义函数在执行后返回的值的类型。 以下语法用于在自定义函数中定义退货类型:

  • @return {type}
  • @returns {type}
    {type}表示函数的返回类型。 允许的返回类型包括:
  • string:表示单个字符串值。
  • 数字:表示单个数值。
  • 布尔值:表示单个布尔值(true或false)。
  • string[]:表示字符串值的数组。
  • number[]:表示数值的数组。
  • 布尔值[]:表示布尔值的数组。
  • 日期:表示单个日期值。
  • date[]:表示日期值的数组。
  • array:表示包含各种类型值的泛型数组。
  • 对象:表示表单对象,而不是直接表示其值。

返回类型不区分大小写。

专用

声明为私有的自定义函数不会出现在自适应表单的规则编辑器的自定义函数列表中。 默认情况下,自定义函数是公用的。 将自定义函数声明为private的语法为@private

创建自定义函数时的准则 considerations

要在规则编辑器中列出自定义函数,您可以使用以下任意格式:

包含或不包含jsdoc注释的函数语句

您可以创建包含或不包含jsdoc注释的自定义函数。

    function functionName(parameters)
        {
            // code to be executed
        }

如果用户没有将任何JavaScript注释添加到自定义函数,则它按函数名称在规则编辑器中列出。 但是,建议包含JavaScript注释,以提高自定义函数的可读性。

带有强制JavaScript注释或注释的Arrow函数

您可以使用箭头函数语法创建自定义函数:

    /**
    * test function
    * @name testFunction
    * @param {string} a parameter description
    * @param {string=} b parameter description
    * @return {string}
    */
    testFunction = (a, b) => {
    return a + b;
    };
    /** */
    testFunction1=(a) => (return a)
    /** */
    testFunction2 = a => a + 100;

如果用户没有将任何JavaScript注释添加到自定义函数,则该自定义函数不会列在自适应表单的规则编辑器中。

带有必需JavaScript注释或注释的函数表达式

要在自适应表单的规则编辑器中列出自定义函数,请以下列格式创建自定义函数:

    /**
    * test function
    * @name testFunction
    * @param {string} input1 parameter description
    * @param {string=} input2 parameter description
    * @return {string}
    */
    testFunction = function(input1,input2)
        {
            // code to be executed
        }

如果用户没有将任何JavaScript注释添加到自定义函数,则该自定义函数不会列在自适应表单的规则编辑器中。

创建自定义函数的先决条件

在开始将自定义函数添加到自适应Forms之前,请确保在计算机上安装了以下软件:

  • 纯文本编辑器(IDE):虽然任何纯文本编辑器都可以工作,但诸如Microsoft Visual Studio Code之类的集成开发环境(IDE)可提供高级功能,以便于编辑。

  • Git: ​管理代码更改需要此版本控制系统。 如果未安装,请从https://git-scm.com下载。

创建自定义功能 create-custom-function

创建自定义函数的步骤包括:

使用AEM项目原型创建客户端库 create-client-library-archetype

您可以向使用AEM项目原型🔗创建的项目中添加客户端库,从而添加自定义函数。
如果您现有项目,则可以直接将自定义函数添加到本地项目。

创建原型项目或使用现有项目后,请创建客户端库。 要创建客户端库,请执行以下步骤:

添加客户端库文件夹

要将新的客户端库文件夹添加到[AEM项目目录],请执行以下步骤:

  1. 在编辑器中打开[AEM项目目录]。

    自定义函数文件夹结构

  2. 找到ui.apps

  3. 添加新文件夹。 例如,添加名为experience-league的文件夹。

  4. 导航到/experience-league/文件夹并添加ClientLibraryFolder。 例如,创建一个名为customclientlibs的客户端库文件夹。

    位置为: [AEM project directory]/ui.apps/src/main/content/jcr_root/apps/

将文件和文件夹添加到客户端库文件夹

将以下内容添加到添加的客户端库文件夹:

  • .content.xml文件
  • js.txt文件
  • js文件夹

Location is: [AEMaaCS project directory]/ui.apps/src/main/content/jcr_root/apps/experience-league/customclientlibs/

  1. .content.xml中,添加以下代码行:

    code language-javascript
    <?xml version="1.0" encoding="UTF-8"?>
    <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:ClientLibraryFolder"
    categories="[customfunctionscategory]"/>
    
    note note
    NOTE
    您可以为client library foldercategories属性选择任意名称。
  2. js.txt中,添加以下代码行:

    code language-javascript
          #base=js
        function.js
    
  3. js文件夹中,将javascript文件添加为function.js,其中包含自定义函数:

    code language-javascript
    /**
        * Calculates Age
        * @name calculateAge
        * @param {object} field
        * @return {string}
    */
    
    function calculateAge(field) {
    var dob = new Date(field);
    var now = new Date();
    
    var age = now.getFullYear() - dob.getFullYear();
    var monthDiff = now.getMonth() - dob.getMonth();
    
    if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < dob.getDate())) {
    age--;
    }
    
    return age;
    }
    
  4. 保存文件。

自定义函数文件夹结构

在filter.xml中包含新文件夹

  1. 导航到[AEMaaCS项目目录]中的/ui.apps/src/main/content/META-INF/vault/filter.xml文件。

  2. 打开文件,并在末尾添加以下行:

    <filter root="/apps/experience-league" />

  3. 保存文件。

    自定义函数筛选器xml

  4. 按照如何生成部分中给出的步骤将新创建的客户端库文件夹生成到您的AEM环境。

通过CRXDE创建和部署自定义函数 create-add-custom-function

如果您使用最新的AEM Forms和Forms加载项,则可以通过CRXDE创建自定义函数,以使用自定义函数的最新更新。 为此,请执行以下步骤:

  1. 登录http://server:port/crx/de/index.jsp#

  2. /apps 文件夹下创建一个文件夹。例如,创建名为experience-league的文件夹。

  3. 保存更改。

  4. 导航到已创建的文件夹,并创建类型为cq:ClientLibraryFolder的节点作为clientlibs

  5. 导航到新创建的clientlibs文件夹并添加allowProxycategories属性:

    自定义库节点属性

    note note
    NOTE
    您可以提供任意名称来取代customfunctionsdemo
  6. 保存更改。

  7. clientlibs文件夹下创建名为js的文件夹。

  8. js文件夹下创建名为functions.js的JavaScript文件。

  9. clientlibs文件夹下创建名为js.txt的文件。

  10. 保存更改。
    创建的文件夹结构如下所示:

    创建的客户端库文件夹结构

  11. 双击functions.js文件以打开编辑器。 该文件包含自定义函数的代码。
    让我们将以下代码添加到JavaScript文件中,以根据出生日期计算年龄(YYYY-MM-DD)。

    code language-javascript
        /**
             * Calculates Age
             * @name calculateAge
             * @return {string}
        */
    
        function calculateAge(dateOfBirthString) {
        var dob = new Date(dateOfBirthString);
        var now = new Date();
    
        var age = now.getFullYear() - dob.getFullYear();
        var monthDiff = now.getMonth() - dob.getMonth();
    
        if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < dob.getDate())) {
        age--;
        }
    
        return age;
        }
    
  12. 保存function.js

  13. 导航到js.txt并添加以下代码:

    code language-javascript
        #base=js
        functions.js
    
  14. 保存 js.txt 文件。

您可以引用以下自定义函数文件夹。 在您的AEM实例上下载并安装此文件夹。

现在,您可以通过添加客户端库在自适应表单中使用自定义函数。

在自适应表单中添加客户端库 add-client-library

将客户端库部署到AEM Forms环境后,请在自适应表单中使用其功能。 在自适应表单中添加客户端库

  1. 在编辑模式下打开表单。 若要在编辑模式下打开表单,请选择一个表单,然后选择​ 编辑

  2. 打开内容浏览器,然后选择自适应表单的​ 指南容器 ​组件。

  3. 单击指南容器属性图标。 这将打开“自适应表单容器”对话框。

  4. 打开​ 基本 ​选项卡,并从下拉列表中选择​ 客户端库类别 ​的名称(在本例中,选择customfunctionscategory)。

    正在添加自定义函数客户端库

  5. 单击​ 完成

现在,您可以创建一个规则以在规则编辑器中使用自定义函数:

正在添加自定义函数客户端库

现在,让我们了解如何在AEM Forms 6.5🔗中使用规则编辑器的调用服务来配置和使用自定义函数

在自适应表单中使用自定义函数 use-custom-functions

在自适应表单中,您可以在规则编辑器🔗中使用自定义函数。
让我们将以下代码添加到JavaScript文件(Function.js文件)中,以根据出生日期(YYYY-MM-DD)计算年龄。 创建自定义函数作为calculateAge(),它将出生日期作为输入并返回年龄:

    /**
        * Calculates Age
        * @name calculateAge
        * @param {object} field
        * @return {string}
    */

    function calculateAge(field) {
    var dob = new Date(field);
    var now = new Date();

    var age = now.getFullYear() - dob.getFullYear();
    var monthDiff = now.getMonth() - dob.getMonth();

    if (monthDiff < 0 || (monthDiff === 0 && now.getDate() < dob.getDate())) {
    age--;
    }

    return age;
    }

在上例中,当用户以(YYYY-MM-DD)格式输入出生日期时,将调用自定义函数calculateAge并返回年龄。

在规则编辑器中计算Age自定义函数

让我们预览表单,观察自定义函数如何通过规则编辑器实现:

在规则编辑器表单预览中计算Age自定义函数

NOTE
您可以引用以下自定义函数文件夹。 使用包管理器在AEM实例中下载并安装此文件夹。

在自定义函数中支持异步函数 support-of-async-functions

异步自定义函数未出现在规则编辑器列表中。 但是,可以在使用同步函数表达式创建的自定义函数中调用异步函数。

同步和异步自定义函数

NOTE
在自定义函数中调用异步函数的优势在于,异步函数允许并行执行多个任务,并且自定义函数中使用了每个函数的结果。

查看以下代码,了解如何使用自定义函数调用异步函数:


    async function asyncFunction() {
    const response = await fetch('https://petstore.swagger.io/v2/store/inventory');
    const data = await response.json();
    return data;
    }

    /**
    * callAsyncFunction
    * @name callAsyncFunction callAsyncFunction
    */
    function callAsyncFunction() {
    asyncFunction()
        .then(responseData => {
        console.log('Response data:', responseData);
        })
        .catch(error => {
         console.error('Error:', error);
    });
}

在上述示例中,asyncFunction函数是asynchronous function。 它通过向https://petstore.swagger.io/v2/store/inventory发出GET请求来执行异步操作。 它使用await等待响应,使用response.json()将响应正文解析为JSON,然后返回数据。 callAsyncFunction函数是一个同步自定义函数,它调用asyncFunction函数并在控制台中显示响应数据。 虽然callAsyncFunction函数是同步的,但它调用异步asyncFunction函数并使用thencatch语句处理其结果。

要查看其是否有效,让我们添加一个按钮,并为按钮创建一个规则,该规则会在单击按钮时调用异步函数。

为异步函数创建规则

请参考控制台窗口的插图以演示当用户单击Fetch按钮时,将调用自定义函数callAsyncFunction,进而调用异步函数asyncFunction。 在控制台窗口中Inspect以查看按钮单击时的响应:

控制台窗口

让我们深入了解一下自定义函数的功能。

自定义函数的各种功能

您可以使用自定义函数向表单添加个性化功能。 这些函数支持各种功能,例如使用特定字段、使用全局字段或缓存。 这种灵活性允许您根据组织的要求自定义表单。

自定义函数中的字段和全局范围对象 support-field-and-global-objects

字段对象是指表单中的单个组件或元素,例如文本字段和复选框。 全局对象包含只读变量,例如表单实例、目标字段实例以及在自定义函数中修改表单的方法。

NOTE
param {scope} globals必须是最后一个参数,它不会显示在自适应表单的规则编辑器中。

让我们了解自定义函数如何在Contact Us表单的帮助下使用字段和全局对象,该表单使用不同的用例。

与我们联系表单

用例:使用SetProperty规则显示面板

将以下代码添加到create-custom-function部分中说明的自定义函数中,以将表单字段设置为Required


    /**
    * enablePanel
    * @name enablePanel
    * @param {object} field1
    * @param {object} field2
    * @param {scope} globals
    */

    function enablePanel(field1,field2, globals)
    {
       if(globals.functions.validate(field1).length === 0)
       {
       globals.functions.setProperty(field2, {visible: true});
       }
    }
NOTE
  • 您可以使用位于[form-path]/jcr:content/guideContainer.model.json中的可用属性配置字段属性。
  • 使用Globals对象的setProperty方法对该表单进行的修改是异步的,在执行自定义函数期间不会反映这些修改。

在此示例中,personaldetails面板的验证是在单击按钮时进行的。 如果在面板中未检测到错误,则单击按钮后,另一个面板(feedback面板)将变为可见。

让我们为Next按钮创建一个规则,该规则将验证personaldetails面板,并在用户单击Next按钮时使feedback面板可见。

设置属性

请参阅下图以演示单击Next按钮时验证personaldetails面板的位置。 如果personaldetails中的所有字段都已验证,feedback面板将变为可见。

设置属性表单预览

如果personaldetails面板的字段中存在错误,则单击Next按钮时会在字段级别显示这些错误,并且feedback面板将保持不可见。

设置属性表单预览

用例:验证字段。

按照create-custom-function部分中的说明,在自定义函数中添加以下代码以验证字段。

    /**
    * validateField
    * @name validateField
    * @param {object} field
    * @param {scope} globals
    */
    function validateField(field,globals)
    {

        globals.functions.validate(field);

    }
NOTE
如果未在validate()函数中传递任何参数,它将验证表单。

在此示例中,自定义验证模式应用于contact字段。 用户需要输入以10开头后接8位数的电话号码。 如果用户输入的电话号码不以10开头或包含多或少8位数,则单击该按钮时将显示验证错误消息:

电子邮件地址验证模式

现在,下一步是为Next按钮创建一个规则,以验证单击按钮时的contact字段。

验证模式

请参阅下图以演示,如果用户输入的电话号码不是以10开头,则在字段级别将显示错误消息:

电子邮件地址验证模式

如果用户输入有效的电话号码并且验证personaldetails面板中的所有字段,屏幕上会显示feedback面板:

电子邮件地址验证模式

用例:重置面板

按照create-custom-function部分中的说明,在自定义函数中添加以下代码以重置面板。

    /**
    * resetField
    * @name  resetField
    * @param {string} input1
    * @param {object} field
    * @param {scope} globals
    */
    function  resetField(field,globals)
    {

        globals.functions.reset(field);

    }
NOTE
如果未在reset()函数中传递任何参数,它将验证表单。

在此示例中,personaldetails面板在单击Clear按钮时重置。 下一步是为Clear按钮创建一个规则,该规则将在单击按钮时重置面板。

清除按钮

请参阅下图以显示,如果用户单击clear按钮,personaldetails面板将重置:

重置表单

用例:在字段级别显示自定义消息并将字段标记为无效

您可以使用markFieldAsInvalid()函数将字段定义为无效,并在字段级别设置自定义错误消息。 fieldIdentifier值可以是fieldIdfield qualifiedNamefield dataRef。 名为option的对象的值可以是{useId: true}{useQualifiedName: true}{useDataRef: true}
用于将字段标记为无效并设置自定义消息的语法包括:

  • globals.functions.markFieldAsInvalid(field.$id,"[custom message]",{useId: true});
  • globals.functions.markFieldAsInvalid(field.$qualifiedName, "[custom message]", {useQualifiedName: true});
  • globals.functions.markFieldAsInvalid(field.$dataRef, "[custom message]", {useDataRef: true});

按照create-custom-function部分中的说明,在自定义函数中添加以下代码,以在字段级别启用自定义消息。

    /**
    * customMessage
    * @name customMessage
    * @param {object} field
    * @param {scope} globals
    */
    function customMessage(field, globals) {
    const minLength = 15;
    const comments = field.$value.trim();
    if (comments.length < minLength) {
        globals.functions.markFieldAsInvalid(field.$id, "Comments must be at least 15 characters long.", { useId: true });
    }
}

在此示例中,如果用户在“注释”文本框中输入的字符数少于15个,则会在字段级别显示自定义消息。

下一步是为comments字段创建规则:

将字段标记为无效

请参阅下面的演示,说明在comments字段中输入负反馈会触发字段级别的自定义消息显示:

将字段标记为无效的预览表单

如果用户在“评论”文本框中输入的字符超过15个,则验证该字段并提交表单:

将字段标记为有效的预览表单

用例:将更改的数据提交到服务器

以下代码行:
globals.functions.submitForm(globals.functions.exportData(), false);用于在操作后提交表单数据。

  • 第一个参数是要提交的数据。
  • 第二个参数表示在提交之前是否验证表单。 它是optional,默认设置为true
  • 第三个参数是提交的contentType,该参数也是可选的,默认值是multipart/form-data。 其他值可以是application/jsonapplication/x-www-form-urlencoded

按照create-custom-function部分中的说明,在自定义函数中添加以下代码,以在服务器上提交操作数据:

    /**
    * submitData
    * @name submitData
    * @param {object} field
    * @param {scope} globals
    */
    function submitData(globals)
    {

    var data = globals.functions.exportData();
    if(!data.comments) {
    data.comments = 'NA';
    }
    console.log('After update:{}',data);
    globals.functions.submitForm(data, false);
    }

在此示例中,如果用户将comments文本框留空,则NA在提交表单时提交给服务器。

现在,为提交数据的Submit按钮创建规则:

提交数据

请参阅以下console window的图示,以演示如果用户将comments文本框留空,则在服务器上提交值为NA

在控制台窗口提交数据

您还可以检查控制台窗口以查看提交到服务器的数据:

在控制台窗口 Inspect数据

对自定义函数的缓存支持

自适应Forms在规则编辑器中检索自定义函数列表时,为自定义函数实施缓存以增强响应时间。 error.log文件中显示一条消息,名称为Fetched following custom functions list from cache

支持缓存的 自定义函数

如果修改了自定义函数,缓存将失效,并且会进行解析。

疑难解答 troubleshooting

  • 用户需要确保核心组件和规范版本设置为最新版本。 但是,对于现有AEM项目和表单,还需要执行其他步骤:

    • 对于AEM项目,用户应使用submitForm()替换submitForm('custom:submitSuccess', 'custom:submitError')的所有实例并部署该项目。

    • 对于现有表单,如果自定义提交处理程序无法正常运行,用户需要使用规则编辑器在​ 提交 ​按钮上打开并保存submitForm规则。 此操作将submitForm('custom:submitSuccess', 'custom:submitError')中的现有规则替换为表单中的submitForm()

  • 如果包含自定义函数代码的JavaScript文件出错,则自定义函数不会列在自适应表单的规则编辑器中。 要检查自定义函数列表,您可以导航到error.log文件以查找错误。 如果出现错误,自定义函数列表显示为空:

    错误日志文件

    如果没有错误,则会获取自定义函数并显示在error.log文件中。 error.log文件中显示一条消息,名称为Fetched following custom functions list

    使用正确的自定义函数 错误日志文件

注意事项

  • parameter typereturn type不支持None

  • 自定义函数列表中不支持的函数包括:

    • 生成器函数
    • 异步/等待函数
    • 方法定义
    • 类方法
    • 默认参数
    • Rest参数
recommendation-more-help
19ffd973-7af2-44d0-84b5-d547b0dffee2