文字 カウント リアルタイム

複数行フィールドに入力された文字をリアルタイムでカウントして、ラベルの横に表示したいと考えております。

developer networkの記事を参考に下記のコードを作成したのですが、文字を打った時の文字数が表示されてそれ以降カウントしてくれません。また詳細画面では文字が打っていても0文字で表示されてしまい詰まっています。

ご教授お願いします。

 

(function() {
  ‘use strict’;
  
kintone.events.on([‘app.record.detail.show’,‘app.record.create.show’,‘app.record.edit.show’,‘app.record.index.edit.show’], function (event) {
  // 本文に入力された文字数を取得
  const record = event.record;
  const mozi = record[‘honbun’][‘value’];
  let mozi_count = mozi.replace(/\s+/g, “”).length;
  
  //ラベルに文字数表示
  const count_mozi = document.createElement(‘span’);
  count_mozi.id = “count_mozi”;
  count_mozi.textContent = “現在”+0+“文字”;
  const label_element = document.getElementsByClassName(“label-6484780”)[0];
  
  //文字数カウント.表示変更
  const honbun_element = document.getElementsByClassName(“value-6484780”)[0];
  honbun_element.addEventListener(‘keyup’, function(){
  let mozi_count = mozi.replace(/\s+/g, “”).length;
  count_mozi.textContent = “現在”+mozi_count +“文字”;
}, false);

label_element.appendChild(count_mozi);

return event;
});
})();

 

 

最初に、keyupイベントを起こすtextareaにアクセスするためにはvalue-6484780より更に子要素を指定する必要があります。

  const honbun_element = document.getElementsByClassName("value-6484780")[0].getElementsByClassName('textarea-cybozu')[0];

 

①カウントされない理由

const mozi = record['honbun']['value'];

こちらがshowイベント時に宣言されていて、keyupイベント内でこの文字列の長さを参照しているため、「編集開始時に宣言した文字列(編集開始時の文字列)」をkeyupイベントで参照し続けていることになります。keyupイベント内で「現在の文字列フィールドの値」を参照する必要があります。

また、keyupイベントより先にappendChildされているmozi_countの値を変えても要素は変わらないので、mozi_countのidを指定して文字を変える必要があります。

    honbun_element.addEventListener('keyup', function(){
let mozi = kintone.app.record.get().record['honbun'].value;
    let mozi_count = mozi.replace(/\s+/g, "").length;
     document.getElementById('count_mozi').textContent = "現在"+mozi_count +"文字";

(この例ではkintone.app.record.get()で文字列を参照していますが、最終的にはindex.edit.showでも対応させるため直接textareaを指定する必要があります)

②詳細画面では0になる理由

「現在○文字」と表示する動作がkeyupイベント(キーの入力)以外で実行されていないためです(showイベント内では「現在0文字」と表示する動作しかありません)。最初のtextContent代入時に文字列の長さを指定する必要があります。

    count_mozi.textContent = "現在"+0+"文字"; 

  count_mozi.textContent = "現在"+(record['honbun'].value?.length || 0) +"文字";

 

また、

    let mozi_count = mozi.replace(/\s+/g, "").length;

こちらは文字列複数行フィールドが空白の時にエラーを起こします(空白時の値はundefind:文字ではないものであるのに対し、replace:文字に対して実行するものを実行)。本来であればif (mozi)と値があるかの判定後にreplaceを実行する必要がありますが、使っていないようなので削除した方が良いでしょう。

 

最終的には以下のような処理で可能です。

(() => {
    'use strict';

    let fieldNumber = '6484780';
    let fieldCode = 'honbun';

    kintone.events.on([
        'app.record.detail.show', 'app.record.create.show', 'app.record.edit.show', 'app.record.index.edit.show'
    ], (event) => {
        if (!document.getElementsByClassName(`label-${fieldNumber}`).length) return event;

        let record = event.record;
        let strLength = record[fieldCode].value?.length || 0;
        let label = document.getElementsByClassName(`label-${fieldNumber}`)[0];
        let span = document.createElement('span');

        span.id = 'count_moji';
        label.appendChild(span);

        document.getElementById('count_moji').textContent = `現在${strLength}文字`;

        if (!event.type.match(/detail/)) {
            let input = document.getElementsByClassName(`value-${fieldNumber}`)[0].getElementsByClassName('textarea-cybozu')[0];

          if (event.type.match(/index/)) input = document.getElementsByClassName('recordlist-editcell-inner-gaia')[0].getElementsByClassName('recordlist-forms-textarea-gaia')[0];

            input.addEventListener('keyup', () => {    
                strLength = input.value?.length || 0;
                document.getElementById('count_moji').textContent = `現在${strLength}文字`;
            });
        }

        return event;
    });
})();

mls-hashimoto

詳しい解説までして頂き有難うございます。

思っていた通りの実装が出来ました。

1点質問なのですが、

 record[fieldCode].value?.length || 0;の文法について

フィールドコードに文字が入っていればその文字数、そうでなければ0とするいう意味であっておりますか?

Hiro さま

実装できたようで何よりです。

質問の回答ですが、ご認識の通りです。説明が足りず申し訳ありません。

let strLength = 0;

if (record[fieldCode].value) strLength = record[fieldCode].value.length;

(if文)

let strLength = record[fieldCode].value ? record[fieldCode].value.length: 0;

(三項演算子)

以上と同じ処理を短くしたものです(オプショナルチェーン論理和 を使用しています)。

 

mls-hashimoto

ご教授頂き有難うございます。

大変勉強になりました。

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