Bootstrap＋Smokeでフォームの入力チェック

Bootstrapで作成しているページで入力チェックを行うためSmokeを使ってみた。
Smokeにはバリデーションの他にもいくつか機能があるが、今回はバリデーションのみを使用。

## Smoke公式
http://alfredobarron.github.io/smoke/#/

## ライブラリ＆使用したバージョン
jQuery 1.12.4
Bootstrap 3.3.6
Smoke 3.1.1
※jQuery、Bootstrap 3は必須

## 導入・構成
Bower、npmでインストールできるが、今回サンプルではダウンロードして以下のように配置。

```
├── css
│   ├── smoke.css
│   └── smoke.min.css
├── js
│   ├── smoke-ja.js
│   ├── smoke-ja.min.js
│   ├── smoke.js
│   └── smoke.min.js
└── sample.html（今回作成するサンプル）
```
※jQuery、BootstrapはMicrosoft CDNを使用

#### メッセージの日本語化
公式サイトのlanguageより以下のリンクがあるのでlangから`smoke-ja.js`をダウンロードし、今回はjs配下に格納。
https://github.com/hidesuke/smoke

こちらの日本語化ファイルは、バージョンが2.2.3のものなのでメッセージが足りていないものがある。
`smoke.js`本体の先頭の方で`languaje`という変数で設定を行っているので、必要に応じて足りていないメッセージを`smoke-ja.js`にコピーして日本語の設定を行う。

## 使ってみる
サンプルの入力フォームはSmoke公式ページのものを拝借して。

#### CSS、JSの読み込み
```html:sample.html
<!-- CSS -->
<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="css/smoke.min.css">

<!-- JS -->
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"></script>
<script src="js/smoke.min.js"></script>
<script src="js/smoke-ja.js"></script>
```

#### バリデーションを行うスクリプト
```html:sample.html
<script>
$(document).ready(function() {
    /**
     * バリデーションボタン押下時処理
     * バリデーションを行う
     */
    $('#btn-validate').on('click', function(e) {
        if ($('#sample-form').smkValidate()) {
            // バリデーションOKの処理
        } else {
            // バリデーションNGの処理
        }
    })

    /**
     * クリアボタン押下時処理
     * フォームのクリア
     */
    $('#btn-clear').on('click', function (e) {
        $('#sample-form').smkClear();
    });
});
</script>
```

#### サンプルフォーム
```html:sample.html
<div id="sample-panel" class="panel panel-primary">
  <div class="panel-heading">Bootstrap + Smoke Validation</div>
  <div class="panel-body">
    <form id="sample-form" data-smk-icon="glyphicon-remove-sign">
      <div class="form-group">
        <label class="control-label">Text</label>
        <input type="text" class="form-control" placeholder="Enter text" required>
      </div>
      <div class="form-group">
        <label class="control-label">Select</label>
        <select class="form-control" required>
          <option value="">Select</option>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>
      </div>
      <div class="form-group">
        <label class="control-label">Textarea</label>
        <textarea class="form-control" rows="3" required></textarea>
      </div>
      <div class="form-group">
        <label class="control-label">Checkbox</label>
        <div class="checkbox">
          <label>
            <input type="checkbox" name="check" value="1" required>
            Checkbox
          </label>
        </div>
      </div>
      <div class="form-group">
        <label class="control-label">Radio</label>
        <div class="radio">
          <label>
            <input type="radio" name="rad" value="option1" required>
            Option 1
          </label>
        </div>
        <div class="radio">
          <label>
            <input type="radio" name="rad" value="option2" required>
            Option 2
          </label>
        </div>
      </div>
      <div class="text-center">
        <button type="button" id="btn-validate" class="btn btn-primary">バリデーション</button>
        <button type="button" id="btn-clear" class="btn btn-default">クリア</button>
      </div>
    </form>
  </div>
</div>
```

## 実行イメージ
**初期表示**
![初期表示.png](https://qiita-image-store.s3.amazonaws.com/0/128475/3c58c338-35f1-9b4b-4e65-f17185633d01.png)

**バリデーション実行**
![バリデーション.png](https://qiita-image-store.s3.amazonaws.com/0/128475/5f8d3e4a-a707-d618-d9d1-d1b6703d1f25.png)

## 使い方説明
#### 入力フォームの作り方
バリデーションエラーを表示するためには、入力フィールドのclassに`form-control`を指定し、`div.form-group`の中に記述する必要ある。

```
<div class="form-group">
  <label class="control-label">Text</label>
  <input type="text" class="form-control" placeholder="Enter text" required>
</div>
```

#### バリデーションチェック
`$.smkValidate()`で対象form内フィールドのバリデーションを行う。戻り値はバリデーション結果で全ての入力がOKならtrue、入力エラーがあればfalseとなる。

#### フォームのクリア
`$.smkClear()`で入力値とバリデーション結果のクリアを行う。入力値もクリアされるのでクリアされたくないフィールドには`data-smk-noclear`属性を付ける。

#### エラー時のアイコン設定
![アイコン変更.png](https://qiita-image-store.s3.amazonaws.com/0/128475/c2d6b965-105d-cbf1-21a8-fd6ce6e1328a.png)
対象のformに`data-smk-icon`属性でクラスを指定すると、入力エラー時にフィールドの右端に表示されるアイコンが指定できる。標準ではBootstrapのGlyphiconsを使用するが、Font Awesomeなども使用可能。

**Font Awesome使用方法**
表示位置がずれるのでstyleでline-heightを設定

```css
<style>
.fa.form-control-feedback { line-height: 34px; }
</style>
```

フォームの`data-smk-icon`属性にFont Awesomeのiconクラスを指定
以下の例のようにspinも使用可能

```html
<form id="sample-form" data-smk-icon="fa fa-spin fa-refresh">
　　　：
</form>
```

#### バリデーション設定
まず基本の必須チェックは`required`属性で指定。
表示するメッセージを変更する場合は`data-smk-msg`属性で指定。
入力形式のチェックはinputタグの`type`属性で自動判別してくれるものと、`data-smk-type`属性で指定するものがある。

| 属性 | 値 | 説明 |
|:---|:---|:---|
| required |  | 必須入力チェック |
| data-smk-msg | メッセージ文字列 | エラー時のカスタムメッセージ |
| input[type] <br> minlength <br> maxlength | text <br> 最小文字数 <br> 最大文字数 | 文字数制限 |
| input[type] | number | 数値チェック |
| input[type] <br> data-smk-pattern | text <br> 正規表現文字列 | 正規表現チェック |
| input[type] <br> data-smk-strongPass | password <br> defaut&#124;week&#124;medium&#124;strong | パスワードチェック <br> default：4文字以上 <br> week：6文字以上 <br> medium：6文字以上の英数字混在 <br> strong：6文字以上の英（小・大文字）数字混在 |
| input[type] | mail | メールアドレスチェック |
| input[type] | url | URLチェック |
| input[type] | date | 日付チェック <br> yyyy-mm-dd形式（正規表現でやっているので厳密ではない） |
| input[type] | time | 時刻チェック <br> hh:mm:ss形式（秒は省略可） |
| input[type] | datetime | 日時チェック <br> yyyy-mm-dd'T'hh:mm:ss形式（正規表現でやっているので厳密ではない） |
| input[type] | month | 年月チェック <br> yyyy-mm形式 |
| input[type] | week | 年週チェック <br> yyyy-'W'00（週目）形式 |
| input[type] | tel | 電話番号チェック <br> '+'数値10〜15桁形式 先頭の'+'な無くても可 |
| input[type] | color | カラーチェク <br> #000000形式 |
| data-smk-type | alphanumeric | 英数字チェック |
| data-smk-type <br> data-smk-min <br> data-smk-max | number <br> 最小値 <br> 最大値 | 数値範囲チェック |
| data-smk-type <br> data-smk-decimal-separator | decimal <br> 小数に使用する記号（省略時は"."） | 数値チェック（小数OK） |
| data-smk-type <br> data-smk-decimal-separator <br> data-smk-thousand-separator | currency <br> 小数に使用する記号（省略時は"."） <br> 3桁ごとの区切り文字（省略時は","） | 通貨チェック |

あとはjsで`$.smkEqualPass()`というパスワードの確認用に入力したものと一致しているかのチェックがある。

## おわり
基本的にはHTMLの記述で設定でき、スクリプトはほとんど不要。
Bootstrapを使っている場合はお手軽に導入できるので、興味を持たれた方は試してみてはいかがでしょうか。