ember-bootstrapで、バリデーションを行う


Ember CP Validationsを使う

Ember Bootstrapのアドオンページを見ると、いくつかのバリデーションライブラリが使えそうだなと一瞬思ってしまうのですが、最新のEmber Bootstrap (v4)と一緒に使えるのはおそらくember-bootstrap-cp-validationsだけです。

  • ember-bootstrap-changeset-validations
    • ember-bootstrapのv3系だと動くようですが、v4だと動きません。
  • ember-bootstrap-validations
    • Archiveされてるのでおそらく動かないでしょう。

アドオンのインストール

ember install ember-bootstrap
ember install ember-bootstrap-cp-validations
ember install ember-cp-validations

フォームを作る

まず、前提として、下記の2点を理解しておく必要があります。

  • ember-bootstrap-cp-validations(ember-bootstrap)のFormコンポーネントは、Classicコンポーネントで作られている(@ember/componentを継承している)
  • ember-cp-validationsのバリデーションはMixinとして提供される

このため、最新のEmber.js Octanceエディションで使われる、Octaneコンポーネント(@glimmer/compnentを継承する)としてフォームを作ることは出来ません。注意してください。

なので、フォームコンポーネントは下記のコマンドで生成します。

ember g component -cc form-demo-01

これで、Classicコンポーネントのhbsファイルとjsファイルが生成されます。

フォームの内容を書く

すべてのファイルの内容を書きます。

app/components/form-demo-01.hbs
<BsForm @formLayout="vertical" @model={{this}} @onSubmit={{action "onSubmit"}} as |form|>
  <form.element @controlType="text" @label="ユーザー名" @placeholder="名前" @property="username" />
  <form.element
    @controlType="password"
    @label="パスワード"
    @placeholder="xxx"
    @property="password"
    @helpText="4文字以上"
  />
  <form.element
    @controlType="email"
    @label="メールアドレス"
    @placeholder="[email protected]"
    @property="email"
  />
  <form.element
    @controlType="email"
    @label="メールアドレスの確認"
    @placeholder="[email protected]"
    @property="emailConfirmation"
  />
  <form.submitButton>
    送信
  </form.submitButton>
</BsForm>
app/components/form-demo-01.js
import Component from "@ember/component";
import { validator, buildValidations } from "ember-cp-validations";

const Validations = buildValidations({
  username: validator("presence", { presence: true, message: "必須フィールドです" }),
  password: [
    validator("presence", { presence: true, message: "必須フィールドです" }),
    validator("length", {
      min: 4,
      message: "4文字以上入力してください",
    }),
  ],
  email: [
    validator("presence", { presence: true, message: "必須フィールドです" }),
    validator("format", { type: "email", message: "Emailのフォーマットを入力してください" }),
  ],
  emailConfirmation: [
    validator("presence", { presence: true, message: "必須フィールドです" }),
    validator("confirmation", {
      on: "email",
      message: "Emailアドレスが合致しません",
      description: "Emailアドレスの確認",
    }),
  ],
});

export default Component.extend(Validations, {
  username: null,
  password: null,
  email: null,
  emailConfirmation: null,
  actions: {
    onSubmit() {
      console.log({
        username: this.username,
        password: this.password,
        email: this.email,
        emailConfirmation: this.emailConfirmation,
      });
    },
  },
});

コード自体は非常に読みやすいですね。buildValidationsでバリデーションMixinを作成し、それをコンポーネントにMixinとして継承させていく、というスタイルになります。

Octanceコンポーネントとして作れるバリデーションライブラリがあると嬉しいのですが、そもそもまだember-bootstrapのフォームがClassicコンポーネントなので、なかなか難しそうです。