app.record.create.showの登録を同期的に行いたい

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

 

フォームに入力されている文字数をカウントするJavaScript が読み込まれた時に、

同期的に実行されていないという警告がブラウザの開発者コンソールに表示されてしまうので、解消できる方法を探しております。

 

イベントハンドラー登録の適切なタイミングについて

を参考に、わけて記述しようとすると実行されなくなってしまいます。

Promiseを使った記述にもトライしましたが、

「Error: Usage: kintone.events.on(event, handler)」というエラーが表示されうまくいきませんでした。

 

どなたか、ご教示いただけますと幸いです。

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

 

 

現在作成しているソースコード↓

 

jQuery.noConflict();

(function($) {

"use strict";

var $ = jQuery;

// IDタグ

const ID_TAG ='id';

// クラスタグ

const CLASS_TAG ='class';

// 対象要素タグ

const TARGET_ELEMENTS_TAG ='.control-gaia';

// フィールドプレフィックスタグ

const FIELD_PREFIX_TAG ='field-';

$(function() {

// この部分が対象となる仮データ

// 他の画面で設定された内容を元に下記のデータを作成する FieldName, 項目長とする

var _targetList = [];

_targetList.push(new item('内容及び理由【400字以内で記載願います】', 400, 'textarea'));

var handler =function(event) {

var _fieldMap = createFieldMap(_targetList);

execute4Event(event, _fieldMap);

return event;

}

var events = [

'app.record.create.show',

'app.record.edit.show'

];

kintone.events.on(events, handler);

});

/**

* フィードを作成する

* @param targetList 対象リスト

*/

function createFieldMap(targetList) {

var _fieldMap = {};

// 1.対象のフィールドの値を設定

$.each(targetList, function(index, value) {

_fieldMap[value.name] = value;

});

// 2.フィールドを取得

$(TARGET_ELEMENTS_TAG).each(function (index, element) {

var _tag = $(element).attr(CLASS_TAG);

var _index = _tag.lastIndexOf(FIELD_PREFIX_TAG);

// プレフィックスが見つからなかったら、スキップ.

if (_index ===-1) returntrue;

_index += FIELD_PREFIX_TAG.length;

var _code = _tag.substring(_index);

var _label = $(element).find(getLabelTag(_code));

var _title = $(_label).text();

// キーが存在しない場合、スキップ.

if (!(_title in _fieldMap)) returntrue;

var _type = _fieldMap[_title].type;

var _value = $(element).find(getValueTag(_code, _type));

_value.attr(ID_TAG, _code);

_fieldMap[_title].element = {

label : _label,

value : $(_value).attr(ID_TAG)

}

// カウントダウンの場合

// $(_label).text(_fieldMap[_title].getTitle());

// カウントアップの場合

$(_label).text(_fieldMap[_title].getUpTitle());

})

return _fieldMap;

}

/**

* ラベルタグを取得する

* @param code コード

*/

function getLabelTag(code) {

return'.label-'+ code +' span';

}

/**

* Valueタグを取得する

* @param code コード

* @param type 種類

*/

function getValueTag(code, type) {

if (type ==='input') {

return'.value-'+ code +' input';

} else if (type === 'textarea') {

return'.value-'+ code +' textarea';

}

return'';

}

/**

* 項目情報

* @param name 名称

* @param maxLength 最大項目長

* @param type 種類

* @param element 要素

*/

var item =function(name, maxLength, type, element ) {

this.name = name;

this.maxLength = maxLength;

this.type = type;

this.element = element;

}

item.prototype = {

/**

* タイトルを取得する

* @returns タイトル

*/

getTitle : function () {

returnthis.name +'('+this.getInputLength() +')';

},

/**

* タイトルを取得する

* @returns タイトル

*/

getUpTitle : function () {

var _length =this.addInputLength();

if (_length ===0) returnthis.name;

returnthis.name +'('+ _length +'文字'+')';

},

/**

* 入力長を取得する

* @returns 入力長

*/

getInputLength: function () {

var _length =this.maxLength;

if (this.element !==null) {

_length -= $('#' + this.element.value).val().length;

}

return _length;

},

addInputLength: function() {

if (this.element !==null) return $('#'+this.element.value).val().length;

},

forceSubstring: function() {

var _force_value = $('#'+this.element.value).val().substring(0, this.maxLength);

$('#' + this.element.value).val(_force_value);

}

}

/**

* イベントを実行する

* @param event イベント

* @param fieldList フィールドリスト

*/

function execute4Event(event, fieldMap) {

$.each(fieldMap, function(key, item){

$('#' + item.element.value).bind('keyup', function (textEvent) {

// カウントダウンの場合

// $(value.element.label).text(value.getTitle());

if (item.getInputLength() <0) {

// この制御に関しては、現行を元にそのままにしている

alert(item.name + 'は項目長を超えました.');

item.forceSubstring();

}

$(item.element.label).text(item.getUpTitle());

});

});

}

/**

* パラメーターデバッグ

* @param event イベント

* @param fieldList フィールドリスト

*/

function debugParam(event, fieldMap) {

$.each(fieldMap, function(key, value){

console.log(value.name);

console.log(value.maxLength);

});

console.log(event);

}

})(jQuery);

 

 

矢形 亮 さん

サンプルコードを簡単に確認してみましたが、
まず、以下の$(function() ~ )の中にkintone.events.on()を表記し、
さらにkintone.events.onのコールバック関数内(サンプルコードでいうhandler関数内)でreturn eventしているせいで該当のエラーが出ています。

回避するためには、$(function() ~ )の「$」を外す $(function() ~ )内にkintone.events.on()を書かないの2つです。

$(function() {
// この部分が対象となる仮データ
// 他の画面で設定された内容を元に下記のデータを作成する FieldName, 項目長とする
var _targetList = [];
_targetList.push(new item('内容及び理由【400字以内で記載願います】', 400, 'textarea'));
var handler =function(event) {
var _fieldMap = createFieldMap(_targetList);
execute4Event(event, _fieldMap);
return event;
}
var events = [
'app.record.create.show',
'app.record.edit.show'
];
kintone.events.on(events, handler);
});

どのような処理を実装しているかまでは確認していませんが、
サンプルコードではeventオブジェクトの中身を使用していないようなので、
解決できるかは不明ですが、kintone.events.on()を削除されてみてはどうでしょう。

見たところDOM操作をしているようですが、
もし、DOMの描画を待って処理する必要があるならば、
エラーは我慢してkintone.events.on()のままにするか、他の方法で描画を待つ必要がありそうです。
ただ製品アップデートで使用できなくなる可能性はあります。

 HANSAさま

ご回答ありがとうございます。指摘いただいた箇所の修正を試したところ、

・「$(function() ~ )内にkintone.events.on()を書かない」
→削除したら動いた
・「$(function() ~ )の「$」を外す」
→外したら動かなかったのでいったんそのまま

といった対応で警告を出さずに文字数カウントができたのですが、
途中でalertを入れないと別の箇所で「Uncaught TypeError: Cannot read property ‘value’ of undefined」というエラーが起きるようになりました
window.onloadで実行している部分の記述で何か良い方法がありましたら教えていただければと思います。

どうぞよろしくお願いいたします。

修正した箇所(ソース全体の20行目付近)↓

$(function() {

// この部分が対象となる仮データ.

// 他の画面で設定された内容を元に下記のデータを作成する FieldName, 項目長とする

var _targetList = [];

_targetList.push(new item('内容及び理由【400字以内で記載願います】', 400, 'textarea'));

alert(1); //これを外したい

window.onload = function(event) {

var _fieldMap = createFieldMap(_targetList);

execute4Event(event, _fieldMap);

return event;

};

});

 

エラーが起きる箇所(ソース全体の140行目付近)↓

/**

* イベントを実行する

* @param event イベント

* @param fieldList フィールドリスト

*/

function execute4Event(event, fieldMap) {

$.each(fieldMap, function(key, item){

$('#' + item.element.value).bind('keyup', function (textEvent) {

// カウントダウンの場合

// $(value.element.label).text(value.getTitle());

if (item.getInputLength() <0) {

// この制御に関しては、現行を元にそのままにしている

alert(item.name + 'は項目長を超えました.');

item.forceSubstring();

}

$(item.element.label).text(item.getUpTitle());

});

});

}

矢形 亮 さん

DOM操作で文字列の長さをチェックするのならば、

まずは、$(function() ~ ) と wondow.onload()について理解する必要があると思います。

参考:https://qiita.com/mimoe/items/74cb3a01a30162759fdd

さらに、kintonejavascriptカスタマイズでwindow.onloadでHTMLの描画を待っても、レコード詳細画面などの要素の描画を待つことができません。

 

実装したい処理はどういった処理でしょうか。

○○のタイミングで××の処理をしたい。等が分かればアドバイスできると思います。

HANSAさま

実装したい処理は、文字列(複数行)のフォームに値が入力されたタイミングで、文字数をカウントする、です。
以下の添付画像のように、「内容及び理由【400字以内で記載願います】」というフォーム名の右にあるカウンターがリアルタイムで更新される処理を現在実装しております。

サンプルコードについて何かしらアドバイスできる箇所がありましたらよろしくお願いいたします。