フィールドに値を計算セットしたが画面上に反映されない件

いつもお世話になっております。JavaScriptでカスタマイズしておりますが、行き詰ってしまい、ご教示いただけると幸いです。よろしくお願いいたします。

a.【フォーム内容】
基準日(日付)
生年月日(日付)
年齢(文字列1行)

b.【仕様】
[年齢]フィールドは、[生年月日]から[基準日]時点での年齢をセットしておくフィールドです。
•レコード追加イベント(app.record.create.show)、
•レコード編集イベント(app.record.edit.show)
において、[基準日]に本日日付を自動セットします。
また、[年齢]フィールドは自動計算するので入力不可に設定します。

c.【作業手順】

  1. 新規レコード追加画面で、[基準日]に本日日付(2016-09-07)が自動でセットされます。
  2. [生年月日]に(1964-12-17)を入力すると、[年齢]フィールドに[51年9ケ月]がセットされます。
  3. 一旦保存します。
  4. 本レコードを再度編集します。
  5. [基準日]を[2020-01-01]に変更すると、[55年1ケ月]の内容が[年齢]フィールドにセットされます。
  6. 一旦保存します。
  7. 本レコードを再度編集します。
  8. app.record.edit.showの結果、[基準日]に本日日付が自動セットされ、[51年9ケ月]の内容が
    計算されて、[年齢]フィールドにセットされると考えましたが、画面上には反映されず、
    [55年1ケ月]のままとなりました。alertで計算内容を表示すると、正しく計算しているような
    状況なのに反映されないのがよくわかりませんでした。
    プログラムの改善点をご指摘いただけると幸いです。

e.【JavaScript内容】

(function() {
    “use strict”;
// 基準日までの年月計算(経過年月数の計算)
    function nen_set(dtDate, dtRefDate, typeDate) {
        var dtToday = new Date(dtRefDate);  //基準日
        var dtFrom = new Date(dtDate);
        switch (typeDate) {
            case ‘yy’:
                var intDays = (dtToday - Date.parse(dtDate)) / 1000 / 60 / 60 / 24;
                return Math.floor(intDays / 365);
            case ‘yymm’:
                var intYear = dtToday.getFullYear() - dtFrom.getFullYear();
                var intMonth = dtToday.getMonth() - dtFrom.getMonth();
                if (intMonth < 0) {
                    intYear–;
                    intMonth += 12;
                }
                return intYear + “年” + intMonth + “ケ月”;
            default:
                return null;
        }
    }

//前ゼロの文字列を作成する関数
    function zeroformat(v, n) {
        var v1 = String(v).length;
        if (n > v1) {
                return (new Array((n - v1) + 1).join(0)) + v;
        } else {
                return v;
        }
    }

 kintone.events.on([‘app.record.create.show’,
                    ‘app.record.edit.show’], function(event) {
        var record = event.record;
        // フィールド制御
        record[‘年齢’][‘disabled’] = true;

        // 基準日に今日をセット
        var dt = new Date();
        var today = dt.getFullYear() + “-” + zeroformat((dt.getMonth()+1),2) + “-” + zeroformat(dt.getDate(),2);
        record[‘基準日’].value = today;

        return event;
 });

//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
    kintone.events.on([‘app.record.edit.change.生年月日’,
                        ‘app.record.create.change.生年月日’,
                        ‘app.record.index.edit.change.生年月日’,
                        ‘app.record.edit.change.基準日’,
                        ‘app.record.create.change.基準日’,
                        ‘app.record.index.edit.change.基準日’], function(event) {

        var record = event.record;
        var wkDate = record[‘生年月日’].value;
        var wkReferenceDate = record[‘基準日’].value;

        if ((wkDate === undefined) || (wkReferenceDate === undefined)) {
            record[‘年齢’].value = “”;
            return event;
        }

        alert(‘wkDate=’ + wkDate + ‘,wkReferenceDate=’ + wkReferenceDate);
        var wkRetVal = nen_set(wkDate, wkReferenceDate, ‘yymm’);        //「○年○ケ月」を求める
        alert(‘wkRetVal=’ + wkRetVal);
        record[‘年齢’].value = wkRetVal;

        return event;
    });
})();

teraさん

サイボウズスタートアップス武井です。

 

showイベントの中でchangeイベントを発生させていることが原因です。

以下のように修正することで解消できます。

(function () {
	"use strict";
// 基準日までの年月計算(経過年月数の計算)
	function nen_set(dtDate, dtRefDate, typeDate) {
		var dtToday = new Date(dtRefDate); //基準日
		var dtFrom = new Date(dtDate);
		switch (typeDate) {
			case 'yy':
				var intDays = (dtToday - Date.parse(dtDate)) / 1000 / 60 / 60 / 24;
				return Math.floor(intDays / 365);
			case 'yymm':
				var intYear = dtToday.getFullYear() - dtFrom.getFullYear();
				var intMonth = dtToday.getMonth() - dtFrom.getMonth();
				if (intMonth < 0) {
					intYear--;
					intMonth += 12;
				}
				return intYear + "年" + intMonth + "ケ月";
			default:
				return null;
		}
	}

//前ゼロの文字列を作成する関数
	function zeroformat(v, n) {
		var v1 = String(v).length;
		if (n > v1) {
			return (new Array((n - v1) + 1).join(0)) + v;
		} else {
			return v;
		}
	}

	var flg = true;
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
	kintone.events.on(['app.record.edit.change.生年月日',
		'app.record.create.change.生年月日',
		'app.record.index.edit.change.生年月日',
		'app.record.edit.change.基準日',
		'app.record.create.change.基準日',
		'app.record.index.edit.change.基準日',
		'app.record.create.show',
		'app.record.edit.show'], function (event) {
		var record = event.record;

		if (event.type === 'app.record.create.show' || event.type === 'app.record.edit.show') {
			// フィールド制御
			record['年齢']['disabled'] = true;

			// 基準日に今日をセット
			var dt = new Date();
			var today = dt.getFullYear() + "-" + zeroformat((dt.getMonth() + 1), 2) + "-" + zeroformat(dt.getDate(), 2);
			if (record['基準日'].value !== today) {
				record['基準日'].value = today;
				flg = false;
				return tekitou(event);
			}
		} else if (flg) {
			return tekitou(event);
		} else {
			flg = true;
		}

		return event;
	});

	function tekitou(event) {
		var record = event.record;
		var wkDate = record['生年月日'].value;
		var wkReferenceDate = record['基準日'].value;

		if ((wkDate === undefined) || (wkReferenceDate === undefined)) {
			record['年齢'].value = "";
			return event;
		}

		alert('wkDate=' + wkDate + ',wkReferenceDate=' + wkReferenceDate);
		var wkRetVal = nen_set(wkDate, wkReferenceDate, 'yymm'); //「○年○ケ月」を求める
		alert('wkRetVal=' + wkRetVal);
		record['年齢'].value = wkRetVal;
		return event;
	}
})();

 

武井様、お世話になります。

showイベントの中でchangeイベントを発生させるとうまく動作しないのですね。

ご指南いただいたプログラムでうまく動作いたしました。ありがとうございました。

お世話になります。1つ疑問点があり、考えてみましたがよくわからなく、投稿させていただきました。

showイベントの中でchangeイベントを発生させていることがフィールド内容が変わらない原因とのことですが、[基準日]フィールドもshowイベントの中でchangeイベントを発生させているのもかかわらず、うまく動作するのは何故でしょうか?

ご教示いただけると幸いです。

 

teraさん

詳しい仕様は内部の人間でないので分かりませんが、

私の予想だと、eventのreturnのタイミングの問題な気がします。

 

なので、もしかするとコード的には

「showイベントの中でchangeイベントを発生させていることが原因」であっても、

内部構造の中では厳密にはこの原因ではないかもしれません。

 

武井様

奥が深いですね。'app.record.detail.show’イベントでも同様に処理できるようにしようと考えていますが、少し手を入れるとうまく動作しないような気がしてきました。。。参考にさせていただきます。ありがとうございました。

'app.record.detail.show’イベントでも同様に処理できるようにしようとしましたが、やはりうまく動作しませんでした。

簡単なサンプルアプリで動作確認したところ、'app.record.detail.show’イベントでは値をセットしてフィールドの更新ができないように思いますが、いかがでしょうか。ご存じであればご教示いただけると幸いです。

サンプルフォーム:「フリガナ(文字列1行)」

サンプルJavaScript

その1

(function () {
 “use strict”;

    kintone.events.on([‘app.record.detail.show’], function(event) {
        var record = event.record;
        record[‘フリガナ’].value = “テスト組み込みフリガナ”;
        return event;
    });
})();

その2

(function () {
 “use strict”;
    function sample_set(event) {
        var record = event.record;
        record[‘フリガナ’].value = “テスト組み込みフリガナ”;
        return event;
    }

    kintone.events.on([‘app.record.detail.show’], function(event) {
        var record = event.record;
        sample_set(event);
        return event;
    });
})();

「その1」「その2」のいずれにおいてもフィールドの更新はできませんでした。

以上よろしくお願いいたします。

teraさん

当然detail.showイベントで同様には動作しません。

PUT処理が必要です。

 

また、PUTした後に、ブラウザ表示上の年齢も更新したい場合は、

DOM操作で無理矢理書き換えるか、画面を更新させる処理も必要となるでしょう。

ハードルが一気に上がってしまいました。初心者なもっと勉強してから挑みたいと思います。ありがとうございました。