もくじ
数値入力フォームで「3桁ごとにカンマ表示」をしたい場面は多いですが、入力中のカーソル位置や小数・負数対応、複数入力欄の対応などを考えると意外と難しいです。
この記事では、以下の要望をすべて満たす汎用JavaScriptサンプルを紹介します。
- 入力中は通常の input 表示
- Enterキーやフォーカスアウトでカンマ付き表示に切り替え
- 小数・負数対応
- 文字列入力も対応
- 複数入力欄対応
- 桁数が多い場合は横スクロール対応
- 入力値は常にカンマなしでサーバー送信可能
リンク
リンク
【サンプル】inputの数値を3桁ごとにカンマ区切り
【実装コード】inputの数値を3桁ごとにカンマ区切り
HTMLの基本構造
Copyをクリックするとコピーできます。
HTML
Copy
<div class="input-wrapper">
<input type="text" class="number-input" placeholder="数値を入力">
<span class="formatted"></span>
</div>
<div class="input-wrapper">
<input type="text" class="number-input" placeholder="数値を入力">
<span class="formatted"></span>
</div>
.input-wrapper | inputとspanを重ねる親要素 |
---|---|
.number-input | ユーザーが入力するテキストボックス |
.formatted | 確定後にカンマ付きの数値を表示するための要素 |
CSSで見た目を整える
Copyをクリックするとコピーできます。
CSS
Copy
.input-wrapper {
position: relative;
width: 100%;
max-width: 250px;
margin-bottom: 1em;
overflow-x: auto;
border: 1px solid #ccc;
border-radius: 4px;
cursor: text;
}
.number-input,
.formatted {
width: 100%;
box-sizing: border-box;
padding: 4px 6px;
font-family: inherit;
font-size: 1em;
font-weight: normal;
border: none;
border-radius: 4px;
}
.number-input {
color: transparent;
background: transparent;
user-select: none;
}
.number-input:focus {
color: inherit;
background: #fff;
user-select: auto;
}
.number-input:focus + .formatted {
display: none;
}
.formatted {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
JavaScriptで機能を実装する
Copyをクリックするとコピーできます。
JavaScript
Copy
document.addEventListener('DOMContentLoaded', function() {
const wrappers = document.querySelectorAll('.input-wrapper');
function formatWithCommas(value) {
if (!value) return '';
const [intPart, decimalPart] = value.split('.');
const formattedInt = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return formattedInt + (decimalPart !== undefined ? '.' + decimalPart : '');
}
wrappers.forEach(wrapper => {
const inputEl = wrapper.querySelector('.number-input');
const spanEl = wrapper.querySelector('.formatted');
function updateDisplay() {
const raw = inputEl.value;
if (/^-?\d*\.?\d*$/.test(raw) && raw !== '-' && raw !== '.' && raw !== '-.') {
spanEl.textContent = formatWithCommas(raw);
} else {
spanEl.textContent = raw;
}
}
// 入力中
inputEl.addEventListener('input', updateDisplay);
// Enterで確定
inputEl.addEventListener('keydown', e => {
if (e.key === 'Enter') {
e.preventDefault();
updateDisplay();
inputEl.blur();
}
});
// フォーカスアウトで確定
inputEl.addEventListener('blur', updateDisplay);
inputEl.addEventListener('focusout', updateDisplay);
inputEl.addEventListener('change', updateDisplay);
// 横スクロール同期
inputEl.addEventListener('scroll', () => {
spanEl.scrollLeft = inputEl.scrollLeft;
});
// wrapperクリックで必ずinputにフォーカス
wrapper.addEventListener('click', () => {
inputEl.focus();
});
// 初期表示
updateDisplay();
});
});
使用感・メリット
- 入力中は数字や文字を入力可能
- Enterキーやフォーカスアウトで数値が入力されている場合、カンマ付き表示に切り替え
- 小数・負の数に対応
- 文字列もそのまま表示可能
- 横に長い数字もスクロールで確認できる
- 複数入力欄でも同じ挙動を適用可能
- 入力値は常にカンマなしで保持 → サーバー送信可能
リンク
リンク