魁!小野の塾 小さな管理機能を作ってみようの巻 第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-validation 、novalidate 属性を追加します。
※novalidate 属性を追加しないと正しく挙動しないので、忘れないように。
パターンは正規表現 になるので、あとから実装していきたいと思います。
<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]
この状態で、必須チェックは入るようになります。(HTMLの標準機能として)
まずは、Bootstrap側が提供しているValidation用Javascriptをコピーしてきます。
※参考 Validation (バリデーション)
※参考 Validation (バリデーション)#Custom styles
(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)
})
})()
[/javascript]
Bootstrapが jQuery と決別した為、jQueryではなく、nativeのJavascriptになっております。
たまに聞かれるのですが、function(){}
を (function(){ ・・・ })()
と、全体を括弧で囲って、その後実行(括弧開始、終了)が書かれています。
これは即時実行関数と言います。グローバル変数汚染が問題になった(prototype.jsとか)ことがありましたが、それを防ぐためです。
※参考 JavaScriptで即時関数を使う理由
※参考 IIFE (即時実行関数式)
※参考 JavaScriptのプロトタイプ汚染攻撃対策は難しい
ちなみに、上記をjQueryで書き直すと以下のようになります。
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’);
});
});
});
[/javascript]
今回はjQueryを利用していますが、Bootstrap側が提供しているものを組み込んでいきたいと思います。
/* 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)
})
})()
[/javascript]
準備が整いましたので、正常系、異常系のメッセージを入れていきたいと思います。
正常系メッセージには、.valid-feedback 、異常系のメッセージには、.invalid-feedback を付けていきます。
両方とも、親要素に、.was-validated がない場合は、非表示の要素になります。
.valid-feedback、.invalid-feedback は、CSSの検証用疑似要素である :valid、:invalid を利用して定義されています。
※参考 :valid
※参考 :invalid
※参考 クライアント側のフォームデータ検証
<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>
[/html]
メッセージを実装したら、登録ボタンを押下し、以下のようにメッセージが表示されれば実装完了です。
次回は、Validationの続きで、パターンを設定していきたいと思います。