新規投稿
フォローする

チェックボックスで表示非常時について

お世話になっております。

添付のようなイメージで、契約プランにチェックしたら、該当のグループが表示できるようなアプリ作りたいですが、初心者で全然うまく反映されないです。

(function() {
"use strict";

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.create.change.Aプラン',
'app.record.create.change.Bプラン',
'app.record.create.change.Cプラン',
'app.record.create.change.Dプラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
'app.record.edit.change.Aプラン',
'app.record.edit.change.Bプラン',
'app.record.edit.change.Cプラン',
'app.record.edit.change.Dプラン'];

kintone.events.on(events, function(event) {

var record = event.record;

var plan = record['契約プラン']['value'];
if (plan.length === 0) {
kintone.app.record.setFieldShown('Aプラン', false);
}

for (var i = 0; i < plan.length; i++) {
if (plan[i] === 'Aプラン') {
kintone.app.record.setFieldShown('Aプラン', true);
}else {
kintone.app.record.setFieldShown('Aプラン', false);
}

}

if (plan.length === 0) {
kintone.app.record.setFieldShown('Bプラン', false);
}

for (var i = 0; i < plan.length; i++) {
if (past[i] === 'Bプラン') {
kintone.app.record.setFieldShown('Bプラン', true);
}else {
kintone.app.record.setFieldShown('Bプラン', false);
}

}


return event;
});
})();

さらに、Aプランのなかも表示非表示をさせたいですが、全然よくわからなくて、とてもさまよっております。

アドバイス頂けたら、本当に助かりますが、どうぞ宜しくお願い致します。

0

29件のコメント

Avatar
rex0220

岡戸さん

試作してみました。
fieldsInfo に、グループ項目とコース項目、料金項目のフィールドコードを指定します。
前提として、契約プランの値とグループ項目フィールドコードを同じにしています。
コース項目、料金項目のフィールドコードは、適当につけていますので、アプリの設定に合わせてください。

契約プランで非選択になった場合に、該当のコース選択はリセットしましたが、不要ならば処理を削除してください。

また、プランを選択してコースが選択されていない場合は、エラー表示としました。

 

(function() {
"use strict";

var fieldsInfo = [
{ groupFieldCode: 'Aプラン', courseFieldCode: 'Aコース', courseInfo: { 'aコース': 'aコース料金', 'bコース': 'bコース料金', 'cコース': 'cコース料金', } },
{ groupFieldCode: 'Bプラン', courseFieldCode: 'Bコース', courseInfo: { 'dコース': 'dコース料金', 'eコース': 'eコース料金', 'fコース': 'fコース料金', } },
{ groupFieldCode: 'Cプラン', courseFieldCode: 'Cコース', courseInfo: { 'gコース': 'gコース料金', 'hコース': 'hコース料金', 'iコース': 'iコース料金', } },
{ groupFieldCode: 'Dプラン', courseFieldCode: 'Dコース', courseInfo: { 'jコース': 'jコース料金', 'kコース': 'kコース料金', 'lコース': 'lコース料金', } },
];

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
];
fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
});
kintone.events.on(events, function(event) {
var record = event.record;
var planValue = record['契約プラン']['value'];

fieldsInfo.forEach(function(planData) {
var planState = planValue.indexOf(planData.groupFieldCode) >= 0;
kintone.app.record.setFieldShown(planData.groupFieldCode, planState);
if (!planState) {
// 非選択プランのコース選択をリセット
record[planData.courseFieldCode]['value'] = [];
// プラン選択時の表示のため、グループを開いておく
kintone.app.record.setGroupFieldOpen(planData.groupFieldCode, true);
}
var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
kintone.app.record.setFieldShown(courcePriceName, courceState);
});
});
return event;
});

kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {
var record = event.record;
var planValue = record['契約プラン']['value'];

fieldsInfo.forEach(function(planData) {
var planState = planValue.indexOf(planData.groupFieldCode) >= 0;
if (planState && record[planData.courseFieldCode]['value'].length === 0) {
kintone.app.record.setGroupFieldOpen(planData.groupFieldCode, true);
record[planData.courseFieldCode]['error'] = '必須です。';
event['error'] = 'コース必須エラー';
}
});
return event;
});

})();
1
Avatar
岡戸 智子

rex0220 様

お世話になっております。

ありがとうございます。すばらしいです。

いつか私でもこんなプログラムが書けたらいいですが・・

まだ初心者でkintoneのプログラムをできない状態ですが、

もしお時間とかありましたら、上の書いていただいた

fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
});


var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
kintone.app.record.setFieldShown(courcePriceName, courceState);

箇所の意味も説明して頂けると幸いです。
本当に感謝しております。


0
Avatar
rex0220

では、少し解説します。
まず、項目を処理しやすいように、配列で定義します。
同じような、項目を処理するときは、配列やオブジェクトにするとループ処理出来るようになります。


var fieldsInfo = [
{ groupFieldCode: 'Aプラン', courseFieldCode: 'Aコース', courseInfo: { 'aコース': 'aコース料金', 'bコース': 'bコース料金', 'cコース': 'cコース料金', } },
{ groupFieldCode: 'Bプラン', courseFieldCode: 'Bコース', courseInfo: { 'dコース': 'dコース料金', 'eコース': 'eコース料金', 'fコース': 'fコース料金', } },
{ groupFieldCode: 'Cプラン', courseFieldCode: 'Cコース', courseInfo: { 'gコース': 'gコース料金', 'hコース': 'hコース料金', 'iコース': 'iコース料金', } },
{ groupFieldCode: 'Dプラン', courseFieldCode: 'Dコース', courseInfo: { 'jコース': 'jコース料金', 'kコース': 'kコース料金', 'lコース': 'lコース料金', } },
];

 


イベント処理も上記の項目を使って、定義します。
forEach は配列処理を便利にしてくれる命令文です。
forEach, map, filterなどをつかってkintoneのrecords配列をもっと上手に扱う」の解説が分かりやすいと思います。

fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
});

 処理結果は、下記の配列になります。
プランの増減があっても、イベント処理の変更は不要で fieldsInfo の変更で済みます。

var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
'app.record.create.change.Aコース',
'app.record.edit.change.Aコース'
'app.record.create.change.Bコース',
'app.record.edit.change.Bコース'
'app.record.create.change.Cコース',
'app.record.edit.change.Cコース'
'app.record.create.change.Dコース',
'app.record.edit.change.Dコース'
];

 

 下記は、コース料金の表示制御です。

var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
kintone.app.record.setFieldShown(courcePriceName, courceState);

 

Object.keys(planData.courseInfo) は、オブジェクトのキーを配列として取り出します。

⇒ ['aコース', 'bコース', 'cコース' ]

['aコース', 'bコース', 'cコース' ].forEach(function(courseFieldCode) {

⇒ courseFieldCode に、 'aコース', 'bコース', 'cコース' と順番に渡されて処理します。

courcePriceName = planData.courseInfo['aコース']; // 'aコース料金'
courcePriceName = planData.courseInfo['bコース']; // 'bコース料金'
courcePriceName = planData.courseInfo['cコース']; // 'cコース料金'


var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);

planState は、プランが選択されている状態が true, 非選択は false
courceStateは、プランとコースの両方選択されている場合のみ、 true となり、コース料金を表示します。

courseValue.indexOf('aコース') は、配列courseValue に、値'aコース' があれば位置を示します。
位置が >= 0 の場合、'aコース' が選択 true, < 0 の場合は非選択 false になります。

 

 

 

2
Avatar
岡戸 智子

rex0220 様

お世話になっております。

とてもご丁寧に教えて頂き、本当にありがとうございます。

とてもわかりやすかったです。

 

お陰様で理想通り動いてます。

実務の物に活用してみます。

本当にとても助かりました。ありがとうございました。

これからもどうぞよろしくお願い致します。

岡戸 智子により編集されました
0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

何度も何度も大変申し訳ございません。

前回作成中のアプリに以下の項目を追加しました。

①「Aコース」に「xコース」を追加し、さらに「xコース仕分」ドロップダウンで「法人・個人」とした場合

   「法人」➡「法人料金」のみ、 「個人」➡「個人料金」のみ表示する

②「Bコース」に「そのた」を追加し、さらに「そのた」にチェックした場合

 「法人aa」と「法人bb」を表示させる

この2つともは配列のみ追加すればいいでしょうか?追加した場合、IF関数を使っても大丈夫でしょうか?

var fieldsInfo = [
{ groupFieldCode: 'Aプラン', courseFieldCode: 'Aコース', courseInfo: { 'aコース': 'aコース料金', 'bコース': 'bコース料金', 'cコース': 'cコース料金', 'xコース':{if (record['xコース仕分']['value'] === '法人') {
kintone.app.record.setFieldShown('法人料金', true);}else {
kintone.app.record.setFieldShown('法人料金', false);
}
}} },
{ groupFieldCode: 'Bプラン', courseFieldCode: 'Bコース', courseInfo: { 'dコース': 'dコース料金', 'eコース': 'eコース料金', 'fコース': 'fコース料金', 'その他':'その他aa'&'その他bb' , } },
{ groupFieldCode: 'Cプラン', courseFieldCode: 'Cコース', courseInfo: { 'gコース': 'gコース料金', 'hコース': 'hコース料金', 'iコース': 'iコース料金', } },
{ groupFieldCode: 'Dプラン', courseFieldCode: 'Dコース', courseInfo: { 'jコース': 'jコース料金', 'kコース': 'kコース料金', 'lコース': 'lコース料金', } },

];

度々大変申し訳ございませんが、アドバイス頂けますか。

よろしくお願い致します。

岡戸 智子により編集されました
0
Avatar
rex0220

普通に開発案件レベルになってしまいましたが、下記のようにすればいいと思います。

ネストに応じた項目定義とロジックが必要です。

 

(function() {
"use strict";

var fieldsInfo = [{
groupFieldCode: 'Aプラン',
courseFieldCode: 'Aコース',
courseInfo: {
'aコース': 'aコース料金',
'bコース': 'bコース料金',
'cコース': 'cコース料金',
'xコース': { 'xコース仕分': { '法人': '法人料金', '個人': '個人料金' } }
}
}, {
groupFieldCode: 'Bプラン',
courseFieldCode: 'Bコース',
courseInfo: {
'dコース': 'dコース料金',
'eコース': 'eコース料金',
'fコース': 'fコース料金',
'その他': ['その他aa', 'その他bb']
}
},
{ groupFieldCode: 'Cプラン', courseFieldCode: 'Cコース', courseInfo: { 'gコース': 'gコース料金', 'hコース': 'hコース料金', 'iコース': 'iコース料金', } },
{ groupFieldCode: 'Dプラン', courseFieldCode: 'Dコース', courseInfo: { 'jコース': 'jコース料金', 'kコース': 'kコース料金', 'lコース': 'lコース料金', } },
];

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
];
fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});
});
kintone.events.on(events, function(event) {
var record = event.record;
var planValue = record['契約プラン']['value'];

fieldsInfo.forEach(function(planData) {
var planState = planValue.indexOf(planData.groupFieldCode) >= 0;
kintone.app.record.setFieldShown(planData.groupFieldCode, planState);
if (!planState) {
// 非選択プランのコース選択をリセット
record[planData.courseFieldCode]['value'] = [];
// プラン選択時の表示のため、グループを開いておく
kintone.app.record.setGroupFieldOpen(planData.groupFieldCode, true);
}
var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
if (typeof courcePriceName === 'string') {
kintone.app.record.setFieldShown(courcePriceName, courceState);
} else if (Array.isArray(courcePriceName)) {
courcePriceName.forEach(function(fcode) {
kintone.app.record.setFieldShown(fcode, courceState);
});
} else {
Object.keys(courcePriceName).forEach(function(courseDropFieldCode) {
kintone.app.record.setFieldShown(courseDropFieldCode, courceState);
if (!courceState) {
// 非選択プランのコース選択をリセット
record[courseDropFieldCode]['value'] = '';
}
var courseDetailValue = record[courseDropFieldCode]['value'] || [];
Object.keys(courcePriceName[courseDropFieldCode]).forEach(function(courseDetailFieldCode) {
var courceDetailName = courcePriceName[courseDropFieldCode][courseDetailFieldCode];
var courceDetailState = planState && (courseDetailValue.indexOf(courseDetailFieldCode) >= 0);
kintone.app.record.setFieldShown(courceDetailName, courceDetailState);
});
})
}
});
});
return event;
});

kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], function(event) {
var record = event.record;
var planValue = record['契約プラン']['value'];

fieldsInfo.forEach(function(planData) {
var planState = planValue.indexOf(planData.groupFieldCode) >= 0;
if (planState && record[planData.courseFieldCode]['value'].length === 0) {
kintone.app.record.setGroupFieldOpen(planData.groupFieldCode, true);
record[planData.courseFieldCode]['error'] = '必須です。';
event['error'] = 'コース必須エラー';
}
var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
if (typeof courcePriceName === 'object' && !Array.isArray(courcePriceName)) {
Object.keys(courcePriceName).forEach(function(courseDropFieldCode) {
if (courceState && !record[courseDropFieldCode]['value']) {
record[courseDropFieldCode]['error'] = '必須です。';
event['error'] = 'コース必須エラー';
}
})
}
});
});
return event;
});

})();
0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

早速のご返信ありがとうございます。

大変恐縮です。

開発案件レベルになってしまった(自覚がなくて、ご迷惑をおかけまして、大変申し訳ございません・・)

にもかかわらず、ご丁寧に教えて頂き、誠にありがとうございます。

感謝、感謝、感謝です。

 

 

 

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

お陰様で、作成頂いたコードに感動しつつ、とても長い時間かかって読み取り中です。

本当に何度もご指導いただいて、感謝切れない気持ちでいっぱいです。

またもや行き詰まって、投稿しました

①区分追加しました。これで全然動かないです・・

 if (record['区分']['value'] === '基本') {
 kintone.app.record.setFieldShown('基本_契約プラン', true);
 kintone.app.record.setFieldShown('基本外_契約プラン', false);
}else {
  kintone.app.record.setFieldShown('基本_契約プラン', false);
  kintone.app.record.setFieldShown('基本外_契約プラン', true);
}

②もう一つのプランを追加しました。

 前回教えて頂いたように、もう一つの配列を作って、ほかの部分も全く同じように、その追加配列分で作ってみましが、それでも大丈夫でしょうか?

お忙しいところ誠に恐縮ですが、もしよろしかったら、再度アドバイス頂けますでしょうか。

岡戸 智子により編集されました
0
Avatar
rex0220

>①区分追加しました。これで全然動かないです・・
>②もう一つのプランを追加しました。

これは、イベント処理に追加した区分を反映していないためです。

「基本契約プラン>コース>コース仕分け」

から

「区分>基本契約プラン>コース>コース仕分け」

という階層構造に変更されていますので、それに対応したロジック変更が必要です。

こちらで、ロジックを追加しても、きりがありませんので、
岡戸さんに、検討していただきたいと思います。
また、何か変更が必要になった場合に、岡戸さんが対応できる必要があります。


まず、先の変更について、調べてみてください。。

「基本契約プラン>コース」

から

「基本契約プラン>コース>コース仕分け」

でどのように fieldsInfo とロジックを変更したか、調べてください。

fieldsInfo に、コース仕分けの階層が追加されていると思います。

それに応じて、events にもコース仕分けの項目処理を追加しています。

あとは実際に、コース仕分け項目の表示制御とエラーチェック処理を追加しています。


区分を追加する場合も、これと同様の追加が必要になります。


まずは、

「基本契約プラン>コース>コース仕分け」 から 「区分>基本契約プラン>コース>コース仕分け」 の変更を

岡戸さんが手を動かして、コードを書いてみてください。

それが出来たら、「基本契約プラン>コース>コース仕分け」 から 「区分>基本契約プラン>コース>コース仕分け」 の変更も
同じような考え方で追加できると思います。


実際に動くものを自分で作らないと、なかなか身につきません。

かなり時間がかかると思いますが、頑張ってください。

 

 

 

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

ご指導ありがとうございます。

おっしゃる通りです。試しにやってみます。

いつもありがとうございます。

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

度々お手数をおかけいたします。

区分をラジオボタンではなく、チェックボックスにして、しかも「基本契約プラン」と「基本外契約プラン」もチェックボックスにしておりますが、

これで区分の表示と非表示は可能でしょうか?

もし可能であれば、

①「基本契約プラン>コース>コース仕分け」 から 「区分>基本契約プラン>コース>コース仕分け」 の変更でfieldsInfoについてすが、

以下のようでは、ぜんぜんあってないような気がしますが、区分を基本と基本外プランとつなげるには今までの一対一ではできなく、

どうすればいいかわからなくて、ネットでも色々調べてみましたが、どこを参考にすればいいのかさっぱりわからなくて、考え方はなんとなく分かるが、

どこから手をつければよろしいかまたもやアドバイスいただければ、幸いです。

本当に申し訳ございません。

var fieldsInfo = [
{ CheckFieldCode:'基本契約プラン', checkInfo:{'Aプラン', 'Bプラン', 'Cプラン', },
{ CheckFieldCode:'基本外契約プラン', checkInfo:{'AAAプラン', 'BBBプラン', 'CCCプラン', },
{
groupFieldCode: 'Aプラン',
courseFieldCode: 'Aコース',
courseInfo: {
'aコース': 'aコース料金',
'bコース': 'bコース料金',
'cコース': 'cコース料金',
'xコース': { 'xコース仕分': { '法人': '法人料金', '個人': '個人料金' } }
}
}, {
groupFieldCode: 'Bプラン',
courseFieldCode: 'Bコース',
courseInfo: {
'dコース': 'dコース料金',
'eコース': 'eコース料金',
'fコース': 'fコース料金',
'その他': ['その他aa', 'その他bb']
}
},

0
Avatar
rex0220

>区分をラジオボタンではなく、チェックボックスにして、しかも「基本契約プラン」と「基本外契約プラン」もチェックボックスにしておりますが、
>これで区分の表示と非表示は可能でしょうか?

可能です。


>区分を基本と基本外プランとつなげるには今までの一対一ではできなく、


「基本外契約プラン」は、複数プラン(Aプラン、Bプラン...)とつながっています。
考え方は、同じですね。

それに対する fieldsInfo は、下記のような構造です。

[
{ groupFieldCode: 'Aプラン', ...},
{ groupFieldCode: 'Bプラン', ...},
...
]


区分を追加する場合は、上位の階層に「基本契約プラン」と「基本外契約プラン」の情報を持つ必要があります。

この辺は、かなり分かりにくいと思いますが、頑張ってください。

1
Avatar
岡戸 智子

rex0220 様

お世話になっております。

初心者で大変お手数をおかけしております。

全然進まないので、順番は関係なくして、考え方がこれで大丈夫かどうか教えていただけますか?

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.区分',
'app.record.edit.show',
'app.record.edit.change.区分',
];

fieldsInfo.forEach(function(divisionData) {
events.push('app.record.create.change.' + divisionData.groupFieldCode);
events.push('app.record.edit.change.' + divisionData.groupFieldCode);
});
kintone.events.on(events, function(event) {
var record = event.record;
var divisionValue = record['区分']['value'];

fieldsInfo.forEach(function(divisionData) {
var divisionState = divisionValue.indexOf(divisionData.groupFieldCode) >= 0;
kintone.app.record.setFieldShown(divisionData.groupFieldCode, divisionState);
if (!divisionState) {
// 非選択プランのコース選択をリセット
record[divisionData.groupFieldCode]['value'] = [];
// プラン選択時の表示のため、グループを開いておく
kintone.app.record.setgroupFieldOpen(divisionData.groupFieldCode, true);
}

こんな感じで、今までのplanDataの上の層をdivisionDataとし、 divisionValueとdivisionStateを追加すると考えで大丈夫でしょうか?

初心者のものにもかかわらず、いつもご対応していただき、本当にありがとうございます。

ちょっとずつですが、頑張ってみたいと思っておりますので、もしよろしかったら、これからもご指導いただければ幸いです。

0
Avatar
rex0220


>こんな感じで、今までのplanDataの上の層をdivisionDataとし、 divisionValueとdivisionStateを追加すると考えで大丈夫でしょうか?

考え方は、いいと思いますが、追加するといいながら処理は、減ってしまっています。
今回の岡戸さんの案では、下層のコース選択やコース区分の変更イベント処理などがなくなっています。
変更イベント処理が無いと、コース選択変更時のコース料金表示制御ができません。
項目自体が無くなっているのであれば、問題ないのですが。


前回の events 処理では、下記のようになっています。
xコース仕分 の変更時もイベント処理対象となっています。

同じように、今回の岡戸さんの案で、events の内容がどのようになるのか、検証してみてください。
項目の値が変更された場合に、表示制御するべき項目がすべて羅列されていればOKです。


前回の events 処理内容

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
];
fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});
});

 

処理結果

var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.契約プラン',
'app.record.edit.show',
'app.record.edit.change.契約プラン',
'app.record.create.change.Aコース',
'app.record.edit.change.Aコース'
'app.record.create.change.xコース仕分',
'app.record.edit.change.xコース仕分'
'app.record.create.change.Bコース',
'app.record.edit.change.Bコース'
'app.record.create.change.Cコース',
'app.record.edit.change.Cコース'
'app.record.create.change.Dコース',
'app.record.edit.change.Dコース'
];
0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

いつもお返事ありがとうございます。

すみません。今までの構造で追加したかったが、コードが長くて、混乱しそうで、おっしゃる通り一部分削りました。

やっぱり全体で考えないといけないですね・・

また前回にアドバイス頂いてた:区分を追加する場合は、上位の階層に「基本契約プラン」と「基本外契約プラン」の情報を持つ必要があります。 についてですが、前回のお話ですと、fieldsInfoには区分の項目は追加はしないで、今までの状態ですと、eventsにも区分の項目追加せず、「契約プラン」を「区分」に変更することになりますので、if関数で「基本契約プラン」と「基本外契約プラン」を追加する考えでしょうか?それとも私の勘違いで、fieldsInfoとeventsには項目追加するのでしょうか?

 論理的に考えるとどこが先で、どこか次になるのか混乱している毎日です。rex0220 様が作っていただいたプログラムはすごくすばらしくて、憧れております。

岡戸 智子により編集されました
0
Avatar
rex0220

まず、events をどうしたいかを考えてください。

次に処理結果をそうするために、どんな fieldsInfo 構造がいいのか考えましょう。

いろいろな構造で、実現可能だと思いますが、

上の階層レベルが変更された場合に、最下層まで表示制御しなくてはなりませんので、

 ループ処理や再帰処理しやすい構造であれば、処理も組みやすいと思います。

 

1
Avatar
岡戸 智子

rex0220 様

お世話になっております。

複雑すぎて、一人では無理と諦めかけておりましたが、rex0220 さんにアドバイス頂けて、

踏ん張ってやってみようという気持ちになりました。本当にありがとうございます。

これからも大変なご迷惑をおかけしますが、お時間ある時で構わないので、ぜひどうぞよろしくお願い致します。

①以下のコードで「xコース仕分」の追加・編集をなさっていると思いますが、解読ができなくて、ご説明して頂けたら幸いです。

 Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});

②eventsについてですが、以下にすると思われますが、

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.区分',
'app.record.edit.show',
'app.record.edit.change.区分',
];
fieldsInfo.forEach(function(divisionData) {
events.push('app.record.create.change.' + divisionData.groupFieldCode);
events.push('app.record.edit.change.' + divisionData.groupFieldCode); }
];

処理結果

var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.区分',
'app.record.edit.show',
'app.record.edit.change.区分',
'app.record.create.change.Aプラン',
'app.record.edit.change.Aプラン'
'app.record.create.change.Bプラン',
'app.record.edit.change.Bプラン'
'app.record.create.change.Cプラン',
'app.record.edit.change.Cプラン'
'app.record.create.change.Dプラン',
'app.record.edit.change.Dプラン'
'app.record.create.change.AAAプラン',
'app.record.edit.change.AAAプラン'
'app.record.create.change.BBBプラン',
'app.record.edit.change.BBBプラン'
'app.record.create.change.CCCプラン',
'app.record.edit.change.CCCプラン'
];

区分を選んだ後のプランを選んだ場合の編集画面は以下となるでしょうか?

planData.events.push('app.record.create.change.' + planData.courseFieldCode);
planData.events.push('app.record.edit.change.' + planData.courseFieldCode);
Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});

 

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

「基本契約プラン」と「基本外契約プラン」が個別に開くようにを以下のようにしてみましたが、「基本外契約プラン」は開かないです。

var planValue1 = record['基本契約プラン']['value'];
var planValue2 = record['基本外契約プラン']['value'];
var planValue = planValue1 || planValue2;

が問題でしょうか?お手すきの際にアドバイス頂けたら幸いです。

 

(function() {
"use strict";

var fieldsInfo = [{
groupFieldCode: 'Aプラン',
courseFieldCode: 'Aコース',
courseInfo: {
'aコース': 'aコース料金',
'bコース': 'bコース料金',
'cコース': 'cコース料金',
'xコース': { 'xコース仕分': { '法人': '法人料金', '個人': '個人料金' } }
}
}, {
groupFieldCode: 'Bプラン',
courseFieldCode: 'Bコース',
courseInfo: {
'dコース': 'dコース料金',
'eコース': 'eコース料金',
'fコース': 'fコース料金',
'その他': ['その他aa', 'その他bb']
}
},
{ groupFieldCode: 'Cプラン', courseFieldCode: 'Cコース', courseInfo: { 'gコース': 'gコース料金', 'hコース': 'hコース料金', 'iコース': 'iコース料金', } },
{ groupFieldCode: 'Dプラン', courseFieldCode: 'Dコース', courseInfo: { 'jコース': 'jコース料金', 'kコース': 'kコース料金', 'lコース': 'lコース料金', } },
{ groupFieldCode: 'AAAプラン', courseFieldCode: 'AAAコース', courseInfo: { 'aaaコース': 'aaaコース料金', 'bbbコース': 'bbbコース料金', } },
];

//レコードの追加、編集、詳細画面で適用する
var events = ['app.record.detail.show',
'app.record.create.show',
'app.record.create.change.基本契約プラン',
'app.record.create.change.基本外契約プラン',
'app.record.edit.show',
'app.record.edit.change.基本契約プラン',
'app.record.edit.change.基本外契約プラン',
];
fieldsInfo.forEach(function(planData) {
events.push('app.record.create.change.' + planData.courseFieldCode);
events.push('app.record.edit.change.' + planData.courseFieldCode);
Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});
});
kintone.events.on(events, function(event) {
var record = event.record;
var planValue1 = record['基本契約プラン']['value'];
var planValue2 = record['基本外契約プラン']['value'];
var planValue = planValue1 || planValue2;

fieldsInfo.forEach(function(planData) {
var planState = planValue.indexOf(planData.groupFieldCode) >= 0;
kintone.app.record.setFieldShown(planData.groupFieldCode, planState);
if (!planState) {
// 非選択プランのコース選択をリセット
record[planData.courseFieldCode]['value'] = [];
// プラン選択時の表示のため、グループを開いておく
kintone.app.record.setGroupFieldOpen(planData.groupFieldCode, true);
}
var courseValue = record[planData.courseFieldCode]['value'];
Object.keys(planData.courseInfo).forEach(function(courseFieldCode) {
var courcePriceName = planData.courseInfo[courseFieldCode];
var courceState = planState && (courseValue.indexOf(courseFieldCode) >= 0);
if (typeof courcePriceName === 'string') {
kintone.app.record.setFieldShown(courcePriceName, courceState);
} else if (Array.isArray(courcePriceName)) {
courcePriceName.forEach(function(fcode) {
kintone.app.record.setFieldShown(fcode, courceState);
});
} else {
Object.keys(courcePriceName).forEach(function(courseDropFieldCode) {
kintone.app.record.setFieldShown(courseDropFieldCode, courceState);
if (!courceState) {
// 非選択プランのコース選択をリセット
record[courseDropFieldCode]['value'] = '';
}
var courseDetailValue = record[courseDropFieldCode]['value'] || [];
Object.keys(courcePriceName[courseDropFieldCode]).forEach(function(courseDetailFieldCode) {
var courceDetailName = courcePriceName[courseDropFieldCode][courseDetailFieldCode];
var courceDetailState = planState && (courseDetailValue.indexOf(courseDetailFieldCode) >= 0);
kintone.app.record.setFieldShown(courceDetailName, courceDetailState);
});
})
}
});
});
return event;
});

0
Avatar
rex0220

区分はとりあえず置いといて、基本外契約プランを何とかしようという発想ですね。

var planValue1 = record['基本契約プラン']['value'];
var planValue2 = record['基本外契約プラン']['value'];
var planValue = planValue1 || planValue2;

|| の処理としては、論理式なので planValue1 が真と評価されると planValue2 は無視されます。
 planValue1 は、配列構造なので論理式として真となります。

結果として、var planValue = planValue1 ; と同じです。

これは、 たぶん配列の結合を行いたいのだと思います。

var planValue = planValue1.concat(planValue2);

 


前回の変更時点で、普通の開発案件レベルだと思いますが、
その後、さらに複雑になっており、初心者向けでないことは確かです。

だいぶ内容が変わっていることから、まだ仕様が固まっているとも言えません。
本当に今の仕様が必要かどうかから見直しされてはいかがでしょうか?

いま悩んでいる部分は、アプリの要件で考えると本質的な機能ではありません。
それほど複雑にしなくてもいいはずです。
多少入力が不要な項目が見えていても、入力業務に支障が無ければ問題ないと思います。


今後の開発や保守を考えると、岡戸さんが対応できる範囲で仕様を調整されたほうが、いいと思います。

 

1
Avatar
rex0220

>①以下のコードで「xコース仕分」の追加・編集をなさっていると思いますが、解読ができなくて、ご説明して頂けたら幸いです。

これだけ説明します。作るより説明のほうが時間がかかります。

設定内容

...
courseInfo: {
'aコース': 'aコース料金', 'bコース': 'bコース料金', 'cコース': 'cコース料金',
'xコース': { 'xコース仕分': { '法人': '法人料金', '個人': '個人料金' } }
}
...

courseInfo: {
'dコース': 'dコース料金', 'eコース': 'eコース料金', 'fコース': 'fコース料金',
'その他': ['その他aa', 'その他bb']
}


courseInfo に、設定している内容に、下記の3種類があります。

・ シンプルな表示制御
'aコース': 'aコース料金'
コース項目の値(兼フィールドコード) : コース料金のフィールドコード


・ 複数のコース項目を表示制御
'その他': ['その他aa', 'その他bb']
コース項目の値(兼フィールドコード) : コース料金のフィールドコードの配列構造


・ 階層がある表示制御
'xコース': { 'xコース仕分': { '法人': '法人料金', '個人': '個人料金' } }
コース項目の値(兼フィールドコード) : コース仕分けの情報

  コース仕分けの情報(courseInfoと同じ構造)
    'xコース仕分': { '法人': '法人料金', '個人': '個人料金' }
    コース仕分のフィールドコード: コース仕分けについての情報(オブジェクト)


3種類なので、JSON の設定方法で識別出来るようにしています。
表示制御の種類が4種類以上ある場合は、構造を見直して種類が識別できる情報を付加することになります。


上記のcourseInfoを使って、変更イベントに必要なフィールドを抽出します。
この処理での、対象項目は、階層構造になっているコース仕分けの情報です。

Object.keys(planData.courseInfo).forEach(function(courseDetailObject) {
var detailObject = planData.courseInfo[courseDetailObject];
if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {
Object.keys(detailObject).forEach(function(courseDetailFieldCode) {
events.push('app.record.create.change.' + courseDetailFieldCode);
events.push('app.record.edit.change.' + courseDetailFieldCode);
})
}
});

たぶん、分かりにくいところは、ここだと思います。

if (typeof detailObject === 'object' && !Array.isArray(detailObject)) {

{ '法人': '法人料金', '個人': '個人料金' } を抽出するために、オブジェクトで、かつ配列で無いものという判定です。
配列は、オブジェクトの1種類ですので、除外しています。

typeof と Array.isArray については、検索して調べてください。

 

1
Avatar
岡戸 智子

rex0220 様

お世話になっております。

お忙しいところ、いつもご丁寧に対応していただき、本当にありがとうございます。

教わった内容を実務に取り込めるように頑張ります。

rex0220さんのおっしゃる通り、初心者の自分ができる範囲(区分はとりあえず置いといて、基本契約プラン・基本外契約プラン)で今回の実務のアプリを作成することにしました。それで、また以下の不具合が発生しております。

入力画面では、チェック入れた項目だけが見えているようですが、例えば間違って、料金まで入れた項目はそのまま裏で残っている。

コース料金の表示制御で、リセットする必要があるとことでしょうか?以下のソースではうまく動かないですが、考え方としてはあってますでしょうか?

if (!courceState) {
 // 非選択プランのコース選択をリセット
 record[courseDropFieldCode]['value'] = '';

// 非選択プランのコース料金入力をリセット
 record[courseDropInfo.coursepriceName]['value'] = '';
 }

何度も何度も申し訳ございませんが、ご指導よろしくお願い致します。

 

 

 

0
Avatar
rex0220

ようやく、コース料金にたどり着きましたね。

区分の前に、コース料金の話があるのかと思っていました。

まず、仕様の確認と調整が必要だと思われます。

アプリの目的としては、顧客が選択したプランとその合計金額の管理でしょうか?

コース料金は、マニュアル入力のようですが、コース毎に固定の料金体系が決まっているのではないでしょうか?

いちいちユーザが、コース料金を調べて入力するのでしょうか?

料金のリセット以前に、使いにくい気がします。

その辺を、リセット処理を開発する前に検討されたほうがいいと思います。

 

 

 

0
Avatar
岡戸 智子

rex0220 様のおっしゃる通りでございます。・・・本当にただただ感動するばかりです。

作成中のアプリはこうなっております。

こんな感じで「基本契約」と「基本外契約」の合計だったり、また、「基本契約」のプラン別の合計を集計する目的でございます。

今までの流れでAプラン合計(計算フィールド)計算式:すべての料金を足す ※すべての料金に関する項目の初期値を0にすれば、

プログラム組まなくても行けるかなと単純に考えておりました。

それで、例えば:Aプランを選択してaコースとxコースを選択して、さらにaコースを外す場合は、裏のデータでもaコースはリセットされます。

でもaコースを選んでからaコース料金に入力してしまった場合は、その料金がリセットされないので、チェックを外した場合、料金がリセットされたらいいのかなと思った次第です・・

 

 

岡戸 智子により編集されました
0
Avatar
rex0220

なるほど、 コース料金はルックアップから設定されるようですね。

この画面構成を見ると、あまり細かく表示制御してもしょうがないと思います。
Aプランを選択した場合は、グループ内の項目は、すべて表示でいいと思います。
細かくパタパタと表示するよりも、はじめからグループ内の項目がすべて見渡せたほうがいいのではないでしょうか?


この図だけではわかりにくいのですが、仕分け数判断のルックアップ取得で、'aコース','bコース','cコース' のコース料金値が決まるのでしょうか?
そういう仕様であれば、仕分け数判断の入力チェックだけ行えばいいことになります。
ルックアップで取得されるコピー項目については、JavaScript で値の設定が出来ません。

その辺を整理しては、いかがでしょうか?

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。早速のご返答ありがとうございます。

顧客別の契約情報を管理するアプリを想定しておりますので、お客様によっては、Aプランでも「'aコース','bコース','cコース' ,'dコース','その他','値引' 」の項目が多くなったり、少なかったりするので、細かくパタパタしようかなと思いました。

仕分け数判断のルックアップ取得で、'aコース','bコース','cコース' のコース料金値が決まりますが、同時存在するバタンと'aコース'だけが存在するバタンと組み合わせが発生しますので、Aプランでチェックいれて、それからルックアップで選んだほうがいいのかなと思いました。

その他のBプラン、Cプランとかはまだこれと違って、手動で入力だけのプランもあります。プランによって規定額がないのもありまして。

また、ルックアップ以外の項目についてですが、例えばdコース仕分でdコース料金①と②を間違って登録した場合、入力を消さない限り、チェックを外すだけでは裏で間違ったデータが残ることになるかなと思いました。

0
Avatar
rex0220

ルックアップで取得した場合、表示の有無に関係なくコピー対象はすべて更新されます。

'aコース'を非表示にしても、ルックアップ取得で値が設定されることになります。

コース選択よりも、ルックアップ取得のほうが優先順位が高いということです。

また 'aコース' を選択後、ルックアップ取得を行っても、'aコース' のデータだけ選択できる標準機能はありません。

かえって混乱する可能性があります。

 

ルックアップ取得が無いプランは、パタパタ表示でもいいかもしれません。

ケースによって使い分けてはいかがでしょう?

 

あとは、コース料金のクリアですが、

courseInfo に、設定している内容に応じて、処理する必要があります。

>courseInfo に、設定している内容に、下記の3種類があります。

これも、階層に応じて処理しましょう。

 

 

 

 

 

0
Avatar
岡戸 智子

いつもご指導ありがとうございます。

courseInfoの①シンプルな表示制御を試してみてます。一番簡単なバタンと思いますが、なかなか消えてくれません・・がんばります。

 

0
Avatar
岡戸 智子

rex0220 様

お世話になっております。

ちょっと訪ねたいですが、rex0220 さんは開発者と思われますが、案件とかは受注受けたりしますか?

例えば、kintoneでアプリは自社で作成するが、カスタマイズでプログラムを依頼する場合は対応可能でしょうか?

0
Avatar
rex0220

システム開発および kintone プラグイン開発を行っています。

既存アプリへの JavaScript カスタマイズなども承っていますので、対応は可能です。

よろしければ、下記のクラウドソーシングでご連絡ください。

ランサーズ A2013

クラウドワークス rex0220

ID は、異なりますがどちらでもOKです。

開発内容をご相談の上、お見積りさせていただきます。

 

0
サインインしてコメントを残してください。