サブテーブル内のフィールド更新 (.thenでエラーが出る。。)

背景・実現したいこと

レコード詳細画面を開いた際、

「①サブテーブルの各レコードが保持する着任日から現在までの経過年月を計算し、

** ②各レコードの経過年月フィールドに更新したい」**

サブテーブルが1レコードのときはうまくいきました。(画面の通り)

②については、複数レコードの場合は最終レコード以外は消え、

最終レコードの経過年月の更新のみ成功します。

自分が書いたコードですと、各レコード計算(33行目のForEach)毎にPUTしてしまっているのが

原因とは分かっているのですが、59行目のPUTを62行目にもっていくと、「更新でエラーが発生しました。paramPUT is not defined」のalertが出てしまいます。

お知恵を拝借頂けると助かります。

エラー情報

show.js:137 Uncaught TypeError: Cannot read property ‘then’ of undefined

このエラーが出てしまう理由も分かりません。(61行目のthenでエラー)

利用したソースコード

jQuery.noConflict();
(function() {
“use strict”;

// ロケールを初期化
moment.locale(‘ja’);
// 今日までの年月計算
function getYearMonth(dtDate) {
var dtToday = moment();
var dtFrom = moment(dtDate);
var years = 0;
var months = 0;
// 入力日が過去日付の場合計算
if (!dtToday.isBefore(dtFrom, ‘day’)) {
years = dtToday.diff(dtFrom, ‘years’);
months = dtToday.diff(dtFrom, ‘months’) % 12;
}
return years + '年 ’ + months + ‘ヶ月’;
}

kintone.events.on([“app.record.edit.show”,“app.record.detail.show”], function(event) {
var record = event.record;
var appId =kintone.app.getId();
var recId =kintone.app.record.getId();
var paramGet = {
‘app’: appId,
‘id’: recId
};
return kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘GET’, paramGet).then(function(resp) {
var record = resp.record;
var tableRecord = record.Table.value;

record.Table.value.forEach(function(row) {
var tableId = row.id;
// alert(row.id + row.value.氏名.value);
var keikaNengetsu = getYearMonth(row.value.着任日.value);
var paramPut = {
‘app’: appId,
‘id’: recId,
“record”: {
“project”: {
“value”: record[‘project’].value
},
“Table”: {
“value”: [
{
“id”: tableId,
“value”: {
“経過年月”: {
“value”: keikaNengetsu
}
}
}
]
}
}
};

return kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘PUT’, paramPut);

}).then(function(resp2) {
alert(‘更新が完了しました’);
return event;

}).catch(function(error) {
// エラー表示をする
alert(‘更新でエラーが発生しました。’ + error.message);
return event;
});

});
});
})();

こんにちは!

61行目の.then~ですが

カッコ(,{,},)を数えていくと

record.Table.value.forEach(function(row) {~~~~}).then(~~~

となっているので、forEachに対する.thenになっているように見えますので、

どのカッコがどのカッコに対応しているか見やすくなるように、一度最初からインデントを揃えてみられると良いと思います:eyes:

 

 

juridon様様

明けましておめでとうございます!

暮れには大変お世話になりました。

ご指摘いただいたところ、理解できました!毎度目から鱗です。

コーディング上でエラーがないのになぜ?と思ってましたが、根本的なところが分かっていませんでした。。

エラー出なくなりました!

お陰様で、本題に入れます。上のPUTでもできるのかもしれませんが、どうしても知恵及ばず、

先日ご教示頂きました、SETを使ってみました。

しかしながら、経過年月フィールドは更新されませんでした。

37行目でrecordオブジェクトに代入できていないので39行目でrecordをSETしてもNG

ということなのでしょうか? が、ではいったいどうやったらrecordオブジェクトに

代入できるのでしょうか? ヒント、アドバイス頂ければ幸いです。

また、上記のようなREST APIのGETに対し、kintone.app.record.set(record)でセットする使い方は

プログラム的に間違ってますでしょうか?

こんにちは!

エラーがなくなってよかったです^^

なのですが、実は、kintone.app.record.set(~~)や、event.recordの書き換えは、

詳細画面では使用できないのです(><)

追加、編集画面の、値を入力でいじることができる画面だけで使用できます。

https://developer.cybozu.io/hc/ja/articles/201942014#step4

かといって、表示のためだけにAPIを使ってGETやPUTするのもなんとなくオススメできないので、

フィールド要素を取得して、DOMで見た目だけ変更すると良いのではないかな:eyes:とおもいます!
https://developer.cybozu.io/hc/ja/articles/201942014-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E8%A9%B3%E7%B4%B0%E6%83%85%E5%A0%B1%E5%8F%96%E5%BE%97#step3

これもテーブル内のフィールドはゲットできないので、

まずテーブルの要素を取得して、経過年月の書かれてある<td></td>までたどっていって、

tdの要素.textContent =  getYearMonth(row.value.着任日.value);
みたいにするといいかも知れません(><)!

juridon様様

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

なんと驚いたことに、仰る通り「詳細画面」でしか検証してなっかったため、

初めて「編集画面」を開いたところ、(「kintone.app.record.set(~~)をイベントハンドラ中に実行できません(英文)」

のエラーは出つつも、なんと!上のコードで複数件が見事更新されました!!(びっくりで感動です!(俺は間違ってなかった的なw))

そして「DOMで見た目だけ変更する」というご提案ありがとうございます。天才的ですね!

確かに開いたときにのみ意味のあるデータを保存する必要ないです。

自分にとっては新機軸な発想ですが、なんとなく

見覚えのあるような、分かるような気がしてきました。チャレンジしてみます!

お世話になっております。頂いたアドバイスにより、少し近づいたような気がします。

var classes =document.getElementsByClassName(‘control-value-content-gaia’);
for (const classNode of classes) {
classNode.innerText = “OK”;
}

試しに、上記を実行すると、ちゃんとOKと表示されました!!

しかしながら共通のclass名なので該当以外の複数個所”OK”と表示されてしまいます。

配列で指定するとエラーが出ました。

方向性的には合ってますでしょうか??

さらに付加的なDOM操作等を施すことで道筋はありますでしょうか?

 

こんにちは!

夜中まで作業されていたんですね(TдT!お疲れさまです!

たとえば↓こんなかんじでテーブルの行のDOM操作できます。

//テーブルの要素を取得  
consttableData=kintone.app.record.getFieldElement("テーブル");  
//テーブルのtbody要素を取得  

consttableBody=tableData.tBodies[0];  
//テーブルのrows(行、tr)の要素を取得  
consttableRows=tableBody.rows;  
  
 //↓1行目の1列目 みたいに使えます  
 tableRows[0].cells[0]

for文などの繰り返しを回して、

目的の要素.textContent = “●●ヶ月”;

とやるとOKだと思います!

 

ただ、DOM操作するには、詳細画面が完全に表示し終わるのを待つ必要があるので、
↓こちらのトピックも参考にされてみてください:eyes:
https://developer.cybozu.io/hc/ja/community/posts/360000775166-%E8%A9%B3%E7%B4%B0%E7%94%BB%E9%9D%A2%E8%A1%A8%E7%A4%BA%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E6%99%82%E3%81%AB-%E3%82%B5%E3%83%96%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E6%8F%8F%E7%94%BB%E5%AE%8C%E4%BA%86%E3%82%92%E5%BE%85%E3%81%A3%E3%81%A6%E3%81%8B%E3%82%89DOM%E3%82%92%E6%93%8D%E4%BD%9C%E3%81%97%E3%81%9F%E3%81%84

 

juridon

ご返信頂き誠に有難うございます。

教えて頂いたtableRows[0].cells[0]ですが、

alertで(いろんな配列で試しましたが)すべて[object HTMLTableCellElement]とのみ表示されました。

console.log(tableRows)で中身は見れましたが、よく理解できませんでした。。

さて、Tableの「経過年月」の「番目」みたいなのが分かったので(★のところ)

下記のようなコードで一応目的は果たせました!!先にjuridon様が「経過年月の書かれてある<td></td>までたどっていって,」
の原始人版かもしれませんが,( ;∀;)

var record = resp.record;
var tableRecord = record.Table.value;

var rownum = 0;
var atai;

tableRecord.forEach(function(row) {
var chakunin = getYearMonth(row.value.着任日.value);
rownum ++;
atai = ( 6 * rownum) + 1; //★

var classes =document.getElementsByClassName(‘control-value-content-gaia’);
var num = 0;
for (const classNode of classes) {
num ++;
if(num ===atai){
// alert(rownum +" 当たり! " + num);
classNode.innerText = chakunin;
}
}
});

ーーーーーー

ただ、「DOM操作するには、詳細画面が完全に表示し終わるのを待つ必要がある」ということで

表示がすべてできないときは、F5すればだいたい全て表示されますので、一旦はこれでヨシと致します。

教えて頂いたsetinterval()のトピックですが、Kintone構文の場合、どこにどのように挟めばよいか

ちょっとまだ自分には難解でした。。

お役に立てたみたいで良かったです:sparkles::sparkles:!!

私もDOMはよく分かっていないところが多くて:sweat_drops:何番目~と辿って行くの大正解だと思います:eyes:!!

setIntervalは結構苦し紛れな方法なので、使わずにうまくいくんだったらOKです(*´ω`*):sparkles::sparkles: