validatorjs がとても便利だったので validatorjs-riot を作った

[validatorjs](https://www.npmjs.com/package/validatorjs) がとても便利だったので、Riot.jsでも簡単に使えるように作りました。
（この記事はvalidatorjs-riotのREADMEから抜粋して日本語訳したものです）

[**validatorjs-riot**](https://www.npmjs.com/package/validatorjs-riot)

# validatorjs-riot というか validatorjs のいいところ

- 用意されているバリデーションルールがたくさんある
- バリデーションルールが読みやすい
- エラーメッセージが多言語対応されている

# インストール

```
npm install validatorjs-riot
```

```js
// ES6 modules
import Validator from 'validatorjs-riot';
 
// CommonJS modules
let Validator = require('validatorjs-riot');
```

# 基本的な使い方

Riot.jsの`ref`属性がついているものがバリデーションの対象となるので、`validate`属性でルールを定義します。

```html
<input type="text" ref="name" validate="required" value="" />
<input type="text" ref="email" validate="required|email" value="not an email address.com" />

<button type="button" onclick="{ register }">登録する</button>

<script>
  let Validator = require('validatorjs-riot');
  this.errors = {}

  this.register = function () {
    let validation = new Validator(this.refs);

    console.log(validation.fails()); // true
    console.log(validation.passes()); // false
    console.log(validation.errors.first('name')); // 'The name format is invalid.'
    console.log(validation.errors.get('name')); // returns an array of all name error messages
    
    if (validation.fails()) {
      this.errors = validation.errors.all()
      return
    }
    // ...
  }
</script>
```

上の例ではバリデーション結果がログに出力されるだけですが、`this.error`に`erros.all()`をセットしているので、HTML部分に少し手を加えてやるとエラーになったフィールドに`class`を追加したりエラーメッセージを表示することができます。（Riot.jsの機能です）

```html
<input type="text" ref="name" validate="required" class="{ has-error : errors.name }" value="" />
<span if="{ errors.name }" each="{ error in errors.name }">{ error }</span>
<input type="text" ref="email" validate="required|email" class="{ has-error : errors.name }"
  value="not an email address.com" />
<span if="{ errors.email }" each="{ error in errors.email }">{ error }</span>
```

# 利用可能なルール

（詳細はREADMEを見てください）

- accepted
- after:date
- after_or_equal:date
- alpha
- alpha_dash
- alpha_num
- before:date
- before_or_equal:date
- between:min,max
- boolean
- confirmed
- date
- digits:value
- different:attribute
- email
- hex
- in:foo,bar,...
- integer
- max:value
- min:value
- not_in:foo,bar,...
- numeric
- required
- required_if:anotherfield,value
- required_unless:anotherfield,value
- required_with:foo,bar,...
- required_with_all:foo,bar,...
- required_without:foo,bar,...
- required_without_all:foo,bar,...
- same:attribute
- size:value
- string
- url
- regex:pattern

**注意**: 

- バリデーションルールには暗黙の「必須」はありません。フィールドが`undefined`または空文字の場合にバリデーションエラーにするには、**required**ルールを使用します。
- `` regex``パターンを使用する際に正規表現にパイプ文字が含まれている場合は、`pattern`属性でルールを指定してください。
- 正規表現に波括弧`{}`を使う場合はRiot.jsの変数と扱われてしまうのでエスケープする必要があります。


## 正規表現バリデーションの例

```html
<input type="text" ref="name" validate="required|size:3" value="Doe" />
<input type="text" ref="salary" validate="required" pattern="/^(?!0.00)\d\{1,3\}(,\d\{3\})*(.\d\d)?$//^(?!0.00)\d\{1,3\}(,\d\{3\})*(.\d\d)?$/" value="10,000.00" />
<input type="text" ref="salary" validate="required" pattern="/^(19|20)[\d]\{2,2\}$/" value="1980" />
```

# エラーメッセージ

エラーがある場合、Validatorインスタンスには、__errors__プロパティに、すべての失敗しているフィールドのエラーメッセージが格納されます。 __errors__プロパティのメソッドとプロパティは次のとおりです。

## .first(refName)

フィールドの最初のエラーメッセージを返し、エラーでない場合はfalseを返します。

## .get(refName)

フィールドのエラーメッセージの配列を返し、エラーでない場合は空の配列を返します。

## .all()

エラーになったすべてのフィールドのすべてのエラーメッセージを含むオブジェクトを返します。
（Riot.jsで使う場合はこれをthis.errorsとかにぶち込んでやればいいと思います。）

## .has(refName)

フィールドに対してエラーメッセージが存在する場合はtrueを返し、そうでない場合はfalseを返します。

## .errorCount

バリデーションエラーの件数を返します。

# バリデーションを行う対象フィールドを指定するには

Validatorの第二引数でオプション設定ができるようになっています。

## 対象にするフィールドを指定する

オプション値に`target:[refName]`を設定するとバリデーション対象を指定することができます。

```html
<input type="text" ref="name" validate="required" value="" />
<input type="text" ref="email" validate="required|email" value="not an email address.com" />
```

```js
let validation = new Validator(this.refs, { target: ['name'] });

validation.fails(); // true
validation.passes(); // false

// Error messages
validation.errors.first('name'); // 'The name field is required.'
validation.errors.get('name'); // returns an array of all name error messages
validation.errors.first('email'); // false
validation.errors.get('email'); // []
```

## 除外するフィールドを指定する

オプション値に`except:[refName]`を設定するとバリデーション対象から除外することができます。

```js
let validation = new Validator(this.refs, { except: ['name'] });
```

# 多言語対応

エラーメッセージはデフォルトで英語になっているので、`Validator.useLang('ja')`を呼び出せば日本語のエラーメッセージで表示されます。

```js
let Validator = require('validatorjs-riot');
Validator.useLang('ja');
```

# エラーメッセージに表示されるフィールド名のカスタマイズ

多言語対応をしたものの、エラーメッセージにはフィールド名がそのまま表示されるので「nameは必須です。」みたいな感じになっていると思います。
`ref-label`に日本語名をセットするか、`.setAttributeNames()`でフィールド名と日本語名のペアを登録することで正しく表示されるようになります。

```html
<input type="text" ref="name" validate="required" ref-label="氏名" value="" />
```

```js
let validator = new Validator(this.refs);
Validator.useLang('ja');
if (validator.fails()) {
  validator.errors.first('name'); // "氏名は必須です。"
}
```

```html
<input type="text" ref="name" validate="required" value="" />
```

```js
let validator = new Validator(this.refs);
validator.setAttributeNames({ name: '氏名' });
if (validator.fails()) {
  validator.errors.first('name'); // "氏名は必須です。"
}
```