MTAppjQuery で Movable Type 8 の記事編集画面に表示するフィールドを選択されたカテゴリごとに切り替える方法をご紹介します。
MTAppjQuery で Movable Type 8 の記事編集画面に表示するフィールドを選択されたカテゴリごとに切り替える方法をご紹介します。
以下の表のように、各フィールドについて、特定のカテゴリが選択されたり選択が解除されたりしたときに、フィールドを表示したり非表示にしたりするようにします。
言い換えると、「◯」となっているフィールドは常に表示で、それ以外のフィールドは「表示するカテゴリ」の列で指定したカテゴリが選択されているときだけ表示されるようになります。
フィールド名 | ベースネーム | 表示するカテゴリ |
---|---|---|
タイトル | title | ◯ |
本文 | text | 当社限定物件 |
概要 | excerpt | ◯ |
担当者名 | staff_name | 当社限定物件 |
郵便番号 | post_code | 公開物件 |
都道府県 | prefecture | 公開物件 |
市区町村 | city | 公開物件 |
番地等 | street | 公開物件 |
最寄駅 | stations | ◯ |
キャプチャで見ると下図のようになります。
はじめに、mtapp.sortDisabled()
を使ってフィールドのドラッグ&ドロップによる並べ替え機能を無効化し、mtapp.fieldSort()
を使ってフィールドを指定通りに並べます。
(function () {
// 記事編集画面のみ動くようにする
if (mtappVars.screen_id === 'edit-entry') {
// ドラッグ&ドロップの並べ替えを無効化
mtapp.sortDisabled();
document.getElementById('display-options').style.display = 'none';
// ベースとなるフィールドの並べ替えと使わないフィールドを非表示
mtapp.fieldSort({
sort: 'title,text,excerpt,customfield_staff_name,customfield_post_code,customfield_prefecture,customfield_city,customfield_street,customfield_stations',
otherFieldHide: true
});
}
})();
続いて下記のようにカテゴリ選択時にフィールドの表示状態を切り替える categoryChanged
関数を作ります。
(function ($) {
/**
* 選択されたカテゴリに基づいてフィールドの表示・非表示を切り替える。
* @param {HTMLElement[]} fields - 表示または非表示にするDOM要素の配列。
* @param {string} ids - 選択されたカテゴリIDのカンマ区切り文字列。
*/
const categoryChanged = (fields, ids) => {
// 選択されたカンマ区切りのカテゴリIDを配列に変換
const selectedIds = ids.split(',');
// 選択されたカテゴリIDからカテゴリ名の配列を取得
const selectedCategories = [];
for (const id of selectedIds) {
const category = window.MT.App.categoryList.find((category) => Number(category.id) === Number(id));
if (category) {
selectedCategories.push(category.label);
}
}
// すべてのフィールドをループして表示・非表示を切り替え
fields.forEach((field) => {
// div.field の id 属性を取得して customfield_ と -field を削除
const basename = field.getAttribute('id').replace(/^customfield_|-field$/g, '');
// フィールドのベースネームと選択されたカテゴリによって表示・非表示を切り替え
// ベースネームが text または staff_name の場合は、当社限定物件のカテゴリが選択されている場合のみ表示
if (['text', 'staff_name'].includes(basename)) {
field.style.display = selectedCategories.includes('当社限定物件') ? 'block' : 'none';
}
// ベースネームが post_code, prefecture, city, street の場合は、公開物件のカテゴリが選択されている場合のみ表示
else if (['post_code', 'prefecture', 'city', 'street'].includes(basename)) {
field.style.display = selectedCategories.includes('公開物件') ? 'block' : 'none';
}
// それ以外のフィールドは常に表示
else {
field.style.display = 'block';
}
});
};
// 記事編集画面のみ動くようにする
if (mtappVars.screen_id === 'edit-entry') {
// 省略
}
})(jQuery);
この関数の第一引数には、表示または非表示を切り替えるフィールド(DOM要素)の配列を渡します。
第二引数には、選択されたカテゴリのIDをカンマ区切りにした文字列を渡します。
フィールドの表示・非表示の切り替えは下記の部分で行なっていますので、この部分( ['text', 'staff_name']
や ['post_code', 'prefecture', 'city', 'street']
など)を適宜環境に合わせて変更してください。
// すべてのフィールドをループして表示・非表示を切り替え
fields.forEach((field) => {
// div.field の id 属性を取得して customfield_ と -field を削除
const basename = field.getAttribute('id').replace(/^customfield_|-field$/g, '');
// フィールドのベースネームと選択されたカテゴリによって表示・非表示を切り替え
// ベースネームが text または staff_name の場合は、当社限定物件のカテゴリが選択されている場合のみ表示
if (['text', 'staff_name'].includes(basename)) {
field.style.display = selectedCategories.includes('当社限定物件') ? 'block' : 'none';
}
// ベースネームが post_code, prefecture, city, street の場合は、公開物件のカテゴリが選択されている場合のみ表示
else if (['post_code', 'prefecture', 'city', 'street'].includes(basename)) {
field.style.display = selectedCategories.includes('公開物件') ? 'block' : 'none';
}
// それ以外のフィールドは常に表示
else {
field.style.display = 'block';
}
});
最後に mtapp.fieldSort()
を使ってフィールドを並べ替えた後でイベントをセットします。
カテゴリが変更されると、#category-ids
の要素で mtappCategoryChanged
イベントが発火されます。なので、そのイベントにバインドする関数の中で categoryChanged
関数が動くようにします。
mtappCategoryChanged
イベントでは、変更後のカテゴリID(カンマ区切り)がイベントオブジェクトから event.detail.newValue
のようにして取得できます。それを categoryChanged
関数の第二引数に渡すようにします。
また、ページを表示した時にも一度 categoryChanged
関数を動かす必要があります。その時は、mtappVars.selectedCategories という変数に選択されているカテゴリIDがセットされていますので、それを categoryChanged
関数の第二引数に渡します。
(function ($) {
const categoryChanged = (fields, ids) => {
// 省略
};
// 記事編集画面のみ動くようにする
if (mtappVars.screen_id === 'edit-entry') {
// ドラッグ&ドロップの並べ替えを無効化
mtapp.sortDisabled();
document.getElementById('display-options').style.display = 'none';
// ベースとなるフィールドの並べ替えと使わないフィールドを非表示
mtapp.fieldSort({
sort: 'title,text,excerpt,customfield_staff_name,customfield_post_code,customfield_prefecture,customfield_city,customfield_street,customfield_stations',
otherFieldHide: true
});
// メインカラムのフィールドをすべて取得
const fields = document.querySelectorAll('#sortable > .field');
// カテゴリの変更を検知するリスナーを設定
document.getElementById('category-ids').addEventListener('mtappCategoryChanged', function (event) {
categoryChanged(fields, event.detail.newValue);
});
// ページを表示した時に実行
categoryChanged(fields, mtappVars.selectedCategories);
}
})(jQuery);
まとめると下記のようなコードになりました。これを user.js に書いてください。また、カテゴリの部分は適宜変更してください。
(function () {
/**
* 選択されたカテゴリに基づいてフィールドの表示・非表示を切り替える。
* @param {HTMLElement[]} fields - 表示または非表示にするDOM要素の配列。
* @param {string} ids - 選択されたカテゴリIDのカンマ区切り文字列。
*/
const categoryChanged = (fields, ids) => {
// 選択されたカンマ区切りのカテゴリIDを配列に変換
const selectedIds = ids.split(',');
// 選択されたカテゴリIDからカテゴリ名の配列を取得
const selectedCategories = [];
for (const id of selectedIds) {
const category = window.MT.App.categoryList.find((category) => Number(category.id) === Number(id));
if (category) {
selectedCategories.push(category.label);
}
}
// すべてのフィールドをループして表示・非表示を切り替え
fields.forEach((field) => {
// div.field の id 属性を取得して customfield_ と -field を削除
const basename = field.getAttribute('id').replace(/^customfield_|-field$/g, '');
// フィールドのベースネームと選択されたカテゴリによって表示・非表示を切り替え
switch (basename) {
case 'text':
case 'staff_name':
field.style.display = selectedCategories.includes('当社限定物件') ? 'block' : 'none';
break;
case 'post_code':
case 'prefecture':
case 'city':
case 'street':
field.style.display = selectedCategories.includes('公開物件') ? 'block' : 'none';
break;
default:
field.style.display = 'block';
}
});
};
// 記事編集画面のみ動くようにする
if (mtappVars.screen_id === 'edit-entry') {
// ドラッグ&ドロップの並べ替えを無効化
mtapp.sortDisabled();
document.getElementById('display-options').style.display = 'none';
// ベースとなるフィールドの並べ替えと使わないフィールドを非表示
mtapp.fieldSort({
sort: 'title,text,excerpt,customfield_staff_name,customfield_post_code,customfield_prefecture,customfield_city,customfield_street,customfield_stations',
otherFieldHide: true
});
// メインカラムのフィールドをすべて取得
const fields = document.querySelectorAll('#sortable > .field');
// カテゴリの変更を検知するリスナーを設定
document.getElementById('category-ids').addEventListener('mtappCategoryChanged', function (event) {
categoryChanged(fields, event.detail.newValue);
});
// ページを表示した時に実行
categoryChanged(fields, mtappVars.selectedCategories);
}
})();