Materializeでのvaliate方法について

###Materializeとは

https://materializecss.com/about.html

###Materializeでのvaliate方法について

inputセレクタとselectセレクタを使ったvalidate方法はやり方が異なります。
それぞれのやり方を以下に整理しました。

#### 前提

- Materialize バージョン： 1.0.0
- inputセレクタ、selectセレクタのタグの後に、helper-textクラスを使ったタグにてエラーメッセージの表示を行う

#### inputセレクタのvalidate

##### 必須入力チェック

inputセレクト内で、classに'validate'を指定し、かつrequiredを指定すると、
Materializeでバリデーションがかかる。

```
<input type="text" name="user_name" class: 'validate', required:'required' >
<span class="helper-text" data-error="ユーザー名を入力してください。"></span>
```

#### selectセレクタのvalidate

##### 必須入力チェック

Materialize自体で、selectのvalidate処理がない様に見受けられるため、
自分でコードを用意してあげる必要があるみたいです。
以下のgithubのページでissueとして取り上げられている様です。

https://github.com/Dogfalo/materialize/issues/1861

ここのページでは、select用のvalidate処理を実装するための方法を「eduardoalcantara」さんが提示されています。提示されているコードをselectの値が変更された時と、buttonを押下した時にselectのvalidateを行うようにコードを修正しました。


```:javascript(Materialize用追加コード)
  // Materializeではエラーメッセージをhelper-textクラスにて表示する仕組みです。
  // Materializeではselect要素をhtmlで指定しても、selectセレクタをinputセレクタにMaterializeにて変換をしている。
  // エラーメッセージを表示するhelper-textクラスをselectセレクタのタグの後に記入をしても、エラーメッセージを正しく表示できない。
  // selectセレクタをinputセレクタに変換しているため、inputセレクタの後にhelper-textクラスを適切な箇所に記載ができず、エラーメッセージが正しく表示できない。
  // inputセレクタの後にhelper-textクラスを定義するにはjavascript側で定義しないと反映できない

  // select用のhelper-textクラスの初期設定
  // select用のhelper-textクラスのタグを、inputセレクタのタグの次にセットを行う
  M.init_validate_select = function () {  
    $("select[required].validate").each(function(){
      const element = $(this);
      const helper = element.parent().parent().find('.helper-text');
      if (helper !== undefined) {
        helper.insertAfter(element.parent().find('input'));
      }
    });
  };

  M.init_validate_select();

　　　　// selectセレクタのvalidate処理
  M.validate_select_field = function (object) {
    const select_value = $(object).val();
    const input_element = $(object).parent().find('input');
    input_element.removeAttr('readonly', '');

    if (select_value != '') {
      input_element.addClass('valid');
      input_element.removeClass('invalid');
    } else {
      input_element.addClass('invalid');
      input_element.removeClass('valid');
    }    
  };

  // selectセレクタの値が変更となったときに発火
  $(document).on('change', 'select[required].validate', function () {
    M.validate_select_field($(this));
  });

  // submit処理を行う際に、inputセレクタとselectセレクタのvalidate処理を行う
  // 返却値としてinvalid数（エラー数）を返却する
  M.validate_submit = function () {
    var input_selector = 'input[type=text].validate, input[type=password].validate, input[type=email].validate, input[type=url].validate, input[type=tel].validate, input[type=number].validate, input[type=search].validate, input[type=date].validate, input[type=time].validate, textarea.validate';
    $(input_selector).each(function (element, index) {
      var element = $(this);
      var len = element[0].value.length; 
      if (len === 0 && element[0].validity.badInput === false && element.is(':required')) {
        if (element.hasClass('validate')) {
          element.addClass('invalid');
          element.removeClass('valid');
        }
      }
    });

    $("select[required].validate").each(function(){
      M.validate_select_field($(this));
    });

    return $(".invalid").length;
  };
```

```:javascript(Materialize用追加コードの呼び出し部)
// Ruby on Railsの場合
$('#edit_user_submit').on('click',function(e) {
　　　　var invalid_num = 0;
  invalid_num = M.validate_submit();
  if(invalid_num == 0) Rails.fire($("#edit_user")[0],'submit');
});
```

```:html
<label>test select</label>
<select class="validate" required:'required'>
  <option value="" selected>null</option>
  <option value="1">test1</option>
  <option value="2">test2</option>
  <option value="3">test3</option>
</select>
<span class="helper-text" data-error="選択してください。"></span>
```


### 参考ページ

https://github.com/Dogfalo/materialize/blob/v1-dev/dist/css/materialize.css

https://github.com/Dogfalo/materialize/blob/v1-dev/dist/js/materialize.js

https://github.com/Dogfalo/materialize/issues/1861