🍣

文字数じゃなくてバイト数で入力を制限する

2024/07/02に公開

入力フォームの文字数=バイト数としたいときって
たぶんない気がするが、
経験したので
記録に残しておこうと思います。

注釈

Node環境下で実装可能です。

環境

stackblitzのスターターキット
https://stackblitz.com/
ちょっとしたデモを作るのに便利です。
今回はNext.jsスターターを利用しました。

コード

page.tsx
'use client';
import { useState } from 'react';
const MAX= 12;

export default function Home() {
  const [name, setName] = useState<string>('');

  const trim = (value: string) => {
    const trimed = Uint8Array.prototype.slice
      .call(Buffer.from(value))
      .slice(0, MAX)
      .toString()
      .replace('�', '');
    setName(trimed);
  };
  return (
    <main>
      <div>
        <input
          type="text"
          className="p-4 rounded-md"
          value={name}
          onChange={(e) => trim(e.target.value)}
        />
      </div>
    </main>
  );
}

バイト数で判定する関数

Uint8Array.prototype.slice
      .call(Buffer.from(value))
      .slice(0, MAX)
      .toString()
      .replace('�', '');

細かくしてコメント

// 入力した文字列をバイト文字列に変換
const byte = Uint8Array.prototype.slice.call(Buffer.from(value));
// 指定バイト数で切り出し
const slice = byte.slice(0, MAX);
// 文字列に変換
const slicedString = slice.toString();
// 文字化けを削除
const trim = slicedString.replace('�', '');

日本語を含む文字列をバイト文字列に変換するとき変換できない文字化けができるので削除します。

まとめ

サーバーサイドで実行されるNext.jsだとユーザー入力を検出してバイト数判定できます。
本当はこんな感じ

<input type="text" maxLength={12} />

でmaxlength属性を使えば文字数制限は簡単にできるので、
やっぱり文字数で判定するようにしたほうが分かりやすいコードになるとおもいました。(元も子もないww...)

Discussion