SequelizeでのバリデーションでInput欄枠に色を付ける

## はじめに
　Node.js + Express + sequelizeを勉強中です。フォームからレコード追加するところでバリデーション作成しました。バリデーションにひっかかた際テキストでの表示しかなかったので、ユーザービリティを上げるために、エラーのでた入力欄に色をつけようと思いました。検索しても出てこなかったので、備忘録も兼ね投稿しました。

## sequelizeとは
>Node.js用のORMライブラリ。
ORMはザックリ言うと「関数やオブジェクトを使って直感的にデータベースを操作しようぜ」なこと。
（参照）[Sequelizeとは？【Node.js】](https://penpen-dev.com/blog/sequelize-node-orm/)

## 環境
+ windows10
+ node&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16.13.1
+ express&nbsp;  4.16.1
+ ejs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.6.1
+ sqlite3&nbsp;&nbsp;&nbsp;&nbsp;5.0.2
+ sequelize　6.14.0
+ sequelize-cli 6.4.1
+ bootstrap　4.3.1（CDNです）

環境のインストール、設定などは済んでいるものとします

## コード

### indexページ
データベース一覧画面、/addで追加した後に戻ってきます。

```rhtml:views/users/index.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html" charset="utf8"/>
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css">
      
    </head>
    <body class="container">
        <header><h1 class="display-4"><%= title %></h1></header>
        <div role="main">
           <table class="table">
                <% for(let co of content){ %>
                    <tr>
                        <th><%= co.id %></th>
                        <td><%= co.name %></td>
                        <td><%= co.mail %></td>
                        <td><%= co.age %></td>
                    </tr>
                
                <% } %>
           </table>
        </div>
    </body>
</html>
```

### addページ
データベースにレコードを追加するejs
className,classPass・・はバリデーションに引っかかったときにクラスを変えるために追加

```rhtml:views/users/add.ejs
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-type" content="text/html" charset="utf8"/>
        <title><%=title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css">
      
    </head>
    <body class="container">
        <header><h1 class="display-4"><%=title %></h1></header>
        <div role="main">
            <ol class="text-danger">
                <% if(err !=null){ for (let e of err.errors){ %>
                    <li><%= e.message%></li>
                <% }}%>
            </ol>
           <form action="/users/add" method="post">
               <div class="form-group">
                   <label for="name">NAME</label>
                   <input type="text" name="name" id="name" class="<%= className %>" value="<%= form.name %>">
               </div>
               <div class="form-group">
                   <label for="pass">PASSWORD</label>
                   <input type="text" name="pass" id="pass" class="<%= classPass %>" value="<%= form.pass %>">
               </div>
               <div class="form-group">
           
                   <label for="mail">Mail</label>
                   <input type="text" name="mail" id="mail" class="<%= classMail %>" value="<%= form.mail %>">
                   </ul>
               </div>
               <div class="form-group">
                   <label for="age">Age</label>
                   <input type="number" name="age" id="age" class="<%=
                   classAge %>" value="<%= form.age %>">
               </div>
               <input type="submit" value="追加" class="btn btn-primary">
           </form>
        </div>
    </body>
</html>

```

### JavaScript
crud作ったのですが、今回の記事には関係ないのでedit、deleteは消しました。



```js:routes/users.js
const express = require('express');
const router = express.Router();
const db = require('../models');

/* GET users listing. */
router.get('/', (req, res, next) => {
  let data={};
  db.User.findAll().then(usrs =>{
    data ={
      title:"Users/Index/Sequelize",
      content:usrs
    }
    res.render('users/index',data);
  })
});

//add
router.get('/add',(req,res,next)=>{
  let data ={
    title:"Users/Add",
    form:new db.User(),
    err:null,
    className:"form-group",
    classPass:"form-group",
    classMail:"form-group",
    classAge:"form-group",
  }
  res.render('users/add',data);
});
router.post('/add',(req,res,next)=>{
  const form ={
    name:req.body.name,
    pass:req.body.pass,
    mail:req.body.mail,
    age:req.body.age,
  }
  db.sequelize.sync()
  .then(()=>db.User.create(form)
  .then(usr=>{
    res.redirect('/users');
  })
  .catch(err=>{
    let data={
      title:"Users/Add",
      form:form,
      err:err,
    };
    // エラーのあるinputの枠を赤にする
　　
   let errPath =err.errors.map(item => item.path);//errのpathを取り出し

   //class名を変えることでCSSを変更
   //取り出したpathがある→ エラー有り→ 色を赤にする
    data.className = errPath.includes("name")  ? "form-group red" : "form-group";
    data.classPass = errPath.includes("pass")  ? "form-group red" : "form-group";
    data.classMail = errPath.includes("mail")  ? "form-group red" : "form-group";
    data.classAge = errPath.includes("age")  ? "form-group red" : "form-group";

    res.render('users/add',data);
  })
  )
});

module.exports = router;
```

### CSS
今回の投稿内容に関係するのは「.red」のみです。

```css:/public/stylesheets/style.css
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}

a {
  color: #00B7FF;
}
.red{
  outline:solid 2px red;
}
```
### models
ここでデータの型とvalidate設定しています。

```js:models/users.js
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User =sequelize.define('User',{
    name: {
      type:DataTypes.STRING,
      validate:{
        notEmpty:true
      }
    },
    pass:{
      type:DataTypes.STRING,
      validate:{
        notEmpty:true
      }
    },
    mail:{
      type:DataTypes.STRING,
      validate:{
        isEmail:true
      }
    } ,
    age:{
      type:DataTypes.INTEGER,
      validate:{
        isInt:true,
        min:0,
        max:130
      }
    } 
  },{});
  User.associate=function(models){};
  return User;
};
```

### appファイル
/root/usersでデータベース表示されるようにしています。
40行くらいありますが、はっしょってます。


```js:app.js
var users = require('./routes/users'); 
app.use('/users',users);//「/users」にアクセスでデータベース表示
```

## つまった所
前振り長かったですが、書きたかったのはここです！！
バリデーションした結果を動的にかえるのに最初

```js
data.classAge = err.get('age')[0]  ? "form-group red" : "form-group";
```
としたのですが、うまくいかず・・・
一度、エラーのpathを取り出して、再度判定したらうまくいきました。

```js
//errのpathを取り出し
let errPath =err.errors.map(item => item.path);

//取り出したpathがある→ その項目にエラー有り→ クラス変更（色を赤にする）
data.classPass = errPath.includes("pass")  ? "form-group red" : "form-group";
```

## 終わりに

codepen使おうと思ったのですが、EJSの<% %>タグは使えないみたいで、コード貼りました。
コードが長くなったので、概要をつかみにくいと自分でも思います。何かいい方法があれば教えてください。

## 参考文献
Node.js　超入門　掌田　津耶乃　著