kintoneのフィールドIDとは?
kintoneではフィールドの判別に「フィールドコード」「フィールド名」を使いますが、
もう一つ、内部パラメータとして「フィールドID(仮称)」を持っています。
普段表には現れませんが、デバッグコンソールでHTMLを見ると、
こんな風にclass名の一部に使われたりしています。
<div class="control-gaia control-decimal-field-gaia field-5525625" >
<div class="control-label-gaia label-5525625" >
<div class="control-value-gaia value-5525625" >
公開されているJavaScript APIではないので、今後のkintoneバージョンアップで動かなくなる可能性はありますが、現状確認できている挙動としては
- フィールドコード:フィールドID = 1:1
- フィールドコードを変えてもフィールドIDは変わらない
- フィールドIDは自動採番で変更不可能
って感じ。
そして、レコード編集画面でフィールドのDOMを取得するときなんかは、
JavaScript APIではうまく取れないので
このフィールドIDをうまく使ってやると、より高度なhackができるわけです!
(繰り返しますが、非公式カスタマイズなので、動かなくなるリスクを踏まえて自己責任で!)
window.cybozuオブジェクト
実は、window.kintone
とは別にwindow.cybozu
というグローバルオブジェクトがあり、
こうしてやると超便利なfieldList
オブジェクトが取れることを、同僚の @t2kojima が発見してくれました!
cybozu.data.page.FORM_DATA.schema.table.fieldList
cybozu.data.page.FORM_DATA.schema.subTable
cybozu.data.page.FORM_DATA.schema.subTable[サブテーブルのフィールドID].fieldList
fieldList
オブジェクトのkey
とvalue.id
が、どちらもフィールドID。
value
の中にはフィールドコードやらフィールド名やら、
他にもデフォルト値、単位、必須制約などなど宝の山が入っております!
fieldListを使った例
基本
Object.values()
で配列にしておくと、その後扱いやすいです。
普通のフィールドだけの場合
シンプルにこれでOK
const fields = Object.values(cybozu.data.page.FORM_DATA.schema.table.fieldList)
サブテーブルを含む場合
ちょっと複雑になるのですが、基本はこの3パターンになると思います。あとは用途によって使い分けてください。
テーブル本体をすべて抽出(テーブル内フィールドは無視)
const fields = Object.values(cybozu.data.page.FORM_DATA.schema.subTable)
テーブル内フィールドだけを、全テーブル横断して抽出
const subTables = Object.values(cybozu.data.page.FORM_DATA.schema.subTable)
const fields = subTables.flatMap(t => Object.values(t.fieldList))
普通のフィールド・テーブル本体・テーブル内フィールドの3種を同列に抽出
const mainFields = Object.values(cybozu.data.page.FORM_DATA.schema.table.fieldList)
const subTables = Object.values(cybozu.data.page.FORM_DATA.schema.subTable)
const subFields = subTables.flatMap(t => Object.values(t.fieldList))
const fields = [...mainFields, ...subTables, ...subFields]
応用
以下、↑のいずれかの方法でfields
配列が作られている前提で進めます。
フィールドコードからフィールドIDを調べる
fields.find(_ => _.var === '支払サイト').id
// "5525625"
フィールド名からフィールドIDを調べる
fields.find(_ => _.label === 'レコード番号').id
// "5525614"
フィールドコードをキーにフィールド情報を引くオブジェクトを作る
const fieldMap = fields.reduce((map, field) => ({ ...map, [field.var]: field }), {})
fieldMap.支払サイト.id
// "5525625"
fieldMap.支払サイト.properties.unit
// "日後"
DOM操作でフィールドに任意の値を設定する
const fieldId = fieldMap.支払サイト.id
$input = document.querySelector(`.value-${fieldId} input`)
$input.value = 30
類似オブジェクト
SCHEMA_DATA
という似たようなオブジェクトがあって、似たように使えるんですが、こっちはルックアップ・関連レコードフィールドの詳細まで入っています。
cybozu.data.page.SCHEMA_DATA.table.fieldList
終わりに
しつこいですが、あくまで自己責任で使ってくださいね!(笑)
よく忘れるので、自分用メモも兼ねて書きましたー。
ではまた!