本文へスキップ
  1. Web BENTO JS
  2. カテゴリ一覧
  3. フォーム補助
09 / FORM 12 パーツ

フォーム改善のJSスニペット 12選

コピペで動くフォーム補助のJSスニペット集です。文字数カウンター・パスワード表示切替・二重送信防止など、プレビューは実際に入力して試せますHTML / CSS / JS タブでコードを確認し、全部コピーを押せば1回の貼り付けで完成します。すべて依存ライブラリなしのバニラJSで、data-bnto-* 属性による自動初期化式です。

該当するパーツが見つかりませんでした。

あと30文字

文字数カウンター

<!-- data-max が上限文字数 -->
<div class="bnto-count" data-bnto-count data-max="30">
  <textarea rows="3" placeholder="30文字まで入力できます" aria-label="コメント"></textarea>
  <span class="num" aria-live="polite">あと30文字</span>
</div>
使い方のコツ

上限は data-max 属性を変えるだけです。「超過しても入力はできるが赤く警告」というSNS風の挙動です。そもそも超過入力を禁止したい場合は textarea に maxlength を併用してください。

パスワード表示切替

<div class="bnto-pw" data-bnto-pw>
  <input type="password" aria-label="パスワード">
  <button type="button" class="eye" aria-label="パスワードを表示" aria-pressed="false">
    <!-- 目アイコン(表示用) -->
    <svg class="i-on" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>
    <!-- 斜線付きの目アイコン(非表示用) -->
    <svg class="i-off" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.88 9.88a3 3 0 1 0 4.24 4.24"/><path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68"/><path d="M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61"/><line x1="2" x2="22" y1="2" y2="22"/></svg>
  </button>
</div>
使い方のコツ

入力ミスが命取りになる新規登録・パスワード変更画面で特に効果的です。状態は aria-pressed で支援技術にも伝わります。type の切替はCSSだけではできないため、JSが必須の代表例です。

必須チェック簡易バリデーション

<!-- 必須にしたい項目に data-req を付ける -->
<form class="bnto-req" data-bnto-req novalidate>
  <input type="text" data-req placeholder="お名前(必須)" aria-label="お名前">
  <input type="email" data-req placeholder="メールアドレス(必須)" aria-label="メールアドレス">
  <p class="err" aria-live="polite"></p>
  <button type="submit" class="bt">送信する</button>
</form>
使い方のコツ

エラー文言は aria-live 領域に出すので、スクリーンリーダーにも読み上げられます。まずHTML標準の required を活用し、文言やデザインを自由にしたい場合にこのJS方式(novalidate + 自前チェック)へ切り替えるのがおすすめです。

全選択チェックボックス

<div class="bnto-checkall" data-bnto-checkall>
  <label class="all"><input type="checkbox" class="parent">すべて選択</label>
  <label><input type="checkbox" class="child">りんご</label>
  <label><input type="checkbox" class="child">みかん</label>
  <label><input type="checkbox" class="child">バナナ</label>
  <!-- .child を必要な数だけ -->
</div>
使い方のコツ

「一部だけ選択中」を示す indeterminate(横棒表示)はHTML属性では書けず、JSからしか設定できないプロパティです。メール一覧や管理画面テーブルの一括操作UIの定番です。

送信二重防止

<form class="bnto-once" data-bnto-once>
  <input type="text" placeholder="お問い合わせ内容" aria-label="お問い合わせ内容">
  <button type="submit" class="bt">送信する</button>
  <p class="st" aria-live="polite"></p>
</form>
使い方のコツ

デモでは2秒後に自動復帰しますが、実運用では setTimeout を削除し、fetch完了時やページ遷移で復帰させます。連打による二重注文・二重投稿を最小のコードで防げる、費用対効果の高い改善です。

入力内容確認

<!-- data-key がそのまま確認欄の項目名になる -->
<div class="bnto-confirm" data-bnto-confirm>
  <input type="text" data-key="お名前" placeholder="お名前" aria-label="お名前">
  <input type="email" data-key="メールアドレス" placeholder="メールアドレス" aria-label="メールアドレス">
  <button type="button" class="go">確認する</button>
  <dl class="view" aria-live="polite"></dl>
</div>
使い方のコツ

確認ページを別に用意しなくても1ページで「入力→確認」が完結します。値の反映は textContent を使っているため、入力にHTMLタグが含まれてもそのまま文字として表示され安全です。

郵便番号ハイフン自動挿入

<!-- inputmode="numeric" でスマホは数字キーボードに -->
<input class="bnto-zip" data-bnto-zip type="text" inputmode="numeric" maxlength="8" placeholder="1234567" aria-label="郵便番号">
使い方のコツ

input イベントで整形しているので、キー入力だけでなくコピペにも対応します。全角数字は半角に自動変換します。電話番号など他の桁区切りにも、スライス位置を変えるだけで応用できます。

● 未保存の変更あり 別のページへ移動 →

変更未保存アラート

<div class="bnto-unsaved" data-bnto-unsaved>
  <input type="text" placeholder="ここに何か入力してみてください" aria-label="メモ">
  <div class="row">
    <span class="badge">● 未保存の変更あり</span>
    <a href="#" class="leave">別のページへ移動 →</a>
  </div>
  <p class="st" aria-live="polite"></p>
</div>
使い方のコツ

デモはページ内 confirm() で完結していますが、実運用でタブを閉じる・リロードも含めて守るなら、コード内にコメントで記載した beforeunload を有効にしてください(ダイアログの文言はブラウザ標準で固定です)。

パスワード強度メーター

<!-- ゲージは i を4つ(4段階) -->
<div class="bnto-pwmeter" data-bnto-pwmeter>
  <input type="password" placeholder="パスワードを入力" aria-label="パスワード" autocomplete="new-password">
  <div class="gauge" aria-hidden="true"><i></i><i></i><i></i><i></i></div>
  <p class="lv" aria-live="polite"></p>
</div>
使い方のコツ

ラベルは aria-live="polite" 領域なので、強度の変化がスクリーンリーダーにも伝わります。判定は「長さ8文字以上・大小英字・数字・記号」の充足数を数えるデモ用の簡易ロジックです。実運用では辞書ベースの判定ライブラリの利用や、サーバー側での検証も必ず併用してください。

全角のまま入力してみてください(欄を出ると半角に)

全角→半角自動変換

<!-- 欄を離れた瞬間(blur)に全角数字・ハイフンを半角へ正規化 -->
<div class="bnto-zenhan" data-bnto-zenhan>
  <input type="tel" inputmode="tel" placeholder="090-1234-5678" aria-label="電話番号">
  <p class="st" aria-live="polite"></p>
</div>
使い方のコツ

「半角で入力してください」とエラーで怒る代わりに、こちらで直してあげるパーツです。input イベントではなく blur(欄を離れた時)で変換しているのは、日本語IMEの変換中に値をいじるとカーソル位置が乱れるためです。長音「ー」やダッシュ「―」もハイフンに寄せています。英字も対象にしたいときは、正規表現に A-Za-z を足すだけです。

条件分岐フォーム

<!-- data-show-on の値と .src の選択値が一致した .extra だけ表示される -->
<div class="bnto-condform" data-bnto-condform>
  <select class="src" aria-label="お問い合わせ種別">
    <option value="資料請求">資料請求</option>
    <option value="お見積もり">お見積もり</option>
    <option value="その他">その他</option>
  </select>
  <div class="extra" data-show-on="お見積もり" hidden>
    <input type="text" placeholder="ご予算" aria-label="ご予算">
  </div>
  <div class="extra" data-show-on="その他" hidden>
    <input type="text" placeholder="お問い合わせ内容" aria-label="お問い合わせ内容">
  </div>
</div>
使い方のコツ

ポイントは表示の切替と同時に required を付け外ししていることです。隠れた項目に required が残っていると、フォームが送信できなくなります。隠すとき入力値もクリアしているので、非表示項目の値がうっかり送信される事故も防げます。ラジオボタンで使う場合は、.src の代わりにラジオ全体の change を拾い、チェック中の値と比較するように書き換えてください。

下書き自動保存

<!-- data-key が localStorage の保存キー(フォームごとに変える) -->
<div class="bnto-draft" data-bnto-draftsave data-key="contact-draft">
  <div class="bar" hidden>
    <span>下書きを復元しますか?</span>
    <span class="bts"><button type="button" class="yes">復元</button><button type="button" class="no">破棄</button></span>
  </div>
  <textarea rows="3" placeholder="お問い合わせ内容" aria-label="お問い合わせ内容"></textarea>
  <p class="st" aria-live="polite"></p>
</div>
使い方のコツ

「うっかりタブを閉じて長文が消えた」を防ぐ、離脱対策の定番です。保存先の localStorage はそのブラウザ内にだけ残るため、個人情報を扱う欄では保存対象にしないか、送信完了時に localStorage.removeItem() で確実に消してください。複数のフォームで使うときは data-key をフォームごとに変えるだけです。シークレットモードなど保存できない環境でも、try/catch で囲んであるので通常入力はそのまま使えます。

フォーム改善JSの基礎知識

フォームはサイトの成果(問い合わせ・購入・登録)に直結する場所でありながら、入力の手間やわかりにくいエラーで離脱がもっとも起きやすいポイントです。このページのスニペットは、文字数カウンター・二重送信防止・郵便番号の自動整形など「小さいけれど効く」改善を集めたものです。すべて依存ライブラリなしのバニラJavaScriptで、jQueryもフレームワークも不要です。

使い方は、HTML / CSS / JSの3タブをそれぞれ貼り付けるか、「全部コピー」ボタンでひとまとめになったコードを1回貼り付けるだけです。初期化は data-bnto-* 属性の自動検出式なので、同じページに何個置いても、うっかりコードを2回貼っても壊れません。

エラーは「早く・優しく」伝える

送信ボタンを押した後にまとめて怒られるより、入力の直後にその場で知らせるほうがずっと親切です。文言も「入力が不正です」ではなく「メールアドレスの形式で入力してください」のように直し方が分かる表現にしましょう。エラーメッセージは aria-live 領域に出力すると、画面を見ていないスクリーンリーダー利用者にも変化が伝わります。

HTML標準バリデーション(required / pattern)との併用

まず活用すべきは requiredpatterntype="email" などのHTML標準バリデーションです。JSを1行も書かずにブラウザがチェックしてくれます。JSの出番は「エラーの見た目や文言を自由にデザインしたい」「リアルタイムに反応させたい」ときです。その場合は form に novalidate を付けて標準UIを止め、自前の表示に置き換えるのが定石です。

「うっかり」を防ぐ小さな仕掛けが離脱を防ぐ

二重送信防止・未保存アラート・ハイフンの自動挿入は、それぞれは数行の改善ですが、ユーザーの失敗体験を確実に減らします。特に「ハイフンあり?なし?」で迷わせる郵便番号・電話番号欄は、入力側に合わせてJSで整形してあげるのがモダンな作法です。積み重ねがフォーム完了率の差になります。

「全部コピー」と「分けて貼る」の使い分け

「全部コピー」を使うと、HTML・CSS・JavaScriptがひとつの自己完結ブロックとしてコピーされるので、1回の貼り付けだけですぐ動きを確認できます。動作のお試しや、1ページ完結のLPに組み込むときはこの方法が手軽です。

一方、本番サイトへ本格的に組み込む場合は、CSSはスタイルシート(.cssファイル)へ、JavaScriptは</body>直前や共通の.jsファイルへ、HTMLは使いたい場所へと分けて貼るのが一般的です。スタイルとスクリプトを1か所に集約できるため、複数ページ・複数パーツで使い回すときの管理がしやすく、ブラウザのキャッシュも効きやすくなります。なお、同じパーツをページ内で何度も使う場合でも、CSSとJSを貼るのは1回だけで大丈夫です(初期化スクリプトが該当要素すべてに自動で効きます)。

よくある質問

コピーしたフォーム改善コードはそのまま動きますか?
はい。「全部コピー」を押すとHTML・CSS・JSがひとつの自己完結ブロックになってコピーされ、ページに貼り付けるだけで動きます。ライブラリの読み込みは一切不要です。
同じページに複数設置しても大丈夫ですか?
大丈夫です。初期化スクリプトは data 属性で対象を自動検出し、初期化済みの要素はスキップするため、複数設置してもコードを2回貼っても壊れません。
HTML標準の required 属性があればJSのバリデーションは不要では?
まずは requiredpattern などHTML標準のバリデーションを使うのが基本です。JSは「エラー文言やデザインを自由にしたい」「入力中にリアルタイムで知らせたい」場合の上乗せとして使うと、両方の利点を活かせます。
送信ボタンの二重防止はなぜ必要ですか?
通信が遅いときにユーザーがボタンを連打すると、同じ内容が複数回送信されることがあります。送信中はボタンを無効化して「送信中…」と表示するだけで、二重注文や二重投稿を手軽に防げます。
このページのパーツはAIコーディングツールでも使えますか?
はい。Claude CodeやCursorのようにWebページを読めるAIには、このページのURLとパーツ名(例:「パスワード表示切替」)を伝えるだけで実装を指示できます。AIがWebを読めない場合は、「全部コピー」で取得した自己完結ブロックをチャットに貼り付けて調整を頼むのが確実です。改変後のコードは、公開前に動作確認することをおすすめします。

関連カテゴリ

フォームまわりと組み合わせて使いやすいパーツはこちらです。