魁小野の塾

魁!小野の塾 小さな管理機能を作ってみようの巻 第12話


小さな管理機能を作ってみよう 第12話

初心者向け、PHPプログラム構築講座です。
初心者といっても、PHPの勉強を少し行い、LAMP環境が自分で構築でき、少しアプリケーションを作成しているレベルを対象とします。
まったくの初心者の場合は、わからない部分が出てくると思います。
できるだけ細かく説明は入れていきますが、説明がわからない場合は、PHPやMySQLの初心者講座をご覧ください。

対象のスキルレベル

  • LAMP環境の構築
  • PHP言語が読める
  • HTML, CSS, Javascriptが少しわかる
  • Bootstrapのドキュメントをみて、HTMLが書ける
  • Ajax(非同期通信)を利用したことがある
  • SESSIONを利用したことがある

構築環境

  • Windows10
  • XAMPP(PHP7.3.2, MariaDB 10.1.38)

ユーザ管理 編集画面

今回は、前回作成した入力項目に、Validation を追加していきます。
必須入力、簡単なパターンチェックを入れていきます。

HTMLのValidation自体は、まだそれほど使えるレベルではないので、しっかり実装する場合は、Javascriptで実装する必要があるようです。
※参考 HTML5におけるinput要素のpattern、type属性のおさらい

仕様や実装状況は、その時に変わりますので、実装する前は一通り調べることをお勧めします。
ブラウザの実装が進むと、開発が楽にできることも多々あります。

必須チェックは、各項目に required 属性を入れていきます。
FORM要素に、.needs-validationnovalidate 属性を追加します。
novalidate 属性を追加しないと正しく挙動しないので、忘れないように。

パターンは正規表現 になるので、あとから実装していきたいと思います。

usersEdit.html(content部分抜粋)
<main class="contents">
	<section class="container-fluid">
		<header>
			<h1><i class="fas fa-id-card-alt"></i> ユーザ管理</h1>
		</header>

		<form class="needs-validation" novalidate>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="name" placeholder="名前を入力してください。" required>
						<label for="name">名前</label>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="email" class="form-control" id="mail" placeholder="メールアドレスを入力してください。" required>
						<label for="mail">メールアドレス</label>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="password" class="form-control" id="passwd" placeholder="パスワードを入力してください。" required>
						<label for="passwd">パスワード</label>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="tel" class="form-control" id="phone" placeholder="電話番号を入力してください。" required>
						<label for="phone">電話番号</label>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<select class="form-select" id="dept" required>
							<option value="">選択してください</option>
							<option value="1">経理</option>
							<option value="2">人事</option>
							<option value="3">総務</option>
							<option value="4">営業第1課</option>
							<option value="5">営業第2課</option>
							<option value="6">営業第3課</option>
						</select>
						<label for="dept">所属部署</label>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="address" placeholder="住所を入力してください。" required>
						<label for="address">住所</label>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<button class="btn btn-success"><i class="far fa-check-circle"></i> 登録</button>
				</div>
			</div>
		</form>

	</section>
</main>

この状態で、必須チェックは入るようになります。(HTMLの標準機能として)
まずは、Bootstrap側が提供しているValidation用Javascriptをコピーしてきます。

※参考 Validation (バリデーション)
※参考 Validation (バリデーション)#Custom styles

Bootstrap Validation Javascript
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
  'use strict'

  // Fetch all the forms we want to apply custom Bootstrap validation styles to
  var forms = document.querySelectorAll('.needs-validation')

  // Loop over them and prevent submission
  Array.prototype.slice.call(forms)
    .forEach(function (form) {
      form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
})()

Bootstrapが jQuery と決別した為、jQueryではなく、nativeのJavascriptになっております。
たまに聞かれるのですが、function(){}(function(){ ・・・ })() と、全体を括弧で囲って、その後実行(括弧開始、終了)が書かれています。
これは即時実行関数と言います。グローバル変数汚染が問題になった(prototype.jsとか)ことがありましたが、それを防ぐためです。

※参考 JavaScriptで即時関数を使う理由
※参考 IIFE (即時実行関数式)
※参考 JavaScriptのプロトタイプ汚染攻撃対策は難しい

ちなみに、上記をjQueryで書き直すと以下のようになります。

jQuery Validation
$(function(){
	var $forms = $('.needs-validation');
	var validation = $forms.each(function(idx, form){
		$(form).on('submit', function(e) {
			if (form.checkValidity() === false) {
				e.preventDefault();
				e.stopPropagation();
			}
			$(form).addClass('was-validated');
		});
	});
});

今回はjQueryを利用していますが、Bootstrap側が提供しているものを組み込んでいきたいと思います。

assets/js/script.js
$(function(){
	/* Datatables有効時 */
	if($.fn.dataTable){
		/* Datatablesの初期設定 */
		$.extend($.fn.dataTable.defaults, {
			info: false,		/* 表の左下の情報非表示 */
			searching: false,	/* 表の右下の検索条件非表示 */
			lengthChange: false	/* 表の左上の表示行数非表示 */
		});
		/* Datatables PDF出力時の言語設定 */
		pdfMake.fonts = {
			GenShin: {
				normal: 'GenShinGothic-Normal-Sub.ttf',
				bold: 'GenShinGothic-Normal-Sub.ttf',
				italics: 'GenShinGothic-Normal-Sub.ttf',
				bolditalics: 'GenShinGothic-Normal-Sub.ttf'
			}
		}
	}
});

/** 
 * 指定要素の内容を、指定値までカウントアップします。
 * 
 * @param $el 指定要素
 * @param end 終了値
 * @param duration 終了までの時間
 */
function countUp($el, end, duration){
	$({value: $el.text()}).animate({value: end}, {
		duration : duration,
		progress : function(){
			$el.text(Math.round(this.value));
		}
	});
}
/**
 * Bootstrap Validation
 */
(function () {
  'use strict'

  // Fetch all the forms we want to apply custom Bootstrap validation styles to
  var forms = document.querySelectorAll('.needs-validation')

  // Loop over them and prevent submission
  Array.prototype.slice.call(forms)
    .forEach(function (form) {
      form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
})()

準備が整いましたので、正常系、異常系のメッセージを入れていきたいと思います。
正常系メッセージには、.valid-feedback 、異常系のメッセージには、.invalid-feedback を付けていきます。
両方とも、親要素に、.was-validated がない場合は、非表示の要素になります。

.valid-feedback.invalid-feedback は、CSSの検証用疑似要素である :valid:invalid を利用して定義されています。
※参考 :valid
※参考 :invalid
※参考 クライアント側のフォームデータ検証

usersEdit.html(content部分抜粋)
<main class="contents">
	<section class="container-fluid">
		<header>
			<h1><i class="fas fa-id-card-alt"></i> ユーザ管理</h1>
		</header>

		<form class="needs-validation" novalidate>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="name" placeholder="名前を入力してください。" required>
						<label for="name">名前</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="email" class="form-control" id="mail" placeholder="メールアドレスを入力してください。" required>
						<label for="mail">メールアドレス</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="password" class="form-control" id="passwd" placeholder="パスワードを入力してください。" required>
						<label for="passwd">パスワード</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="tel" class="form-control" id="phone" placeholder="電話番号を入力してください。" required>
						<label for="phone">電話番号</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
				<div class="col-lg mb-3">
					<div class="form-floating">
						<select class="form-select" id="dept" required>
							<option value="">選択してください</option>
							<option value="1">経理</option>
							<option value="2">人事</option>
							<option value="3">総務</option>
							<option value="4">営業第1課</option>
							<option value="5">営業第2課</option>
							<option value="6">営業第3課</option>
						</select>
						<label for="dept">所属部署</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<div class="form-floating">
						<input type="text" class="form-control" id="address" placeholder="住所を入力してください。" required>
						<label for="address">住所</label>
						<div class="valid-feedback">正しい入力です</div>
						<div class="invalid-feedback">正しく入力してください</div>
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col-lg mb-3">
					<button class="btn btn-success"><i class="far fa-check-circle"></i> 登録</button>
				</div>
			</div>
		</form>

	</section>
</main>

メッセージを実装したら、登録ボタンを押下し、以下のようにメッセージが表示されれば実装完了です。

次回は、Validationの続きで、パターンを設定していきたいと思います。

魁!小野の塾 小さな管理機能を作ってみようの巻

魁!小野の塾 PHPで簡単なプログラムを作ってみようの巻

  • このエントリーをはてなブックマークに追加

PAGE TOP