MTAppMultiForm

指定した要素を、チェックボックス・ラジオボタン・ドロップダウンのいずれかに置き換えるメソッドです。選択された値はカンマ区切りで元のフィールドへ書き戻されます。P7 では本体から削除しており、互換コードを掲載しています。

このメソッドは MTAppjQuery P7 には同梱していません(非推奨)。

同じことは PowerCMS 標準のカスタムフィールド型「チェックボックス(複数選択)」「ドロップダウン(複数選択)」 で実現できます。新しく作る場合は標準のフィールド型をお使いください。JavaScript を書く必要がなく、入力値の検証やテンプレートタグでの取り出しも PowerCMS 側で面倒を見てくれます。

標準のフィールド型では対応できない場面(例: MTAppJSONTable のセル内の入力欄を選択式にしたい場合。カスタムフィールド型はテーブルのセル内には適用できません)に限り、このページのコードを user.js にコピーしてお使いください。

指定した要素を、チェックボックス・ラジオボタン・ドロップダウンのいずれかに置き換えるメソッドです。選択された値はカンマ区切りで元のフィールドへ書き戻されます。

P5 では本体に同梱していましたが、PowerCMS 7 の標準機能と重複するため P7 では削除しました。すでに user.js で使用中の場合は、下記のコードを user.js に貼り付ければ、呼び出し方・オプション名を変えずにそのまま動作します。

構文

$(selector).MTAppMultiForm(options);

jQuery プラグイン($.fn.MTAppMultiForm)です。対象は input または textarea です。

パラメータ

options {Object} — 省略可。以下のプロパティを持ちます。

プロパティ既定値説明
typestring''生成する形式。'checkbox' / 'radio' / 'select' / 'select.multiple' のいずれか。必須(未指定の場合は何もしません)
itemsArray[]選択肢の配列。必須(空配列の場合は何もしません)
stylesstring'height: auto;'type'select.multiple' のときに select へ付与する style 属性
debugbooleanfalsetrue で元のフィールドを隠さず表示したままにする

戻り値

{jQuery} — 対象の jQuery オブジェクト(メソッドチェーン可)。

保存される値

選択された値をカンマ区切りで連結した文字列が、元のフィールドに保存されます(例: A,B,C)。'checkbox''select.multiple' は複数値、'radio''select' は単一値になります。

読み込み時は、元のフィールドの値をカンマで分割し、前後の空白を除いたうえで items と突き合わせて選択状態を復元します。items に無い値は選択状態として復元されません。

使用例

// カスタムフィールドをチェックボックス群にする
$('#customfield_tags').MTAppMultiForm({
    type: 'checkbox',
    items: ['お知らせ', 'イベント', '採用情報']
});

// ドロップダウンにする
$('#customfield_layout').MTAppMultiForm({
    type: 'select',
    items: ['▼レイアウト選択', '左画像右テキスト', '右画像左テキスト']
});

// MTAppJSONTable のセル内の入力欄をドロップダウンにする
$('#customfield_paragraph').MTAppJSONTable({
    header: { body: '本文', layout: 'レイアウト指定' },
    headerOrder: ['body', 'layout'],
    headerPosition: 'left',
    cbAfterBuild: function (cb, $container) {
        $container.find('td.layout .jsontable-input').MTAppMultiForm({
            type: 'select',
            items: ['▼レイアウト選択', '左画像右テキスト', '右画像左テキスト']
        });
    }
});

生成される HTML

元のフィールドの直後に span を挿入します。spanid は、元のフィールドに id があれば mtappmltform-<元のid>、無ければ mtappmltform-<type>-<ランダムな文字列> になります。

<!-- type: 'checkbox' の場合 -->
<span id="mtappmltform-customfield_tags" class="mtappmultiform mtappmultiform-checkbox">
  <label><input type="checkbox" value="お知らせ">お知らせ</label>
  <label><input type="checkbox" value="イベント">イベント</label>
</span>

<!-- type: 'select' の場合 -->
<span id="mtappmltform-customfield_layout" class="mtappmultiform mtappmultiform-select">
  <select>
    <option value="左画像右テキスト">左画像右テキスト</option>
  </select>
</span>

type'select' / 'select.multiple' の場合は、適用直後にも元のフィールドへの書き戻しを行います。そのため、値が未設定のときは選択肢の先頭が既定値として保存されます。

コード

以下を user.js の先頭(各メソッドの呼び出しより前)に貼り付けてください。

(function ($) {
    /**
     * 指定した要素を、チェックボックス・ラジオボタン・ドロップダウンのいずれかに置き換える。
     * 選択された値はカンマ区切りで元のフィールドへ書き戻される。
     *
     * @param {Object}   [options]
     * @param {string}   [options.type='']                'checkbox' / 'radio' / 'select' / 'select.multiple'
     * @param {Array}    [options.items=[]]               生成する選択肢
     * @param {string}   [options.styles='height: auto;'] type が 'select.multiple' のときの style 属性
     * @param {boolean}  [options.debug=false]            true で元のフィールドを表示したままにする
     */
    $.fn.MTAppMultiForm = function (options) {
        const op = $.extend({}, $.fn.MTAppMultiForm.defaults, options);

        return this.each(function () {
            if (!op.type || op.items.length === 0) {
                return;
            }
            const $this = op.debug ? $(this) : $(this).hide();

            const currentValue = $this.val();
            const selected = currentValue
                ? currentValue.split(',').map((v) => v.replace(/^\s+|\s+$/g, ''))
                : [];

            const wrapId = $this.attr('id')
                ? `mtappmltform-${$this.attr('id')}`
                : `mtappmltform-${op.type.replace('.multiple', '')}-${$.temporaryId()}`;

            const $wrap = $('<span>', {
                id: wrapId,
                'class': `mtappmultiform mtappmultiform-${op.type.replace('.', '-')}`
            });

            const isButton = op.type === 'checkbox' || op.type === 'radio';

            if (isButton) {
                op.items.forEach((item) => {
                    const $input = $('<input>', { type: op.type, value: item })
                        .prop('checked', selected.includes(item));
                    if (op.type === 'radio') {
                        $input.attr('name', `${wrapId}-item`);
                    }
                    // 選択肢のラベルはテキストノードで流し込む(HTML として解釈させない)
                    $wrap.append(
                        $('<label>').append($input).append(document.createTextNode(item))
                    );
                });
            } else {
                const $select = $('<select>');
                if (op.type === 'select.multiple') {
                    $select.attr({ multiple: 'multiple', style: op.styles });
                }
                op.items.forEach((item) => {
                    $select.append(
                        $('<option>', { value: item }).text(item).prop('selected', selected.includes(item))
                    );
                });
                $wrap.append($select);
            }

            $this.after($wrap);

            const writeBack = ($chosen) => {
                const values = $chosen.map(function () {
                    return $(this).val();
                }).get();
                $this.val(values.join(','));
            };

            if (isButton) {
                $wrap.on('click', 'input', function () {
                    writeBack($wrap.find('input:checked'));
                });
            } else {
                // 初期表示時にも書き戻して、選択肢の先頭が既定値として保存されるようにする
                $wrap.on('change', 'select', function () {
                    writeBack($(this).find('option:selected'));
                }).find('select').trigger('change');
            }
        });
    };
    $.fn.MTAppMultiForm.defaults = {
        debug: false,
        type: '', // 'checkbox' / 'radio' / 'select' / 'select.multiple' のいずれか
        items: [],
        styles: 'height: auto;'
    };
})(jQuery);

補足

  • 上記のコードは PowerCMS 7.1 の記事編集画面で動作を確認しています。P5 版から、変数宣言の書き方と選択肢の組み立てを見直していますが、呼び出し方・オプション名・保存される値の形式は P5 と同じです。
  • 選択肢の文字列は HTML としてではなくテキストとして描画されます。items<> を含む文字列を渡しても、タグとして解釈されることはありません。
  • $.temporaryId() は MTAppjQuery 本体が提供するヘルパーです。本体より後に読み込まれる user.js から呼び出す限り、そのまま使えます。
  • 選択肢に無い値が元のフィールドに保存されていた場合、その値は画面上に現れず、いずれかの選択肢を操作した時点で失われます。既存データに含まれる値をすべて items に列挙しておいてください。

関連

  • MTAppMultiCheckbox — 入力欄をチェックボックス群にする。タグ欄への適用に対応し、P7 でも本体に同梱しています。選択肢に無い値を失わない、区切り文字を指定できるなど、MTAppMultiForm より安全に使えます。チェックボックス形式であればこちらを検討してください。
  • MTAppJSONTable — JSON を表形式の UI で編集する。セル内の入力欄を選択式にしたい場合に組み合わせます。
  • P5 からのアップグレード — P7 で削除したメソッドの一覧と代替手段。