Last active
October 7, 2021 03:46
-
-
Save fddcddhdd/95cf9a4d5090cf886055 to your computer and use it in GitHub Desktop.
kintoneで大中小カテゴリーなど親子関係にあるプルダウンを実現するためのjavascript(マスタは他のアプリ)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// カテゴリーマスタ・アプリの情報 | |
var MASTER_CATEGORY_APP_NO = 1; | |
var MASTER_CATEGORY_QUERY = ' 有効フラグ in ("ON") '; | |
var MASTER_BIG_CATEGORY_NAME = '大カテゴリ'; | |
var MASTER_MIDDLE_CATEGORY_NAME = '中カテゴリ'; | |
var MASTER_SMALL_CATEGORY_NAME = '小カテゴリ'; | |
// プルダウンの値を格納するフィールド名(このJSを読み込んでいるアプリ) | |
var BIG_CATEGORY_NAME = '大'; | |
var MIDDLE_CATEGORY_NAME = '中'; | |
var SMALL_CATEGORY_NAME = '小'; | |
(function () { | |
//別kintoneアプリからの取得クラス変数 | |
var getRecordMethod; | |
// 新規レコード追加・編集画面になったら | |
kintone.events.on(['app.record.create.show','app.record.edit.show'], function (event) { | |
// 元々ある大中小のテキスト入力フィールドは非表示にする(表示・操作はプルダウンだけにしたい) | |
kintone.app.record.setFieldShown(BIG_CATEGORY_NAME, false); | |
kintone.app.record.setFieldShown(MIDDLE_CATEGORY_NAME, false); | |
kintone.app.record.setFieldShown(SMALL_CATEGORY_NAME, false); | |
// 既存レコードの場合、選択済のカテゴリーの値を、変数に格納する。 | |
var big_cat_selected = event["record"][BIG_CATEGORY_NAME]["value"]; | |
var middle_cat_selected = event["record"][MIDDLE_CATEGORY_NAME]["value"]; | |
var small_cat_selected = event["record"][SMALL_CATEGORY_NAME]["value"]; | |
// 大中小のプルダウンを表示するエリアを生成 | |
var mySpaceField = kintone.app.record.getSpaceElement('my_space_field'); | |
// 別アプリである「カテゴリーマスタ」のデータを入れる連想配列を初期化 | |
var hashItems = new Array(); | |
//別kintoneアプリからの取得クラスを生成(リロードや二回目の編集を考慮して初期化) | |
getRecordMethod = new KintoneRecordManager(); | |
getRecordMethod.records = []; | |
getRecordMethod.offset = 0; | |
//全てのレコードセットをグローバル変数に格納(WebAPI経由なので1秒位かかる) | |
getRecordMethod.getRecords(function(records) { | |
// 0件なら何もしない | |
if (records.length == 0) { | |
mySpaceField.innerHTML = 'マスタアプリにレコードがありません'; | |
return; | |
} | |
// マスタアプリのデータを、ローカルの連想配列に格納 | |
for (var i = 0; i < records.length; i++) { | |
var record = records[i]; | |
hashItems[i] = { | |
big_cat: record[MASTER_BIG_CATEGORY_NAME]["value"], | |
middle_cat: record[MASTER_MIDDLE_CATEGORY_NAME]["value"], | |
small_cat: record[MASTER_SMALL_CATEGORY_NAME]["value"] | |
}; | |
} | |
// 新規作成なら(選択済が無ければ)、大・中・小カテゴリーの最初の選択肢を選択済にしておく | |
if(big_cat_selected == undefined) { big_cat_selected = hashItems[0]['big_cat'];} | |
if(middle_cat_selected == undefined) { middle_cat_selected = hashItems[0]['middle_cat'];} | |
if(small_cat_selected == undefined) { small_cat_selected = hashItems[0]['small_cat'];} | |
//最初にプルダウンを、全てクリアする | |
for (var i=mySpaceField.childNodes.length-1; i>=0; i--) { | |
mySpaceField.removeChild(mySpaceField.childNodes[i]); | |
} | |
//大・中・小カテゴリーのプルダウンを作成 | |
var select1 = document.createElement("select"); select1.name = "big_cat"; | |
var select2 = document.createElement("select"); select2.name = "middle_cat"; | |
var select3 = document.createElement("select"); select3.name = "small_cat"; | |
//プルダウンオブジェクト・選択済項目・親カテゴリ・自カテゴリの定義配列 | |
var arrCategory = new Array( | |
{"pulldown":select1, "selected":big_cat_selected, "parent":'', "self":'big_cat'}, | |
{"pulldown":select2, "selected":middle_cat_selected, "parent":'big_cat', "self":'middle_cat'}, | |
{"pulldown":select3, "selected":small_cat_selected, "parent":'middle_cat', "self":'small_cat'} | |
); | |
//大・中・小カテゴリーのプルダウン作成 | |
for(iCat=0; iCat <arrCategory.length; iCat++){ | |
//カテゴリーマスタのレコード数だけループ(重複したフィールド値を1個にまとめる) | |
var first_value = ""; | |
for ( var i in hashItems ) { | |
// 親カテゴリーが無い or 親カテゴリーが一致なら | |
if(arrCategory[iCat]['parent'] == '' || arrCategory[iCat-1]['selected'] == hashItems[i][arrCategory[iCat]['parent']]){ | |
// かつ、自カテゴリの新しい値だったら、プルダウンに追加する | |
if(first_value != hashItems[i][arrCategory[iCat]['self']]){ | |
var option = document.createElement('option'); | |
option.setAttribute('value', hashItems[i][arrCategory[iCat]['self']]); | |
//既存レコードの選択済の値だったら、selectedにしておく | |
if(arrCategory[iCat]['selected'] == hashItems[i][arrCategory[iCat]['self']]){ | |
option.setAttribute('selected', true); | |
} | |
option.innerHTML = hashItems[i][arrCategory[iCat]['self']]; | |
arrCategory[iCat]['pulldown'].appendChild(option); | |
// プルダウンに追加した値を、次の比較対象とする | |
first_value = hashItems[i][arrCategory[iCat]['self']]; | |
} | |
} | |
} | |
} | |
// 大カテゴリーを変更 | |
select1.onchange = function(event) { | |
var first_value_middle = ""; | |
var first_value_small = ""; | |
// 中カテゴリーをクリア | |
for (var i=select2.childNodes.length-1; i>=0; i--) { | |
select2.removeChild(select2.childNodes[i]); | |
} | |
//カテゴリーマスタのレコード数だけループ | |
for ( var i in hashItems ) { | |
//新しい中カテゴリーが出てきたらプルダウンに追加する | |
if(this.value == hashItems[i]['big_cat'] && first_value_middle != hashItems[i]['middle_cat']){ | |
var option2 = document.createElement('option'); | |
option2.setAttribute('value', hashItems[i]['middle_cat']); | |
option2.innerHTML = hashItems[i]['middle_cat']; | |
select2.appendChild(option2); | |
first_value_middle = hashItems[i]['middle_cat']; | |
//// 中カテゴリーが変更されたら、小カテゴリーの項目も変更する | |
for (var i=select3.childNodes.length-1; i>=0; i--) { | |
select3.removeChild(select3.childNodes[i]); | |
} | |
//カテゴリーマスタのレコード数だけループ | |
for ( var i in hashItems ) { | |
//新しい中カテゴリーが出てきたら、プルダウンに追加する | |
if(first_value_middle == hashItems[i]['middle_cat'] && first_value_small != hashItems[i]['small_cat']){ | |
var option3 = document.createElement('option'); | |
option3.setAttribute('value', hashItems[i]['small_cat']); | |
option3.innerHTML = hashItems[i]['small_cat']; | |
select3.appendChild(option3); | |
// プルダウンに追加した値を、次の比較対象とする | |
first_value_small = hashItems[i]['small_cat']; | |
} | |
} | |
} | |
} | |
} | |
// 中カテゴリーを変更 | |
select2.onchange = function(event) { | |
var first_value = ""; | |
for (var i=select3.childNodes.length-1; i>=0; i--) { | |
select3.removeChild(select3.childNodes[i]); | |
} | |
//カテゴリーマスタのレコード数だけループ | |
for ( var i in hashItems ) { | |
//新しい小カテゴリーが出てきたら、プルダウンに追加する | |
if(this.value == hashItems[i]['middle_cat'] && first_value != hashItems[i]['small_cat']){ | |
var option3 = document.createElement('option'); | |
option3.setAttribute('value', hashItems[i]['small_cat']); | |
option3.innerHTML = hashItems[i]['small_cat']; | |
select3.appendChild(option3); | |
// プルダウンに追加した値を、次の比較対象とする | |
first_value = hashItems[i]['small_cat']; | |
} | |
} | |
} | |
// 小カテゴリーの変更は、他に影響が無いので特に処理は行わない。 | |
// 画面に、大・中・小カテゴリーのプルダウンを表示する | |
mySpaceField.appendChild(select1); | |
mySpaceField.appendChild(select2); | |
mySpaceField.appendChild(select3); | |
// CSSを使って、見た目をkintoneっぽくする | |
//プルダウンオブジェクト・項目名の定義配列 | |
var arrOutput = new Array( | |
{"pulldown":select1, "fieldname":BIG_CATEGORY_NAME}, | |
{"pulldown":select2, "fieldname":MIDDLE_CATEGORY_NAME}, | |
{"pulldown":select3, "fieldname":SMALL_CATEGORY_NAME} | |
); | |
//親子関係カテゴリーのプルダウンを画面に表示する | |
for(iOutput=0; iOutput <arrOutput.length; iOutput++){ | |
// 見た目がkintoeデフォルトと同じようになるように、CSS解析してセット(崩れる可能性あり) | |
var div_outer = document.createElement('div'); | |
div_outer.className = 'control-gaia control-single-select-field-gaia'; | |
var span = document.createElement('span'); | |
span.innerHTML = arrOutput[iOutput]['fieldname']; | |
span.className = 'control-label-text-gaia'; | |
var div = document.createElement('div'); | |
div.className = 'control-label-gaia'; | |
div.appendChild(span); | |
div_outer.appendChild(div); | |
arrOutput[iOutput]['pulldown'].style.width = '230px'; | |
arrOutput[iOutput]['pulldown'].style.cursor = "pointer"; | |
div_outer.appendChild(arrOutput[iOutput]['pulldown']); | |
mySpaceField.appendChild(div_outer); | |
} | |
}); | |
return event; | |
}); | |
// レコード追加・編集保存前イベント | |
kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) { | |
// プルダウンで選択されている値を、kintoneレコードに格納する | |
event["record"][BIG_CATEGORY_NAME]["value"] = $('select[name="big_cat"]').val(); | |
event["record"][MIDDLE_CATEGORY_NAME]["value"] = $('select[name="middle_cat"]').val(); | |
event["record"][SMALL_CATEGORY_NAME]["value"] = $('select[name="small_cat"]').val(); | |
return event; | |
}); | |
})(); | |
/** | |
* Kintoneと通信を行うクラス() | |
*/ | |
KintoneRecordManager = (function() { | |
KintoneRecordManager.prototype.query = ''; | |
KintoneRecordManager.prototype.records = []; | |
KintoneRecordManager.prototype.appId = null; | |
KintoneRecordManager.prototype.query = MASTER_CATEGORY_QUERY; | |
KintoneRecordManager.prototype.limit = 100; | |
KintoneRecordManager.prototype.offset = 0; | |
function KintoneRecordManager() { | |
// this.appId = kintone.app.getId(); | |
this.appId = MASTER_CATEGORY_APP_NO; | |
} | |
// すべてのレコード取得する | |
KintoneRecordManager.prototype.getRecords = function(callback) { | |
kintone.api('/k/v1/records', 'GET', { | |
app: this.appId, | |
query: this.query + (' order by 優先度 asc limit ' + this.limit + ' offset ' + this.offset ) //order by,limit, offsetの順番じゃないとダメ! | |
}, (function(_this) { | |
return function(res) { | |
var len=0; | |
Array.prototype.push.apply(_this.records, res.records); | |
len = res.records.length; | |
_this.offset += len; | |
if (len < _this.limit) { | |
_this.ready = true; | |
if (callback !== null) { | |
callback(_this.records); | |
} | |
} else { | |
_this.getRecords(callback); | |
} | |
}; | |
})(this)); | |
}; | |
return KintoneRecordManager; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment