開發及使用自訂函式的範例

本文提供根據核心元件的最適化表單的詳細自訂函式範例,對於在各種情況下有效實施提供寶貴的見解。 自訂函式用於AEM Forms的規則編輯器,可讓開發人員定義及控制控制表單行為的邏輯。
本文探討自訂函式的不同實作,說明如何使用這些函式來量身打造表單以符合特定需求並增強整體功能。

使用自訂函式設定下拉式清單選項

核心元件中的規則編輯器不支援​ 屬性的 ​設定選項以在執行階段設定下拉式清單選項。 不過,您可以使用自訂函式來設定下拉式清單選項。

依照create-custom-function區段中的說明,在自訂函式中新增下列程式碼,以使用自訂函式設定下拉式清單選項:

    /**
    * @name setEnums
    * @returns {string[]}
    **/
    function setEnums() {
    return ["0","1","2","3","4","5","6"];
    }

    /**
    * @name setEnumNames
    * @returns {string[]}
    **/
    function setEnumNames() {
    return ["Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    }

在上述程式碼中,setEnums是用來設定enum屬性,setEnumNames是用來設定下拉式清單的enumNames屬性。

讓我們為Next按鈕建立規則,當使用者按一下Next按鈕時,此規則會設定下拉式清單選項的值:

下拉式清單選項

請參考下圖,示範按一下「顯示」按鈕時,下拉式清單的選項設定位置:

規則編輯器中的下拉式清單選項

使用SetProperty規則顯示面板

讓我們瞭解自訂函式如何透過Contact Us表單使用欄位和全域物件。

連絡我們表單

在自訂函式中新增下列程式碼(如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」面板將保持隱藏狀態。

設定屬性表單預覽

驗證欄位

讓我們瞭解自訂函式如何透過Contact Us表單使用欄位和全域物件來驗證欄位。

依照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面板就會顯示在畫面上:

電子郵件地址驗證模式

重設面板

讓我們瞭解自訂函式如何在Contact Us表單的協助下,使用欄位和全域物件來重設欄位。

依照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()函式中傳遞引數,則會驗證表單。

在此範例中,按一下Clear按鈕時,personaldetails面板會重設。 下一步是為Clear按鈕建立規則,以在按鈕點選時重設面板。

清除按鈕

請參閱下圖以顯示,如果使用者按一下clear按鈕,personaldetails面板會重設:

重設表單

在欄位層級顯示自訂訊息並將欄位標籤為無效的方式

讓我們瞭解自訂函式如何使用欄位和全域物件在欄位層級顯示自訂訊息,並透過Contact Us表單將欄位標籤為無效。

您可以使用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個字元,該欄位將會驗證並提交表單:

將欄位標示為有效的預覽表單

將變更的資料提交至伺服器

讓我們瞭解自訂函式如何在Contact Us表單的協助下,使用欄位和全域物件在伺服器上提交已處理的資料。

下列程式碼行:
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資料

覆寫表單提交成功和錯誤處理常式

讓我們瞭解自訂函式如何在Contact Us表單的協助下,使用欄位和全域物件來覆寫提交處理常式。

新增下列程式碼行(如create-custom-function區段中所述),以自訂表單提交的提交或失敗訊息,並在強制回應方塊中顯示表單提交訊息:

/**
 * Handles the success response after a form submission.
 *
 * @param {scope} globals - This object contains a read-only form instance, target field instance, triggered event, and methods for performing form modifications within custom functions.
 * @returns {void}
 */
function customSubmitSuccessHandler(globals) {
    var event = globals.event;
    var submitSuccessResponse = event.payload.body;
    var form = globals.form;

    if (submitSuccessResponse) {
        if (submitSuccessResponse.redirectUrl) {
            window.location.href = encodeURI(submitSuccessResponse.redirectUrl);
        } else if (submitSuccessResponse.thankYouMessage) {
            showModal("success", submitSuccessResponse.thankYouMessage);
        }
    }
}

/**
 * Handles the error response after a form submission.
 *
 * @param {string} customSubmitErrorMessage - The custom error message.
 * @param {scope} globals - This object contains a read-only form instance, target field instance, triggered event, and methods for performing form modifications within custom functions.
 * @returns {void}
 */
function customSubmitErrorHandler(customSubmitErrorMessage, globals) {
    showModal("error", customSubmitErrorMessage);
}
function showModal(type, message) {
    // Remove any existing modals
    var existingModal = document.getElementById("modal");
    if (existingModal) {
        existingModal.remove();
    }

    // Create the modal dialog
    var modal = document.createElement("div");
    modal.setAttribute("id", "modal");
    modal.setAttribute("class", "modal");

    // Create the modal content
    var modalContent = document.createElement("div");
    modalContent.setAttribute("class", "modal-content");

    // Create the modal header
    var modalHeader = document.createElement("div");
    modalHeader.setAttribute("class", "modal-header");
    modalHeader.innerHTML = "<h2>" + (type === "success" ? "Thank You" : "Error") + "</h2>";

    // Create the modal body
    var modalBody = document.createElement("div");
    modalBody.setAttribute("class", "modal-body");
    modalBody.innerHTML = "<p class='" + type + "-message'>" + message + "</p>";

    // Create the modal footer
    var modalFooter = document.createElement("div");
    modalFooter.setAttribute("class", "modal-footer");

    // Create the close button
    var closeButton = document.createElement("button");
    closeButton.setAttribute("class", "close-button");
    closeButton.innerHTML = "Close";
    closeButton.onclick = function() {
        modal.remove();
    };

    // Append the elements to the modal content
    modalFooter.appendChild(closeButton);
    modalContent.appendChild(modalHeader);
    modalContent.appendChild(modalBody);
    modalContent.appendChild(modalFooter);

    // Append the modal content to the modal
    modal.appendChild(modalContent);

    // Append the modal to the document body
    document.body.appendChild(modal);
}

在此範例中,當使用者使用customSubmitSuccessHandlercustomSubmitErrorHandler自訂函式時,成功和失敗訊息會顯示在強制回應視窗中。 JavaScript函式showModal(type, message)可用來在熒幕上動態建立及顯示模型對話方塊。

現在,為成功的表單提交建立規則:

表單提交成功

請參考下圖以示範,成功提交表單時,成功訊息會顯示於強制回應視窗中:

表單提交成功訊息

同樣地,讓我們為失敗的表單提交建立規則:

表單提交失敗

請參考下圖以示範,當表單提交失敗時,強制回應視窗中會顯示錯誤訊息:

表單提交失敗訊息

若要以預設方式顯示表單提交成功與失敗,Default submit Form Success HandlerDefault submit Form Error Handler函式為現成可用。

如果自訂提交處理常式無法在現有AEM專案或表單中如預期般執行,請參閱疑難排解區段。

在可重複面板的特定執行個體中執行動作

使用可重複面板上的視覺化規則編輯器建立的規則會套用至可重複面板的最後一個例項。 若要為可重複面板的特定執行個體編寫規則,我們可以使用自訂函式。

讓我們建立另一個表格做為Booking Form,以收集前往目的地的旅行者相關資訊。 將旅行者面板新增為可重複的面板,使用者可在其中使用Add Traveler按鈕新增5個旅行者的詳細資料。

旅行者資訊

新增下列程式碼行(如create-custom-function區段中所述),以於可重複面板的特定執行個體中執行動作,而非最後一個執行個體:

/**
* @name hidePanelInRepeatablePanel
* @param {scope} globals
*/
function hidePanelInRepeatablePanel(globals)
{
    var repeatablePanel = globals.form.travelerinfo;
    // hides a panel inside second instance of repeatable panel
    globals.functions.setProperty(repeatablePanel[1].traveler, {visible : false});
}

在此範例中,hidePanelInRepeatablePanel自訂函式會在可重複面板的特定執行個體中執行動作。 在上述程式碼中,travelerinfo代表可重複的面板。 repeatablePanel[1].traveler, {visible: false}程式碼會在可重複面板的第二個執行個體中隱藏面板。

讓我們新增標示為Hide的按鈕,並新增規則以隱藏可重複面板的第二個執行個體。

隱藏面板規則

請參考以下影片,示範按一下Hide時,第二個可重複執行個體中的面板會隱藏:

表單載入時使用值預先填寫欄位

讓我們瞭解自訂函式如何在Booking Form的協助下,使用欄位和全域物件來預先填入欄位。

新增下列程式碼行(如create-custom-function區段中所述),以在表單初始化時載入欄位中的預先填入值:

/**
 * Tests import data
 * @name testImportData
 * @param {scope} globals
 */
function testImportData(globals)
{
    globals.functions.importData(Object.fromEntries([['amount','10000']]));
}

在上述程式碼中,當表單載入時,testImportData函式會預填Booking Amount文字方塊欄位。 我們假設預訂表單要求最低預訂金額為10,000

讓我們在表單初始化時建立規則,當表單載入時,Booking Amount文字方塊欄位中的值會預先填入指定的值:

匯入資料規則

請參考下列熒幕擷圖,以示範當表單載入時,Booking Amount文字方塊中的值會預先填入指定的值:

匯入資料規則表單

聚焦在特定欄位

讓我們瞭解自訂函式如何在Booking Form的協助下,使用欄位和全域物件來設定特定欄位的焦點。

新增下列程式碼行(如create-custom-function區段中所述),以便在按一下Submit按鈕時將焦點設定在指定的欄位上:

/**
 * @name testSetFocus
 * @param {object} emailField
 * @param {scope} globals
 */
    function testSetFocus(field, globals)
    {
        globals.functions.setFocus(field);
    }

讓我們在Submit按鈕中新增規則,以便在按一下Email ID文字方塊欄位時設定焦點:

設定焦點規則

請參閱下列熒幕擷圖,示範按一下Submit按鈕時,焦點設定在Email ID欄位上:

設定焦點規則

NOTE
如果您想要專注在相對於email欄位的下一個或上一個欄位,可以使用選用的$focusOption引數。

使用dispatchEvent屬性新增或刪除可重複的面板

讓我們瞭解自訂函式如何在Booking Form的協助下,使用dispatchEvent屬性使用欄位和全域物件來新增或刪除可重複的面板。

新增下列程式碼行(如create-custom-function區段中所述),以在使用dispatchEvent屬性按一下Add Traveler按鈕時新增面板:

/**
 * Tests add instance with dispatchEvent
 * @name testAddInstance
 * @param {scope} globals
 */
function testAddInstance(globals)
{
    var repeatablePanel = globals.form.traveler;
    globals.functions.dispatchEvent(repeatablePanel,'addInstance');
}

讓我們在Add Traveler按鈕中新增規則,以便在點選時新增可重複面板:

新增面板規則

請參考下方的gif,示範按一下Add Traveler按鈕時,使用dispatchEvent屬性新增面板:

新增面板

同樣地,新增下列程式碼行(如create-custom-function區段中所述),以便在使用dispatchEvent屬性按一下Delete Traveler按鈕時刪除面板:

/**

 * @name testRemoveInstance
 * @param {scope} globals
 */
function testRemoveInstance(globals)
{
    var repeatablePanel = globals.form.traveler;
    globals.functions.dispatchEvent(repeatablePanel, 'removeInstance');
}

讓我們在Delete Traveler按鈕中新增規則,以便在點選重複面板時將其刪除:

刪除面板規則

請參考下方的gif,示範按一下Delete Traveler按鈕時,會使用dispatchEvent屬性刪除旅行者面板:

刪除面板

疑難排解

  • 如果自訂提交處理常式無法在現有AEM專案或表單中如預期般執行,請執行下列步驟:

    • 請確定核心元件版本已更新至3.0.18和更新版本。 不過,對於現有的AEM專案和表單,還有其他要遵循的步驟:

    • 對於AEM專案,使用者應使用submitForm()取代submitForm('custom:submitSuccess', 'custom:submitError')的所有執行個體,並透過Cloud Manager管道部署專案。

    • 針對現有表單,如果自訂提交處理常式無法正常運作,使用者需要使用規則編輯器在​ 提交 ​按鈕上開啟並儲存submitForm規則。 此動作將表單中submitForm('custom:submitSuccess', 'custom:submitError')的現有規則取代為submitForm()

另請參閱

recommendation-more-help
fbcff2a9-b6fe-4574-b04a-21e75df764ab