AEM開発者ブログ by YAMATO

アドビ社のデリバリーパートナー大和株式会社のAEM開発者ブログです。

ダイアログの選択肢をJSで生成する【Classic UI】

AEM Developerの皆様お疲れさまです。大和株式会社の狩野です。

Qiitaのアドベントカレンダーに便乗して始めた記事投稿イベント9日目です。
今日9日目の内容は、「ダイアログの選択肢をJSで生成する」です。

8日目の記事→ローカル環境でコードが反映されない時に取る行動

ダイアログの選択肢を動的に作成したい場面はいくつかあると思います。
そういう時にJavascriptで作成が可能なので、今回はその方法について紹介したいと思います。

最初に注意してほしいのですが、今回の記事ではClassicUIでの方法のみです。

本当は、TouchUIでの方法も紹介したかったのですが、コードの検証やサンプルコードを書くのが間に合わなかったので、今日のところはClassicUIのみとさせてください。
一応、下にTouchUIダイアログを動的に作成する方法についての記事を載せますが、後日、こちらのブログでもTouchUIでの方法についても紹介したいと思います。

TouchUIダイアログを動的に作成する方法についてはこちら→Dynamically updating Adobe Experience Manager TouchUI Dialog Select Fields

選択肢の元となるノード

今回、選択肢の元となるノードはデザインダイアログで作成して、それをJavascriptで取得してダイアログの選択肢に利用するという方法を取ります。 最初にそのデザインダイアログを作成します。

design_dialog
    +- items
        | jcr:primaryType = "cq:Widget"
        | xtype = "tabpanel"
        +- items
            | jcr:primaryType = "cq:WidgetCollection"
            +- tab1
                | jcr:primaryType = "cq:Panel"
                | title = "選択肢"
                +- items
                    | jcr:primaryType = "cq:WidgetCollection"
                    +- optionsProvider
                        jcr:primaryType = "cq:Widget"
                        fieldLabel = "ダイアログ選択肢の元となるダイアログ"
                        name = "./options"
                        xtype = "multifield"

このデザインダイアログで選択肢を作成します。

作成したノードから選択肢を利用するダイアログ

デザインダイアログで作成した選択肢を利用するダイアログを作成します。

dialog
    +- items
        | jcr:primaryType = "cq:Widget"
        | xtype = "tabpanel"
        +- items
            | jcr:primaryType = "cq:WidgetCollection"
            +- tab1
                | jcr:primaryType = "cq:Panel"
                | title = "from design"
                +- items
                    | jcr:primaryType = "cq:WidgetCollection"
                    +- fromdesign
                        jcr:primaryType = "cq:Widget"
                        fieldLabel = "デザインダイアログから作成した選択肢"
                        name = "./fromdesign"
                        optionsProvider = "CQ.DialogWidgets.fetchDialogOption"
                        type = "select"
                        xtype = "selection"

ただ、このままでは optionsProvider の中にある CQ.DialogWidgets.fetchDialogOption が定義されていないので動きません。

CQ.dialogWidgets.fetchDialogOption

fetchDialogOptionを含むClientLibrary作成

以下のようなフォルダ構造でClientLibraryフォルダを作成します

dialogWidgets
    | categories = "cq:widgets" //←categoriesにcq:widgetsを加えることによってAuthor時のみ読み込むClientLibsとなる
    +- js
    |   +- optionsProvider.js
    +- js.txt

optionsProvider.js

ダイアログの optionsProvider プロパティで定義した関数が返す連想配列がダイアログの選択肢となります。

CQ.DialogWidgets = CQ.DialogWidgets || {};

CQ.DialogWidgets.fetchDialogOption = function() {
    const designPath = "/etc/designs/test-design/jcr:content/path/to/design";
    const json = CQ.shared.HTTP.eval(designPath + ".json");
    let multiFieldValues = json["options"];
    if (typeof multiFieldValues === "string") {
        multiFieldValues = multiFieldValues.split(",");
    }
    let optionsFromDesign = [];
    for (let option of multiFieldValues) {
        // このvalue, textがダイアログのvalue, textとなる
        optionsFromDesign.push({
            value: option,
            text: option
        })
    }
    return optionsFromDesign;
}

以上の手順を踏めば、デザインダイアログでダイアログ選択肢を作成することができます。
今回はvalueとtextが同じですが、違うようにすることも、optionsProvider.jsを編集すれば可能です。

最後に

以上となります。明日は小林さんが執筆します。内容は「どう使い分ける?編集可能テンプレートのStructureとInitial Content」です。
お楽しみに。