Developer

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

魁!小野の塾 小さな管理機能を作ってみようの巻 第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部分抜粋)
[html highlight=”7,11,19,25,33,39,55″] <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]

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

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

Bootstrap Validation Javascript
[javascript highlight=””] // 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)
})
})()
[/javascript]

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

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

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

jQuery Validation
[javascript highlight=””] $(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’);
});
});
});
[/javascript]

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

assets/js/script.js
[javascript highlight=”37-58″] $(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)
})
})()
[/javascript]

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

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

usersEdit.html(content部分抜粋)
[html highlight=”13,14,23,24,31,32,41,42,57,58,67,68″] <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>
[/html]

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

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

魁!小野の塾