expressでvalidateパッケージをいくつか使ってみた後…(車輪)
2018/08/25
車輪の再発明記録です。
expressで、validateのパッケージを探してたんだけど、いくつか試した後、面倒になって自作してしまいました。 今見てみると、express-validatorで問題ないような気もする。。。
viewを簡潔に書きたくて、handlebarsを選択したんけど、これがかなり厳格にviewでロジックを書く事を拒否してるので、viewからカジュアルにメソッド呼び出しもさせてくれなくて、微妙な感じになってしまったのかもしれない。
validate.js
フィールド毎にルールを定義できて、チェック結果を連想配列で返せるのと、チェック関数を提供する。
var Field = function(name){ this.name = name, this.rules = []; }; Field.prototype.rule = function(fun, message){ this.rules.push({ fun: fun, message: message }); }; var validate = { fields: {}, errors: {}, field: function (name) { if (!(name in this.fields)) { this.fields[name] = new Field(name); } return this.fields[name]; }, init: function(){ this.fields = {}; this.errors = {}; }, isValid: function(req){ console.log('isValid'); for (var name in this.fields) { var f = this.fields[name]; var value = req.body[name]; for (var j = 0; j < f.rules.length; j++) { var rule = f.rules[j]; console.log(rule.fun.toString()); if (!rule.fun(value)) { if (!(name in this.errors)) { this.errors[name] = []; } this.errors[name].push(rule.message); } } } return Object.keys(this.errors) == 0; }, required: function(){ return function(x){ if (typeof x == 'undefined') { return false; } if (typeof x == 'string') { if (x.length == 0) { return false; } } return true; }; }, maxlength: function(n){ var max = n; return function(x){ console.log(x); return x.length <= max; }; }, notinclude: function(arr){ var items = arr; return function(x){ for (var i = 0; i < items.length; i++) { if (x == items[i]) { return false; } } return true; }; }, }; module.exports = validate; // vim: set ts=2 sts=2 sw=2 expandtab ai: |
routes/index.js
使用例。validate.field() でルールとエラーメッセージを登録している。
var validate = require('../validate'); router.post('/register/:id', function(req, res, next) { var id = req.params.id; validate.init(); validate.field('kamigo').rule(validate.required(), '入力してください。'); validate.field('nakasiti').rule(validate.required(), '入力してください。'); validate.field('simogo').rule(validate.required(), '入力してください。'); if (!validate.isValid(req)) { console.log(validate.errors); req.flash('error', '入力エラーがあります。'); return res.render('register', { errors: validate.errors, }); } .... |
views/register.hbs
viewファイル。inputのclassにエラー用クラスを追加するのと、エラーメッセージを表示する。
<div class="col-lg-3 col-sm-10"> <input class="form-control {{#if errors.kamigo}}is-invalid{{/if}}" type="text" value="{{req.body.kamigo}}" id="kamigo" name="kamigo" placeholder="五" maxlength="8" > <div class="invalid-feedback"> {{errors.kamigo}} </div> </div> <div class="col-lg-4 col-sm-10"> <input class="form-control {{#if errors.nakasiti}}is-invalid{{/if}}" type="text" value="{{req.body.nakasiti}}" id="nakasiti" name="nakasiti" placeholder="七" maxlength="10"> <div class="invalid-feedback"> {{errors.nakasiti}} </div> </div> <div class="col-lg-3 col-sm-10"> <input class="form-control {{#if errors.simogo}}is-invalid{{/if}}" type="text" value="{{req.body.simogo}}" id="simogo" name="simogo" placeholder="五" maxlength="8"> <div class="invalid-feedback"> {{errors.simogo}} </div> </div> |
express-validator への置き換えを検討した方がいいか。