[a-blog cms]Formモジュールとバリデーションのあれこれ
前書き
このエントリーはa-blog cms Advent Calendar 2023 11日目の記事です。
今回は、ただa-blog cmsの組み込みJSを使ってバリデーションをするだけではなく、いくつかのポイントと応用を紹介していきます。
※a-blog cmsの動作テストはv3.1.5で行っております。
※a-blog cmsにはバリデータがサーバーサイドと組み込みJSの2種類あるので、それぞれ「SSバリデータ」と「JSバリデータ」と表現いたします。
本題
組み込みJSのバリデーションについて
組み込みJSとはa-blog cmsの標準で搭載してあるJavaScriptで、その中にバリデータが入っています。(公式サイトはこちら)
使い方は以下で、ポイントはどのクラス/data属性に何の値を入れるかです。
- formタグに
js-validator
クラス - SSバリデータにid属性
- (2)につけたid属性の値をエラー文に
data-validator-label
属性 - 同じくエラー文に
data-validator
属性 - 同じくエラー文に
validator-result-{ここにはSSバリデータのnameが入ります}
クラス - JSバリデータで設定するクラスをつけたい箇所に
data-validator
属性
(1)はformタグにつけてください。
(2)(3)(4)は同じid値を入れてください。
(4)はなくても動作しますが、付けることでフォーカスから外れた時点で動作します。
(5)がデフォルトでは表示非表示をしてくれていて、{}にはSSバリデータのnameが入ります。
後に出てくるvalidatorOkClass
validatorNgClass
の付与先で、入力するinputのnameが入ります。
(6)もなくても動作しますが、後々あった方が扱いやすい場面が出てきます。
とりあえず、設定を変更していなければ上記の手順で動作します。
<dl data-validator="name">
<dt>名前</dt>
<dd>
<input
type="text"
name="name"
value="{name}"
placeholder="名前を入力してください">
</dd>
<!-- エラー文 -->
<dd>
<p
class="validator-result-{name:v#required}"
data-validator="name-v-required"
data-validator-label="name-v-required">
※お名前を入力してください
</p>
</dd>
<!-- / -->
<dd hidden>
<input type="hidden" name="name:v#required" id="name-v-required">
<input type="hidden" name="field[]" value="name" />
</dd>
</dl>
組み込みJSのコンフィグ
組み込みJSは /js/config.js
で初期設定が行われていますが、テーマ毎に設定を変更したい場合もあるため、テーマ内で設定を上書きすることが推奨されています。
ACMS.Config({
validatorFormMark: 'form.js-validator',
validatorResultClass: 'validator-result-',
validatorOkClass: 'valid',
validatorNgClass: 'invalid'
});
設定項目 | 説明 |
---|---|
validatorFormMark | バリデーターを使うform要素のセレクター |
validatorResultClass | バリデーション実行後に要素につけるクラス属性(エラーメッセージの表示切り替えに利用できます。) |
validatorOkClass | バリデートにパスした時につけるクラス |
validatorNgClass | バリデートに引っかかった場合につけるクラス |
エラー箇所まで戻る
ここまでは公式ドキュメントにも書いてありますが、ここからは応用編として進めていきます。
ポイントは、使い方(6)でつけたdata属性とコンフィグのvalidatorNgClass
です。
動作の流れは、送信ボタンを押した時にvalidatorNgClass
がついているかどうかを確認します。
また、使い方(6)の要素にクラスを一つつけておきましょう(ここではjs-validate
)。そうすることで、楽にエラー箇所を取得できるようになります。
以下、動作の流れです。
- ボタンクリック時にチェックできるようにする。
- クリックした後にJSバリデータが動作するので、
validatorNgClass
の付与に時間がかかってしまい、エラーチェックを抜けてしまう場合がある。なので、setTimeout関数
で時間を空ける。 - もしエラーがあった場合、使い方(6)で指定した箇所に
validatorNgClass
のクラスが付与されている。 - 前文でつけたクラス(
js-validate
)とvalidatorNgClass
のクラスでquerySelector関数
を実行すると、はじめに取得した一致箇所が取得できる。 - JavaScriptの
scrollTo関数
でエラー箇所まで戻る。
function errCheck() {
setTimeout(() => {
const errText = document.querySelector('.js-validate.invalid');
if(!errText) return true;
const targetTop = errText.getBoundingClientRect().top + window.scrollY;
window.scrollTo({
top: targetTop,
behavior: 'smooth'
});
}, 100);
return false;
}
const buttonList = document.querySelectorAll('button[name="ACMS_POST_Form_Confirm"]');
buttonList.forEach((button) => {
button.addEventListener('click', errCheck);
});
Formモジュールのstepを選べるようにする
最後に応用2です。
フォームのstepを選べるようにする場合、通常の実装をしようとするとその分formを増やす必要があります。
しかしそうしてしまうと、JSバリデータは入力欄がある方のformタグにしか反応しないです。
ですので、stepをsubmitにしてしまいます。
実際のコードを見た方がわかりやすいと思います。
<form
action=""
method="post"
class="js-validator"
enctype="multipart/form-data">
<input type="hidden" name="ACMS_POST_Form_Confirm" value="next">
<input type="hidden" name="takeover" value="{takeover}" />
<button type="submit" name="step" value="firstQuestion">問題1へ</button>
<button type="submit" name="step" value="secondQuestion">問題2へ</button>
</form>
こうすることで押した方のボタンのstepに進むことができ、一つのformで完結するのでJSバリデータを動作させることができるようになります。
後書き
いかがでしたでしょうか?
応用2に関しては滅多に見ない仕様な気もするのでおまけ程度ですが、エラースクロールはUXから考えても実装しておいて損はないかなと思います。
Discussion