kinotne JavaScript 追加画面 スペースにテーブル表示

いつもお世話になっております。

kintoneを使い始めたばかりですが、ご指摘いただきたいです。

現在、問合せ管理システムを作成しており、フィールド追加画面のスペースに該当する店舗の一覧を表示したいのですが、取得ボタンを押すたびに、表示テーブルの順番が変わってしまい、どうしたらよいかわからない状態です。

現在のソースはこちらです。

店舗情報はほかアプリにマスタを作成しています。

kintone.events.on(‘app.record.create.change.spStoreBoutonPartial’, function(event) {
var record = event.record;
var i = record.tblStore.value;
var acount=1;
var k=0;
var code = new Array();
var si = record.txtCity.value;
var ken = record.txtStorePrefecture.value;
for(var j=0;j<5;j++){
if(i[j].value[‘tblStoreOfficial’].value!=null){
code[k] = i[j].value[‘tblStoreOfficial’].value;
k++;
}
}
for(var j = 0;j < 8;j++){
if(record[‘drpsStoreCategory’][‘value’][j] != null){
code[k] = record[‘drpsStoreCategory’][‘value’][j];
k++;
}
}

var manager = new KintoneRecordManager;
manager.appId = 301; // レコード取得先のアプリID

console.log( kintone.app.record.getSpaceElement(‘spStoreTable’));

// 検索条件の指定
for(var m=0;m<k;m++){
if(ken != null){
var query = ‘住所 like "’ + ken + ‘"’; //都道府県で検索
if(si != null){
query = query + ’ and 住所 like “’ + si + '”'; //市区町村で検索
}
}else if(si != null){
var query = ‘住所 like "’ + si + ‘"’;
}

//商品記号、商品カテゴリーで検索
if(code[m] != null){
if(code[m] == “シャンプー&コンディショナー”){
query = query + ’ and シャンプーコンディショナー =“’ + code[m] + '”‘;
}else if(code[m] == “養毛料+染毛料”){
query = query + ‘and 養毛料_染毛料 = "’ + code[m] + ‘"’;
}else{
query = query + ’ and ’ + code[m] + ’ = "’ + code[m] + ‘"’;

}
}
alert(m);
manager.query = query + ’ order by 更新日 desc’; //更新日順に並び替え

var hit = 0;
manager.getRecords(function(records) {
// レコード取得後の処理
console.log(records);

alert(m);

//レコードの表示
var tblTr = new Array();
var tblTd = new Array();
var tblTd1 = new Array();
var tblTd2 = new Array();
var tblTd3 = new Array();
var tblTd4 = new Array();
var tblTd5 = new Array();
var tblTd6 = new Array();
var tblTd7 = new Array();
var tblTd8 = new Array();
var tblTd9 = new Array();

var tbody = document.createElement(‘tbody’);
var caption = document.createElement(‘caption’);

var th = document.createElement(‘th’);
var th1 = document.createElement(‘th’);
var th2 = document.createElement(‘th’);
var th3 = document.createElement(‘th’);
var th4 = document.createElement(‘th’);
var th5 = document.createElement(‘th’);
var th6 = document.createElement(‘th’);
var th7 = document.createElement(‘th’);
var th8 = document.createElement(‘th’);
var th9 = document.createElement(‘th’);
th.bgColor=(“pink”);
th1.bgColor=(“pink”);
th2.bgColor=(“pink”);
th3.bgColor=(“pink”);
th4.bgColor=(“pink”);
th5.bgColor=(“pink”);
th6.bgColor=(“pink”);
th7.bgColor=(“pink”);
th8.bgColor=(“pink”);
th9.bgColor=(“pink”);

caption.appendChild(document.createTextNode(“【”+code[acount]+“】”));

th.appendChild(document.createTextNode(“店舗紹介”));
th1.appendChild(document.createTextNode(“ショップ名”));
th2.appendChild(document.createTextNode(“取り寄せ案内”));
th3.appendChild(document.createTextNode(“店舗名”));
th4.appendChild(document.createTextNode(“TEL”));
th5.appendChild(document.createTextNode(“住所”));
th6.appendChild(document.createTextNode(“更新日”));
th7.appendChild(document.createTextNode(“確認日”));
th8.appendChild(document.createTextNode(“備考欄”));
th9.appendChild(document.createTextNode(“取扱い商品”));

var tr = document.createElement(‘tr’);
tr.appendChild(th);
tr.appendChild(th1);
tr.appendChild(th2);
tr.appendChild(th3);
tr.appendChild(th4);
tr.appendChild(th5);
tr.appendChild(th6);
tr.appendChild(th7);
tr.appendChild(th8);
tr.appendChild(th9);

tbody.appendChild(caption);
tbody.appendChild(tr);

var tblcb = new Array();
var nul=0;
var idname =kintone.app.record.get().record.txtShopCount1.value;
idname=parseInt(idname);
for (var key in records) {
if(records[key][“量販店名”][“value”]!=“”){ //空白のレコードは表示させないようにする
tblTr[key] = document.createElement(‘tr’);

tblTd[key] = document.createElement(‘td’);
tblTd[key].width = 40;
var cb = document . createElement ( ‘input’ );
cb . type = ‘checkbox’ ;
cb.id = ‘cb’ + idname;
tblTd[key] . appendChild ( cb );

tblTd1[key] = document.createElement(‘td’);
tblTd1[key].id=“shop”+idname;
tblTd1[key].width=150;
tblTd1[key].appendChild(document.createTextNode(records[key][“量販店名”][“value”]));

tblTd9[key] = document.createElement(‘td’);
tblTd9[key].width = 50;
var cb = document . createElement ( ‘input’ );
cb . type = ‘checkbox’ ;
cb.id = ‘stock’ + idname;
tblTd9[key] . appendChild ( cb );

tblTd2[key] = document.createElement(‘td’);
tblTd2[key].id=“store”+idname;
tblTd2[key].width=130;
tblTd2[key].appendChild(document.createTextNode(records[key][“販売店名”][“value”]));

~省略~

 

tblTd6[key] = document.createElement(‘td’);
tblTd6[key].id=“memo”+idname;
tblTd6[key].width=160;
tblTd6[key].appendChild(document.createTextNode(records[key][“メモ”][“value”]));

tblTd7[key] = document.createElement(‘td’);
tblTd7[key].id=“code”+idname;
tblTd7[key].width=250;
tblTd7[key].appendChild(document.createTextNode(records[key][“KH”][“value”]));
tblTd7[key].appendChild(document.createTextNode(" "));
~省略~
tblTd7[key].appendChild(document.createTextNode(records[key][“ZC”][“value”]));

 

tblTr[key].appendChild(tblTd[key]);
tblTr[key].appendChild(tblTd1[key]);
tblTr[key].appendChild(tblTd9[key]);
tblTr[key].appendChild(tblTd2[key]);
tblTr[key].appendChild(tblTd3[key]);
tblTr[key].appendChild(tblTd4[key]);
tblTr[key].appendChild(tblTd8[key]);
tblTr[key].appendChild(tblTd5[key]);
tblTr[key].appendChild(tblTd6[key]);
tblTr[key].appendChild(tblTd7[key]);
tbody.appendChild(tblTr[key]);

idname++;
hit++;
}else{
nul++;
}

}

if(hit == 0){ //1件でも表示されたらhitは1以上になるので0の場合は販売店がない
tblTd1[0] = document.createElement(‘td’);
tblTd1[0].colSpan = 9;
tblTd1[0].appendChild(document.createTextNode(“販売店はありません”));
tbody.appendChild(tblTd1[0]);

}

var table = document.createElement(‘table’);
table.id=“table5”;
table.border = 1;

//表示した件数を隠しフィールドの店舗件数1に代入
key=parseInt(key);
key=key-nul;
key=key+1;
var div = document.createElement(‘div’);
div.appendChild(document.createTextNode(“該当件数:” + key));
kintone.app.record.getSpaceElement(‘spCount’).appendChild(div);
var i =kintone.app.record.get().record.txtShopCount1.value;
i=parseInt(i);
key=i+key;
var record = kintone.app.record.get();
record[‘record’][‘txtShopCount1’][‘value’] = key;
kintone.app.record.set(record);

table.appendChild(tbody);
//bodyに追加
kintone.app.record.getSpaceElement(‘spStoreTable’).appendChild(table);

//表示したレコードを空白にする。※取得ボタンを2度以上押された場合、何度も同じデータが表示されるのを防ぐため
for (var key in records) {
for (var value in records[key]){
records[key][value][“value”] = “”;
}
}

acount++;
var record = kintone.app.record.get();
record[‘record’][‘txtCount’][‘value’] = acount;
kintone.app.record.set(record);

});
}
return event;
});

/**
* kintoneと通信を行うクラス
*/
var KintoneRecordManager = (function() {
KintoneRecordManager.prototype.records = []; // 取得したレコード
KintoneRecordManager.prototype.appId = null; // アプリID
KintoneRecordManager.prototype.query = ‘’; // 検索クエリ
KintoneRecordManager.prototype.limit = 100; // 一回あたりの最大取得件数
KintoneRecordManager.prototype.offset = 0; // オフセット

function KintoneRecordManager() {
this.appId = kintone.app.getId();
}

// すべてのレコード取得する
KintoneRecordManager.prototype.getRecords = function(callback) {
kintone.api(
kintone.api.url(‘/k/v1/records’, true),
‘GET’,
{
app: this.appId,
query: this.query + (’ limit ’ + this.limit + ’ offset ’ + this.offset),
fields: [“KH”,~省略~,“ZN”,“量販店名”, “販売店名”, “TEL”, “住所”, “確認日”, “メモ”,“更新日”]
},
(function(_this) {
return function(res) {

var len;
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); // レコード取得後のcallback

}
} else {
_this.getRecords(callback); // 自分自身をコール

}
};
})(this)
);

 

きれいなソースでなく、初心者で申し訳ありませんが、ご指摘よろしくお願いいたします。

また、kintoneのJavaScript連携を学びたいので、学べるセミナーなども教えていただきたいです。

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

パット見ですが、カテゴリー順にデータを取得して表示するという意図かと思いますが、for文中で非同期処理である manager.getRecords がコールされていることが意図通りにいっていない原因ではないでしょうか。(for文中における)非同期処理に関するトピックは過去に幾つかありましたので、確認頂くのが良いかと思います。(文字通り非同期ですので、for文の順序どおりAPIの処理は実行されません。ですので、for文ではなくて・・・という回答が鉄板で記載されています)

 

> kintoneのJavaScript連携

 

まずは、「はじめよう kintone JavaScript API(https://cybozudev.zendesk.com/hc/ja/sections/200332780)」からスタートして、その他のTipsや一般のJavaScriptの記事を通して学んでいくことになると思いますが、リアルな勉強会・セミナーもググってもらうと幾つか出てくると思いますので、チェックされてはいかがでしょうか。

Yamashita様

迅速な対応ありがとうございます。

非同期の部分は納得いたしました。

for文以外の対応策が思いつかない状態なのですが、初心者でも使える方法はありますでしょうか?

他のトピックにあるようにPromiseで処理するのが定石な感じですが、ハードルが高いかと思います。

 

ただ、今回は取得してくるアプリもひとつなので、そもそもカテゴリで区切りながらリクエストするのではなくて、ワンショットでリクエストして、取得後にソートする等で対応した方が良いように思いました。なお、取得時に複数の項目でソートする条件も付けることが出来ますので、そこで対応してしまうのも良いと思います。( 参考リンク https://www.joyzo.co.jp/blog/1277 )

Yamashita様

ありがとうございます。

やはり難しいですか。

対応策もありがとうございます。

検証してみます。

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。