Skip to content

Instantly share code, notes, and snippets.

@adamsilver
Last active August 6, 2020 14:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamsilver/74638e38b0f7e314e1f9cebce17a0970 to your computer and use it in GitHub Desktop.
Save adamsilver/74638e38b0f7e314e1f9cebce17a0970 to your computer and use it in GitHub Desktop.
Server side form validator component for Express
function isEmpty(value) {
var valid = true;
if(!value || value.trim().length == 0) {
valid = false;
}
return valid;
}
router.post('/edit', (req, res) => {
var v = new Validator(req, res);
v.add('subject', [{ fn: isEmpty, message: 'Enter the subject' }]);
v.add('body', [{ fn: isEmpty, message: 'Enter the question' }]);
if(v.validate()) {
res.redirect('/');
} else {
res.render('template');
}
});
function Validator(req, res) {
this.req = req;
this.res = res;
this.validators = [];
this.errors = [];
}
Validator.prototype.add = function(name, rules) {
this.validators.push({
name: name,
rules: rules
});
};
Validator.prototype.getErrors = function() {
return this.errors;
};
Validator.prototype.getFormattedErrors = function() {
return this.errors.map(this.formatError);
};
Validator.prototype.exposeInlineErrors = function() {
this.res.locals.inlineErrors = {};
this.errors.forEach(error => {
const { name, message } = error;
this.res.locals.inlineErrors[name] = { text: message };
});
};
Validator.prototype.exposeErrorSummaryItems = function() {
this.res.locals.errorSummary = {
items: this.getFormattedErrors()
};
};
Validator.prototype.formatError = function(error) {
return {
text: error.message,
href: '#' + error.name
};
};
Validator.prototype.getError = function(name) {
return this.getErrors().filter(error => error.name == name).map(this.formatError)[0];
};
Validator.prototype.validate = function() {
const body = this.req.body;
const errors = [];
for( let validator of this.validators ) {
const { name, rules } = validator;
const value = body[ name ];
for( let rule of rules ){
const { fn, params, message} = rule;
const isValid = fn( value, params );
if( !isValid ){
errors.push( { name, message } );
break;
}
}
}
this.errors = errors;
this.exposeInlineErrors();
this.exposeErrorSummaryItems();
this.res.locals.hasValidationErrors = true;
return errors.length == 0;
};
module.exports = Validator;
{% if errorSummary.items.length %}
{{ govukErrorSummary({
titleText: 'There is a problem',
errorList: errorSummary.items
}) }}
{% endif %}
{{ govukInput({
label: { text: 'Subject'},
id: 'subject',
name: 'subject',
errorMessage: inlineErrors.subject
}) }}
{{ govukTextarea({
label: { text: 'Question' },
id: 'body',
name: 'body',
errorMessage: inlineErrors.body
}) }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment