Webアプリケーションで避けて通れないものといえば「値チェック」。サーバーサイドで行うものはもちろん必要ですが、データを送信する前にJSでチェックするほうがUI/UX的に良いのは当たり前でしょう。
Magentoでは1系ではprototype.jsをベースにしたバリデーションが実装されていました。
2系はjQueryベースになっていますが、概ね同じ方式が使えます。
#MagentoのJSバリデーションが定義されている場所
Magento2系の場合、同じ様な定義が以下の箇所にあります。チェック処理の形式も似ていて、紛らわしいので注意が必要です。
- lib/web/jquery/jquery.validate.js
- lib/web/mage/validation.js
- lib/web/mage/validation/validation.js
- lib/web/mage/backend/validation.js
- lib/web/prototype/validation.js
- vendor/magento/module-ui/view/base/web/js/lib/validation/rules.js
#knockout.jsなフォームの値チェック
Magento2の標準テーマの場合、ベタなHTMLのフォームとUI Componentが描画するフォームの2種類があります。
前者の場合はHTMLに書き込んでしまえば色々できますが、後者はちょっと面倒です。
主にUI Componentが描画するフォームはチェックアウト画面で出てきますが、ここで表示されるフォームの値チェックは、データベースのcustomer_entity_attributeテーブルにある、validation_rules列の値をベースにしています。
要はここにチェックパターンを書いていけばチェックアウト画面での値チェックを強化できます。
ただし、ここの定義はシステム全体で共用するものなので、多言語サイトとして運用する場合には言語別の差をどう吸収するかよく考える必要があります。
#非UI Componentなフォームの値チェック
会員登録フォームや住所編集フォームの場合は、ベタなHTMLが用いられています。
こちらの場合は、各入力要素のタグを見ると下記のようになっています。
<input type="text" name="telephone" id="telephone" value="" title="電話番号" class="input-text required-entry">
もとのphtmlでは下記のように定義されています。
<input type="text"
name="telephone"
id="telephone"
value="<?= $block->escapeHtmlAttr($block->getTelephone()) ?>"
title="<?= $block->escapeHtmlAttr(__('Phone Number')) ?>"
class="input-text <?= $_validationClass ?: '' ?>"
>
この例は電話番号入力欄の例ですが、$_validateionClassの値を元にJSバリデーションがかかることを意味しています。
電話番号の場合はrequired-entryが入っている、ということになります。
この定義は、eav_attributeテーブルのis_requred列にあり、ここの値が1の場合はrequired-entryとして扱われます。
##非UI ComponentでもUI Component版と同じバリデーションをするには
とはいえチェックアウト画面とその他の画面でチェックパターンが異なると困ります。
非UI Componentなフォーム入力要素の場合は、
<input type="text"
name="telephone"
id="telephone"
value="<?= $block->escapeHtmlAttr($block->getTelephone()) ?>"
title="<?= $block->escapeHtmlAttr(__('Phone Number')) ?>"
class="input-text <?= $_validationClass ?: '' ?>"
data-validate="{'required':true,'validate-digits':true,'maxlength':14,'minlength':9}"
>
というように、タグ上にdata-validate属性を追加し、JSON形式でチェックパターンを書けば動きます。
なお、チェックパターンは前から順番に適用されていくので注意しましょう。
##data-validateの場合はどの定義を見ているか
data-validateで値チェックをする場合、JSの処理は
- lib/web/mage/validation.js
をみています。ここに定義されているパターンを使うことになるので、存在しないパターンを使わないように注意しましょう。
UI Component版は
- vendor/magento/module-ui/view/base/web/js/lib/validation/rules.js
を見るので一部パターンが異なる点にも注意が必要です。
#独自にチェックパターンを追加したい場合
独自にチェックパターンを追加したい場合は、
- lib/web/mage/validation.js
に対してmixinを宣言します。
日本語化エクステンションの実装がわかりやすいと思うのでそちらを参照していただくと良いでしょう。