0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TextInputGuardでWeb入力の全角半角・IME・桁数を制御する

0
Last updated at Posted at 2026-04-26

はじめに

Web サイトの入力フォームとして inputtextarea タグで文字列を受け付けることは多いと思います。

サーバー側でのバリデーションは当然として、クライアント側でも UX 向上のために入力制御を行いたい場面はよくあります。

ただ、標準の入力要素だけでは思い通りに制御できないことも多いです。

例えば、以下のようなケースで困ったことはないでしょうか

  • maxlength を指定しているのに、type="number" だと効かない
  • 全角数字が入力されてしまい、サーバーでエラーになる
  • IME入力中に制御しようとして挙動が壊れる
  • カンマ区切りや通貨表示をしたいが、入力中の制御が難しい

このように「やりたいことは単純なのに実装が面倒」というのが、入力制御の厄介なポイントです。

今回は、これらの問題をシンプルに解決できる TextInputGuard ライブラリ を紹介します。

TextInputGuard とは

TextInputGuard は、入力欄の入力制御に特化した MIT ライセンスのライブラリです。

自作で入力制御を実装しようとすると、以下のような問題に直面します。

  • IME変換の扱いが難しい
  • Undo / Redo の挙動
  • オートコンプリートやペースト時の挙動

これらをすべて正しく扱うのは意外と大変です。

TextInputGuard を使うことで、これらを意識せずに ルールを組み合わせるだけで入力制御を実現 できます。

使用例

数値入力

ESモジュールとして数値入力の制限をかけた例です。

See the Pen TextInputGuard - price by natade (@natade-jp) on CodePen.

HTML

<input id="price" type="text" inputmode="decimal" style="text-align: right" value="123.45" />

JavaScript

import { attach, rules } from "https://esm.sh/text-input-guard";
const input = document.querySelector("#price");
const guard = attach(input, {
  rules: [
    rules.numeric({
      allowFullWidth: true,
      allowMinus: true,
      allowDecimal: true,
      allowEmpty: false
    }),
    rules.digits({
      int: 8,
      frac: 2,
      modeInt: "block",
      modeFrac: "block",
      fixFracOnBlur: "round",
      forceFracOnBlur: true
    }),
    rules.prefix({
      text: "¥",
      showWhenEmpty: true
    }),
    rules.suffix({
      text: " JPY"
    }),
    rules.comma()
  ],
  onChange: () => {
    render();
    return;
  }
});

解説

attach に対して rules を配列で渡すだけで入力制御を構築できます。

例では役割ごとにルールを分けています。

  • rules.numeric() → 数値として入力できるようにする
  • rules.digits() → 整数部・小数部の桁数を制御する
  • prefix() / suffix() / comma() → 表示用の整形

また onChange のコールバックの設定で次の結果を出力するように作っています。

guard.getDisplayValue(): ¥123.45 JPY
guard.getRawValue()    : 123.45

見た目(getDisplayValue)と実データ(getRawValue)は別管理になっており prefix() / suffix() / comma() は見た目に関するルールで、フォーカスを外したタイミングで自動的に付与されます。

一方で、フォーム送信時には getRawValue() の値が使われるため、サーバー側では純粋な数値として扱えます。

※ 投稿時点は見た目と実データが別管理になるようなルールは textarea に対応していないので注意

文字入力

ライブラリを UMD 形式で利用し、英数字入力を制限する例です。

See the Pen TextInputGuard - price sample umd by natade (@natade-jp) on CodePen.

HTML

<script src="
https://cdn.jsdelivr.net/npm/text-input-guard@1.2.1/dist/umd/text-input-guard.min.js
"></script>
<input id="code" type="text" inputmode="url" value="123abc" />

JavaScript

const input = document.getElementById("code");
const guard = TextInputGuard.attach(input, {
	rules: [
		TextInputGuard.rules.imeOff(),
		TextInputGuard.rules.ascii({
			case: "upper"
		}),
		TextInputGuard.rules.filter({
			category: ["alpha-upper", "digits"],
			allow: /[-_@]/
		}),
		TextInputGuard.rules.bytes({
			max: 10,
			mode: "block",
			unit: "cp932"
		})
	]
});

解説

英数字コード入力を想定して制限を行っています。

それぞれのルールの役割は以下の通りです。

  • imeOff() → 全角入力されても半角相当に補正
  • ascii() → 英数字を半角に統一し、大文字へ変換
  • filter() → 許可した文字(英大文字・数字・一部記号)のみ通す
  • bytes() → バイト数(ここでは CP932)で最大長を制限

また、inputmode="url" を指定することで、モバイル環境では英数字入力しやすいキーボードが表示されます。ただし、これだけでは完全には制御できないため imeOff() と組み合わせて補正しています。

このように、rules を組み合わせることで「入力補正」「入力制限」「長さ制御」を段階的に適用できるのが特徴です。

利用できるルールについて

説明してきたようにルールを組み合わせることで入力制御を構築します。
ルールは自作することも可能ですが、標準で多くの実用的なルールが用意されています。

特に、文字数制限に関しては以下のように用途に応じた制御が可能です。

  • 文字数単位(グラフェム)
  • バイト数単位(UTF / SJIS / CP932)
  • 表示幅単位(半角=1 / 全角=2)

日本語環境特有の要件にも対応しやすいのが特徴です。

また、filter() を利用することで、

  • 許可した文字種のみ通す
  • サロゲートペア(絵文字など)を除外する
  • 特定の記号のみ許可する

といった細かい入力制御も行えます。

文字列系

ルール 主な用途 主な機能 よく使う組み合わせ
kana() かな入力 ひらがな・全角カタカナ・半角カタカナへ正規化 trim() / filter()
imeOff() ASCII入力欄 日本語IMEで入りやすい記号や全角ASCIIをASCII入力相当に補正 ascii()
ascii() 英数字・コード入力 全角英数字・記号・スペースを半角ASCIIへ正規化し、英字の大小文字も統一可能 imeOff() / filter()
filter() 入力可能文字の制限 許可カテゴリ・追加許可・禁止文字を指定し、不許可文字を削除またはエラー化 ascii() / kana()
trim() 前後空白の除去 入力値の先頭・末尾の空白を削除 文字列系全般
length() 文字数制限 グラフェム・UTF-16・UTF-32単位で最大長を制御 filter()
width() 半角全角の幅制限 半角を1、全角を2として最大幅を制御 氏名・住所・品名など
bytes() バイト数制限 UTF-8 / UTF-16 / UTF-32 / SJIS / CP932 のバイト数で最大サイズを制御 filter("sjis-only") / filter("cp932-only")

数値系

ルール 主な用途 主な機能 よく使う組み合わせ
numeric() 数値入力の基本処理 全角数字の半角化、マイナス、小数点、空文字の扱いを制御 digits()
digits() 数値の桁数制限 整数部・小数部の桁数、超過時の挙動、blur時の丸めや0埋めを制御 numeric()

表示整形系

ルール 主な用途 主な機能 よく使う組み合わせ
comma() 金額・数量の表示整形 整数部に3桁区切りカンマを付与 numeric() / digits()
prefix() 表示用の接頭辞 先頭に ¥ などの文字列を付与 comma()
suffix() 表示用の接尾辞 末尾に などの文字列を付与 comma()

より詳細なオプションや挙動については、以下の API ドキュメントを参照してください。

さいごに

入力制御は一見シンプルですが、実際にやるとブラウザ差異やIMEの影響でかなり厄介な分野です。

TextInputGuard を使うことで、その複雑さを意識せずに実用的な入力制御を実現できます。

同じように悩んでいる方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?