行の文字数カウント

Kintoneで、「入力中の行の文字数」をカウントしたい。

  • 現在、文字数カウントは「スペースID:ButtonSpace2」を使用しており、入力時に文字数をJSでカウントしています。
  • これを、スペースではなく「フィールド」に変更したいと考えています。
  • フィールド :文字列(複数行)
    フィールド名 :内容
    フィールドコード:内容
  • ただし、フィールド内で文字数のカウントを表示する方法がうまくいかないきません。
  • 文字数をカウントし、「文字数」という数値フィールドを作成してそこに代入する方法はありますが、アプリ内には既にたくさんのフィールドがあるため、これ以上フィールドを増やしたくありません。
  • 現在は、カーソル位置に文字数を表示する方法を採用していますが、スペース以外で実現できる方法があるか知りたいです。
  • スペースだと文字数のカウントは表示できても、入力した文字を保存できないため、
    文字列フィールドに文字数のカウント機能を持たせることを希望しています。
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function () {
    const spaceId = 'ButtonSpace2';  // 使用するスペースID

    const spaceElement = kintone.app.record.getSpaceElement(spaceId);
    if (!spaceElement) {
        console.error('指定されたスペースが存在しません。');
        return;
    }

    const maxLength = 25;

    // テキストエリアの作成
    const textarea = document.createElement('textarea');
    textarea.rows = 5;
    textarea.cols = 50;
    textarea.placeholder = 'ここに入力してください';
    textarea.style.fontSize = '14px';
    spaceElement.appendChild(textarea);

    // ツールチップ(吹き出し)の作成
    const tooltip = document.createElement('div');
    tooltip.style.position = 'absolute';
    tooltip.style.backgroundColor = '#f8f8f8';
    tooltip.style.border = '1px solid #ccc';
    tooltip.style.padding = '4px 8px';
    tooltip.style.borderRadius = '6px';
    tooltip.style.fontSize = '12px';
    tooltip.style.display = 'none';
    tooltip.style.pointerEvents = 'none';
    tooltip.style.zIndex = 1000;
    document.body.appendChild(tooltip);

    // 全角換算で文字数をカウント(半角=0.5, 全角=1)
    function countFullWidth(str) {
        let len = 0;
        for (let char of str) {
            len += /[ -~]/.test(char) ? 0.5 : 1;
        }
        return len;
    }

    // 現在行のテキストを取得
    function getCurrentLine(text, caretPos) {
        const lines = text.substring(0, caretPos).split('\n');
        return lines[lines.length - 1] || '';
    }

    // 入力・カーソル移動時に吹き出し更新
    function updateTooltip(e) {
        const caretPos = textarea.selectionStart;
        const currentLine = getCurrentLine(textarea.value, caretPos);
        const lineLength = countFullWidth(currentLine);
        const remaining = maxLength - lineLength;

        // メッセージ構築
        let message = `この行: ${lineLength.toFixed(1)}文字(全角換算)\n`;
        if (remaining < 0) {
            message += `⚠ ${(-remaining).toFixed(1)}文字オーバー`;
            tooltip.style.backgroundColor = '#ffe6e6';
            tooltip.style.color = '#c00';
        } else {
            message += `あと${remaining.toFixed(1)}文字入力可能`;
            tooltip.style.backgroundColor = '#f8f8f8';
            tooltip.style.color = '#000';
        }

        tooltip.textContent = message;
        tooltip.style.left = e.clientX + 10 + 'px';
        tooltip.style.top = e.clientY + 10 + 'px';
        tooltip.style.display = 'block';
    }

    textarea.addEventListener('input', updateTooltip);
    textarea.addEventListener('mousemove', updateTooltip);
    textarea.addEventListener('blur', () => {
        tooltip.style.display = 'none';
    });
});

フィールド要素を取得するAPIが追加画面と編集画面に非対応だから
querySelectorAll() で内容フィールドを指定するしかないと思われます。

kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function (event) {
    const maxLength = 25;
    const fieldLabel = '内容';

    let textarea = null;
    const labels = document.querySelectorAll('.control-label-text-gaia');
    labels.forEach(label => {
        if (label.textContent.trim() === fieldLabel) {
            const controlElement = label.closest('.control-gaia');
            if (controlElement) {
                textarea = controlElement.querySelector('textarea');
            }
        }
    });

    if (!textarea) {
        console.error('フィールド名が「内容」の文字列(複数行)フィールドが存在しません。');
        return event;
    }

    return event;
});
1 Like

ご回答いただき有難うございます!
参考にさせていただきます:woman_bowing:

1 Like

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