HTML & CSS

最終更新日:
公開日:

レシピ

フォーム

フォームに入力できない入力欄を設定する

input要素readonly属性を使った、値の編集ができない入力項目の設定方法を解説します。

この記事のポイント

  • あえて編集できない項目を設定する
  • フォームの値として送信したいときはreadonly属性を使う
  • フォームの送信に含めないときはdisabled属性を使う
  • HTML、JavaScriptだけで完全に入力編集できないようにすることは不可能

目次

フォームの値を編集できないようにする

フォームでは値があらかじめ入力された状態で、閲覧者からの編集をできないようにしたいことがあります。
その場合は、input要素readonly属性、またはdisabled属性を指定します。

以下のフォームは通常の入力できるフォームのHTMLとブラウザでの表示例になります。
なお、今回は主にHTMLの解説になるためCSSのソースコードと解説は省略します。

HTMLの赤字のコードは入力欄になっているinput要素select要素textarea要素です。
フォームの各入力欄はすでに入力されていることを想定してvalue属性checked属性selected属性を設定しています。

HTMLコード例

<body>
	<section>
		<h2>お問い合わせフォーム</h2>
		<form action="" method="post">
			<div>
				<label for="name">お名前</label>
				<input id="name" type="text" name="name" value="山田 由紀">
			</div>

			<div>
				<label for="furigana">フリガナ</label>
				<input id="furigana" type="text" name="furigana" value="ヤマダ ユキ">
			</div>

			<div>
				<label>性別</label>
				<label><input type="radio" name="gender" value="男性">男性</label>
				<label><input type="radio" name="gender" value="女性" checked>女性</label>
			</div>

			<div>
				<label>どこで知りましたか?</label>
				<label><input type="checkbox" name="question" value="広告をみた">広告をみた</label>
				<label><input type="checkbox" name="question" value="インターネット検索" checked>インターネット検索</label>
				<label><input type="checkbox" name="question" value="知人からの紹介">知人からの紹介</label>
				<label><input type="checkbox" name="question" value="その他">その他</label>
			</div>

			<div>
				<label>年齢</label>
				<select name="age">
					<option value="10代">10代</option>
					<option value="20代">20代</option>
					<option value="30代" selected>30代</option>
					<option value="40代">40代</option>
					<option value="50代">50代</option>
					<option value="60代">60代</option>
					<option value="70代">70代</option>
					<option value="80代">80代</option>
					<option value="90代以上">90代以上</option>
				</select>
			</div>

			<div>
				<label for="t_message">お問い合わせ内容</label>
				<textarea id="t_message" name="message">お問い合わせのテスト</textarea>
			</div>

			<div class="btn_area">
				<input type="submit" name="btn_submit" value="送信">
			</div>
		</form>
	</section>
</body>
通常の入力できるフォームの表示例

続いて、上記のHTMLにある入力欄にreadonly属性を追加したコードと表示例です。
今回は表示や機能の違いを確認するために送信ボタンのinput要素にもreadonly属性を指定しています。

HTMLコード例

<body>
	<section>
		<h2>お問い合わせフォーム</h2>
		<form action="" method="post">
			<div>
				<label for="name">お名前</label>
				<input id="name" type="text" name="name" value="山田 由紀" readonly>
			</div>

			<div>
				<label for="furigana">フリガナ</label>
				<input id="furigana" type="text" name="furigana" value="ヤマダ ユキ" readonly>
			</div>

			<div>
				<label>性別</label>
				<label><input type="radio" name="gender" value="男性" readonly>男性</label>
				<label><input type="radio" name="gender" value="女性" checked readonly>女性</label>
			</div>

			<div>
				<label>どこで知りましたか?</label>
				<label><input type="checkbox" name="question" value="広告をみた" readonly>広告をみた</label>
				<label><input type="checkbox" name="question" value="インターネット検索" checked readonly>インターネット検索</label>
				<label><input type="checkbox" name="question" value="知人からの紹介" readonly>知人からの紹介</label>
				<label><input type="checkbox" name="question" value="その他" readonly>その他</label>
			</div>

			<div>
				<label>年齢</label>
				<select name="age" readonly>
					<option value="10代">10代</option>
					<option value="20代">20代</option>
					<option value="30代" selected>30代</option>
					<option value="40代">40代</option>
					<option value="50代">50代</option>
					<option value="60代">60代</option>
					<option value="70代">70代</option>
					<option value="80代">80代</option>
					<option value="90代以上">90代以上</option>
				</select>
			</div>

			<div>
				<label for="t_message">お問い合わせ内容</label>
				<textarea id="t_message" name="message" readonly>お問い合わせのテスト</textarea>
			</div>

			<div class="btn_area">
				<input type="submit" name="btn_submit" value="送信" readonly>
			</div>
		</form>
	</section>
</body>
readonly属性を設定したフォームの表示例

ブラウザの表示ではreadonly属性の有無による影響はありません。
しかし、「お名前」と「フリガナ」を入力するinput要素textarea要素は値の表示のみで入力できない状態になります。

しかし、ラジオボタンやチェックボックス、プルダウンメニューや送信ボタンはreadonly属性があっても選択変更したり押すことができてしまいます。
そのため、テキスト入力以外の入力欄を編集できないようにしたいときはreadonly属性を使うことができません。

最後に、disabled属性を設定したコードと表示例です。

HTMLコード例

<body>
	<section>
		<h2>お問い合わせフォーム</h2>
		<form action="" method="post">
			<div>
				<label for="name">お名前</label>
				<input id="name" type="text" name="name" value="山田 由紀" disabled>
			</div>

			<div>
				<label for="furigana">フリガナ</label>
				<input id="furigana" type="text" name="furigana" value="ヤマダ ユキ" disabled>
			</div>

			<div>
				<label>性別</label>
				<label><input type="radio" name="gender" value="男性" disabled>男性</label>
				<label><input type="radio" name="gender" value="女性" checked disabled>女性</label>
			</div>

			<div>
				<label>どこで知りましたか?</label>
				<label><input type="checkbox" name="question" value="広告をみた" disabled>広告をみた</label>
				<label><input type="checkbox" name="question" value="インターネット検索" checked disabled>インターネット検索</label>
				<label><input type="checkbox" name="question" value="知人からの紹介" disabled>知人からの紹介</label>
				<label><input type="checkbox" name="question" value="その他" disabled>その他</label>
			</div>

			<div>
				<label>年齢</label>
				<select name="age" disabled>
					<option value="10代">10代</option>
					<option value="20代">20代</option>
					<option value="30代" selected>30代</option>
					<option value="40代">40代</option>
					<option value="50代">50代</option>
					<option value="60代">60代</option>
					<option value="70代">70代</option>
					<option value="80代">80代</option>
					<option value="90代以上">90代以上</option>
				</select>
			</div>

			<div>
				<label for="t_message">お問い合わせ内容</label>
				<textarea id="t_message" name="message" disabled>お問い合わせのテスト</textarea>
			</div>

			<div class="btn_area">
				<input type="submit" name="btn_submit" value="送信" disabled>
			</div>
		</form>
	</section>
</body>
disabled属性を設定したフォームの表示例

全ての入力欄が入力できない状態になりました。
以上のことから、全ての入力欄を閲覧者から編集できないようにしたいときはdisabled属性が有効です。
ただし、disabled属性を指定した入力欄はフォームを送信するときに送信されません。

一方でreadonly属性はフォームを送信するときにも値が送信されます。
2つの属性の大きな違いは値を送信するか、送信しないかです。
readonly属性は値を送信しますが、disabled属性は送信しません。

フォームを編集できないようにしながら値を送信するようにする

disabled属性のようにチェックボックスなども選択・編集できないようにしながら、値を送信したいことがあります。
そのような設定をするためには主に2つの方法があります。

  • 値の表示と送信する値を別要素にして分ける
  • JavaScriptを使って入力を制限する

手軽な方法は1つ目の「値の表示と送信する値を別要素にして分ける」という方法です。
1つずつ解説していきます。

値の表示と送信する値を別要素にして分ける

入力値を表示するためのHTML要素と、値を送信するためのHTML要素を物理的に分ける方法です。
以下の例では入力値の表示はp要素、送信する値はtype属性に「hidden」を設定したinput要素を配置してます。

以下のコード例では表示用のp要素と非表示にしている送信用のinput要素をそれぞれ赤字にしています。

HTMLコード例

<body>
	<section>
		<h2>お問い合わせフォーム</h2>
		<form action="" method="post">
			<div>
				<label for="name">お名前</label>
				<p>山田 由紀</p>
			</div>
			<div>
				<label for="furigana">フリガナ</label>
				<p>ヤマダ ユキ</p>
			</div>
			<div>
				<label>性別</label>
				<p>女性</p>
			</div>
			<div>
				<label>どこで知りましたか?</label>
				<p>インターネット検索</p>
			</div>
			<div>
				<label>年齢</label>
				<p>30代</p>
			</div>
			<div>
				<label for="t_message">お問い合わせ内容</label>
				<p>お問い合わせのテスト</p>
			</div>
			<div class="btn_area">
				<input type="submit" name="btn_submit" value="送信" disabled>
			</div>
			<input type="hidden" name="name" value="山田 由紀">
			<input type="hidden" name="furigana" value="ヤマダ ユキ">
			<input type="hidden" name="gender" value="女性">
			<input type="hidden" name="question" value="インターネット検索">
			<input type="hidden" name="age" value="30代">
			<input type="hidden" name="message" value="お問い合わせのテスト">
		</form>
	</section>
</body>

以下のような表示になります。

表示例

JavaScriptを使って入力を制限する

2つ目はJavaScriptによってフォームの入力を制限する方法です。

input要素、select要素、textarea要素に対してそれぞれフォーカスやクリックなどのイベントが発生したタイミングで入力状態を解除するように設定します。

以下のコード例ではフォームのHTMLはこれまでと同じものを使いながら、その後ろにscript要素を追加してJavaScriptによる入力制限を実装しています。
フォームの入力に使うHTML要素は先述の3種類に分かれているため、それぞれ分けてイベントが発生したタイミングの処理を記述していきます。

disabled属性のコード例

<body>
	<section>
		<h2>お問い合わせフォーム</h2>
		<form action="" method="post">
			<div>
				<label for="name">お名前</label>
				<input id="name" type="text" name="name" value="山田 由紀">
			</div>
			<div>
				<label for="furigana">フリガナ</label>
				<input id="furigana" type="text" name="furigana" value="ヤマダ ユキ">
			</div>
			<div>
				<label>性別</label>
				<label class="label_gender"><input type="radio" name="gender" value="男性">男性</label>
				<label class="label_gender"><input type="radio" name="gender" value="女性" checked>女性</label>
			</div>
			<div>
				<label>どこで知りましたか?</label>
				<label class="label_q"><input type="checkbox" name="question" value="広告をみた">広告をみた</label>
				<label class="label_q"><input type="checkbox" name="question" value="インターネット検索" checked>インターネット検索</label>
				<label class="label_q"><input type="checkbox" name="question" value="知人からの紹介">知人からの紹介</label>
				<label class="label_q"><input type="checkbox" name="question" value="その他">その他</label>
			</div>
			<div>
				<label>年齢</label>
				<select name="age">
					<option value="10代">10代</option>
					<option value="20代">20代</option>
					<option value="30代" selected>30代</option>
					<option value="40代">40代</option>
					<option value="50代">50代</option>
					<option value="60代">60代</option>
					<option value="70代">70代</option>
					<option value="80代">80代</option>
					<option value="90代以上">90代以上</option>
				</select>
			</div>
			<div>
				<label for="t_message">お問い合わせ内容</label>
				<textarea id="t_message" name="message">お問い合わせのテスト</textarea>
			</div>
			<div class="btn_area">
				<input type="submit" name="btn_submit" value="送信">
			</div>
		</form>
	</section>
	<script>

  // コンテンツ読み込み完了したら実行
	window.addEventListener('DOMContentLoaded', ()=>{


		//------------------------------
		// input要素
		//------------------------------

		// input要素を取得
		let input_elements = document.querySelectorAll('input');

		// 送信ボタン以外のinput要素に入力無効を設定
		for(let i of input_elements) {

			if( i.type !== 'submit' ) {

				// テキスト入力系の動作をキャンセル
				i.addEventListener('focusin', (e)=>{
					i.blur();
					return false;
				});

				// ラジオボタン、チェックボックスの選択をキャンセル
				i.addEventListener('click', (e)=>{
					e.preventDefault();
				});
			}
		}


		//------------------------------
		// select要素
		//------------------------------

		// select要素を取得
		let select_elements = document.querySelectorAll('select');

		// select要素に入力無効を設定
		for(let s of select_elements) {
	
			// クリック開始、タッチ開始のタイミングで選択をキャンセル
			s.addEventListener('mousedown', (e)=>{
				s.blur();
				e.preventDefault();
				window.focus();
				return false;
			});

			// タブキーなどでselect要素が選択されたときに選択をキャンセル
			s.addEventListener('keydown', (e)=>{
				s.blur();
				e.preventDefault();
				window.focus();
				return false;
			});
		}


		//------------------------------
		// textarea要素
		//------------------------------

		// textarea要素を取得
		let textarea_elements = document.querySelectorAll('textarea');

		// textarea要素に入力無効を設定
		for(let t of textarea_elements) {
			t.addEventListener('focusin', (e)=>{
				t.blur();
				return false;
			});
		}

	});
	</script>
</body>

JavaScriptによる入力制限についてポイントは2つあります。

  • 各要素で発生するイベントが異なる
  • input要素の送信ボタン(type=”submit”)のみ制限をつけないようにしている

特にinput要素はテキスト入力の他にラジオボタンやチェックボックス、送信ボタンなど様々な形式の入力要素が混在するためやや複雑になってしまいます。

完全に入力編集できないようにすることは不可能

ここまでフォームの値を編集できないようにする方法について解説してきましたが、フロントエンド側のみで入力値の編集を完全に防ぐ方法は残念ながらありません

ブラウザは機能としてJavaScriptを無効にしたり、「開発者ツール(デベロッパーツールなどブラウザによって呼び方が異なります)」でHTML自体を編集することができます。
これらの方法はHTMLやJavaScriptで制限することは不可能なため、フォームの値を完全に編集できないようにすることはできないとある程度割り切るか、もしくはどうしても編集を許可したくない場合はサーバーサイドと連携する方法を検討する必要があります。