question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Customize validation message example + documentation issues

See original GitHub issue

@aldeed I am using this for my meteor project and I have migrate from meteor package to this node_module package together with collection-2-core package.

Currently I want to customize the validation messages for regEx because all error message for regEx is just “failed regular expression validation”, and I would like to give a more clear validation message such as “must contain at least 1 digit” etc.

However, I couldn’t find a correct way/clear example to do it. I checked the message-box package and still don’t know how to do it, and I found the documentation a bit confusing :

  1. the CHANGELOG in this README is not found
  2. at custom validation, it mentions using message-box but doen’s show clearly how to use it, I am still very new to Meteor and npm so may need more explanation on how to use it.
  3. at validate one key against another, it is using SimpleSchema.messages again instead of message-box which confuse me that which is the correct way to do.
  4. in message-box package, I am not sure where should I call the MessageBox.defaults() to make it effective (in import/ client folder?), also theimport MessageBox from 'message-box'; should be included in the Usage.
  5. when I tried to follow the Manually Adding a Validation Error in imports/collections/Users.js with
SimpleSchema.messageBox.messages({
    en: {
        wrongPassword: "Wrong password"
    }
});

It shows me messageBox is undefined even if I have imported both simpleschema and message-box npm packages. screen shot 2017-03-10 at 6 29 52 pm

I tried to customize with the code below:

MessageBox.defaults({
    initialLanguage: 'en',
    messages: {
        en: {
            required: '{{label}} is required',
            minString: '{{label}} must be at least {{min}} characters',
            maxString: '{{label}} cannot exceed {{max}} characters',
            minNumber: '{{label}} must be at least {{min}}',
            maxNumber: '{{label}} cannot exceed {{max}}',
            minNumberExclusive: '{{label}} must be greater than {{min}}',
            maxNumberExclusive: '{{label}} must be less than {{max}}',
            minDate: '{{label}} must be on or after {{min}}',
            maxDate: '{{label}} cannot be after {{max}}',
            badDate: '{{label}} is not a valid date',
            minCount: 'You must specify at least {{minCount}} values',
            maxCount: 'You cannot specify more than {{maxCount}} values',
            noDecimal: '{{label}} must be an integer',
            notAllowed: '{{value}} is not an allowed value',
            expectedType: '{{label}} must be of type {{dataType}}',
            regEx: function ({
                label,
                type,
                regExp,
            }) {
                console.log(label, type, regExp)
                // See if there's one where exp matches this expression
                let msgObj;
                if (regExp) {
                    msgObj = _.find(regExpMessages, (o) => o.exp && o.exp.toString() === regExp);

                }
                var regExpMessageTail = 'failed regular expression validation';
                if (regExp === /\d/) { // check for at least 1 digit
                    regExpMessageTail = 'must contain at least 1 digit';
                }
                var regExpMessage = msgObj ? msgObj.msg : regExpMessageTail;


                return `${label} ${regExpMessage}`;
            },
            keyNotInSchema: '{{name}} is not allowed by the schema',
        },
    }
});

But it is not working. I understand that it is still in progress, but would be nice to add a clear example on customize validation messages for regEx. Thank you!

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:6
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
ghostcommented, Apr 30, 2017

I had a similar problem, I wanted to replace the built-in errors with translated versions:

import SimpleSchema from 'simpl-schema'
import MessageBox from 'message-box'
import { Tracker } from 'meteor/tracker'

const mySchema = new SimpleSchema({
  ...
}, {tracker: Tracker})

// this domain regex matches all domains that have at least one .
// sadly IPv4 Adresses will be caught too but technically those are valid domains
// this expression is extracted from the original RFC 5322 mail expression
// a modification enforces that the tld consists only of characters
const rxDomain = '(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z](?:[a-z-]*[a-z])?'
// this domain regex matches everythign that could be a domain in intranet
// that means "localhost" is a valid domain
const rxNameDomain = '(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\\.|$))+'
// strict IPv4 expression which allows 0-255 per oktett
const rxIPv4 = '(?:(?:[0-1]?\\d{1,2}|2[0-4]\\d|25[0-5])(?:\\.|$)){4}'
// strict IPv6 expression which allows (and validates) all shortcuts
const rxIPv6 = '(?:(?:[\\dA-Fa-f]{1,4}(?::|$)){8}' // full adress
  + '|(?=(?:[^:\\s]|:[^:\\s])*::(?:[^:\\s]|:[^:\\s])*$)' // or min/max one '::'
  + '[\\dA-Fa-f]{0,4}(?:::?(?:[\\dA-Fa-f]{1,4}|$)){1,6})' // and short adress
// this allows domains (also localhost etc) and ip adresses
const rxWeakDomain = `(?:${[rxNameDomain, rxIPv4, rxIPv6].join('|')})`

const regExpObj = {
  // We use the RegExp suggested by W3C in http://www.w3.org/TR/html5/forms.html#valid-e-mail-address
  // This is probably the same logic used by most browsers when type=email, which is our goal. It is
  // a very permissive expression. Some apps may wish to be more strict and can write their own RegExp.
  Email: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  // Like Email but requires the TLD (.com, etc)
  EmailWithTLD: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[A-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[A-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?$/,

  Domain: new RegExp(`^${rxDomain}$`),
  WeakDomain: new RegExp(`^${rxWeakDomain}$`),

  IP: new RegExp(`^(?:${rxIPv4}|${rxIPv6})$`),
  IPv4: new RegExp(`^${rxIPv4}$`),
  IPv6: new RegExp(`^${rxIPv6}$`),
  // URL RegEx from https://gist.github.com/dperini/729294
  // http://mathiasbynens.be/demo/url-regex
  Url: /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a>
  // unique id from the random package also used by minimongo
  // character list: https://github.com/meteor/meteor/blob/release/0.8.0/packages/random/random.js#L88
  // string length: https://github.com/meteor/meteor/blob/release/0.8.0/packages/random/random.js#L143
  Id: /^[23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz]{17}$/,
  // allows for a 5 digit zip code followed by a whitespace or dash and then 4 more digits
  // matches 11111 and 11111-1111 and 11111 1111
  ZipCode: /^\d{5}(?:[-\s]\d{4})?$/,
  // taken from Google's libphonenumber library
  // https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js
  // reference the VALID_PHONE_NUMBER_PATTERN key
  // allows for common phone number symbols including + () and -
  Phone: /^[0-90-9٠-٩۰-۹]{2}$|^[++]*(?:[-x‐-―−ー--/  ­ <200b>⁠ ()()[].\[\]/~⁓∼ ~*]*[0-90-9٠-٩۰-۹]){3,}[-x‐-―−ー--/  ­ <200b>⁠ ()()[].\[\]/~⁓∼ ~0-90-9٠-٩۰-۹]*(?:ext=([0-90-9٠-٩۰-۹]{1,7})|[  \t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|[,xx##~~]|int|anexo|int)[:\..]?[  \t,-]*([0-90-9٠-٩۰-۹]{1,7})#?|[- ]+([0-90-9٠-٩۰-۹]{1,5})#)?$/i, // eslint-disable->
}

const regExpMessages = [
  { exp: regExpObj.Email, msg: 'muss eine gültige Email-Adresse sein' },
  { exp: regExpObj.EmailWithTLD, msg: 'muss eine gültige Email-Adresse sein' },
  { exp: regExpObj.Domain, msg: 'muss eine gültige Domain sein' },
  { exp: regExpObj.WeakDomain, msg: 'muss eine gültige Domain sein' },
  { exp: regExpObj.IP, msg: 'muss eine gültige IPv4 or IPv6-Adresse sein' },
  { exp: regExpObj.IPv4, msg: 'muss eine gültige IPv4-Adresse sein' },
  { exp: regExpObj.IPv6, msg: 'muss eine gültige IPv6-Adresse sein' },
  { exp: regExpObj.Url, msg: 'muss eine gültige URL sein' },
  { exp: regExpObj.Id, msg: 'muss eine gültige alphanumerische ID sein' },
  { exp: regExpObj.ZipCode, msg: 'muss eine gültige Postleitzahl sein' },
  { exp: regExpObj.Phone, msg: 'muss eine gültige Telefonnummer sein' },
]

const myMessageBox = new MessageBox({
  initialLanguage: 'de',
  messages: {
    de: {
      required: '{{label}} wird benötigt',
      minString: '{{label}} muss mindestends {{min}} Buchstaben lang sein',
      maxString: '{{label}} darf nicht mehr als {{max}} lang sein',
      minNumber: '{{label}} muss mindestens {{min}} sein',
      maxNumber: '{{label}} darf nicht größer als {{max}} sein',
      minNumberExclusive: '{{label}} muss größer als {{min}} sein',
      maxNumberExclusive: '{{label}} muss kleiner als {{max}} sein',
      minDate: '{{label}} muss {{min}} oder später sein',
      maxDate: '{{label}} kann nicht nach {{max}} sein',
      badDate: '{{label}} ist kein gültiges Datum',
      minCount: 'Du musst mindestens {{minCount}} Werte angeben',
      maxCount: 'Du darfst nicht mehr als {{maxCount}} Werte angeben',
      noDecimal: '{{label}} muss eine ganze Zahl sein',
      notAllowed: '[value] ist kein erlaubter Wert',
      expectedType: '{{label}} muss vom Typ {{dataType}} sein',
      regEx({ label, regExp }) {
        // See if there's one where exp matches this expression
        let msgObj
        if (regExp) {
          msgObj = _.find(regExpMessages, (o) => o.exp && o.exp.toString() === regExp)
        }

        const regExpMessage = msgObj ? msgObj.msg : 'Die Eingabe wurde bei der Überprüfung durch einen regulären Ausdruck für ungültig erklärt'

        return `${label} ${regExpMessage}`
      },
      keyNotInSchema: '{{name}} ist nicht im Schema vorgesehen'
    }
  }
})

mySchema.messageBox = myMessageBox

Most code is taken from the messagebox defaults. Obviously you should put that messagebox in a file somewhere and import it always when you need it.

I wonder how this works: https://github.com/aldeed/node-simple-schema/blob/2b8f902e0d8d84eb923f9cf0cca2124f03f41cf8/lib/testHelpers/testSchema.js#L171

1reaction
aldeedcommented, May 5, 2017

https://github.com/aldeed/node-simple-schema#customizing-validation-messages

This was not very well documented until yesterday, but I’m pretty sure there’s no actual issue here. If I’m wrong, I can reopen this.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Customize validation message example + documentation issues
Currently I want to customize the validation messages for regEx because all error message for regEx is just "failed regular expression ...
Read more >
How to Report Errors in Forms: 10 Design Guidelines
Follow the error-prevention guidelines: offer suggestions for field values, constrain inputs to legal values, and be flexible by allowing for ...
Read more >
Validation Message | Mendix Documentation
Validation message properties consist of the following sections: Common; Design Properties. 2.1 Common Section. For more information on ...
Read more >
HOWTO: Customize Document Validation
Customizing Validation Error Messages. Sometimes, the default localized messages are not satisfying. Especially when using patterns.
Read more >
HTML5 form required attribute. Set custom validation message?
In my case I want to check that the value is a number before posting but I can't use the type="number" attribute (for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found