2
votes

I am using Knockout.validation to validate my input fields in my page. At first, everything is going well until I tried to use regex. I really don't know what it is that I'm doing wrong, hope you can help me out.

Below is my script:

var self = this;
self.MobileNumber = ko.observable().extend({ pattern: { params: "^(?:04\d{2}|\({1}04\d{2}\){1})\s{0,1}(\d{3}(\s{0,1})\d{3})$", message: "Invalid mobile number."} });

And below is my HTML page:

<div>
    <input data-bind="value: MobileNumber, valueUpdate: 'blur'" />
</div>
<div>
    <p data-bind="validationMessage: MobileNumber">
    </p>
</div>
2
Ok, but what is your question? What is not working? Are you sure your regex is correct? Have you test it (with something like jsregex.com)? - nemesv

2 Answers

15
votes

The regex needs to be declared as a regex rather than a string, so instead of your line above I'd use

self.MobileNumber = ko.observable().extend({ 
    pattern: { 
        params: /^(?:04\d{2}|\({1}04\d{2}\){1})\s{0,1}(\d{3}(\s{0,1})\d{3})$/, 
        message: "Invalid mobile number."
    } 
});

In my own code I habitually set up an object of regex patterns to make it easy to reuse across my app...

var patterns = {
    email: /^([\d\w-\.]+@([\d\w-]+\.)+[\w]{2,4})?$/,
    phone: /^\d[\d -]*\d$/,
    postcode: /^([a-zA-Z]{1,2}[0-9][0-9]?[a-zA-Z\s]?\s*[0-9][a-zA-Z]{2,2})|(GIR 0AA)$/
};

Then my ko looks like...

self.postcode = ko.observable().extend({
     required: true,
     pattern: {
         message: 'Must be a valid UK postcode',
         params: patterns.postcode
     }
});
2
votes

Please note if you're providing an object for pattern that you MUST include a message.

The regex can either be a string or a Regex literal.

However: If you're entering a pure string don't forget to escape any backslashes '^\\d{5}(?:[-\\s]\\d{4})?$' instead of '^\d{5}(?:[-\s]\d{4})?$'

self.postcode = ko.observable().extend({
     required: true,
     pattern: {
         message: 'Must be a valid UK postcode',
         params: patterns.postcode
     }
});

The follow doesn't work, and leads to bizarre behavior (I think it is actually trying to match against the toString() value of the pattern parameter which gives very strange results).

self.postcode = ko.observable().extend({
     required: true,
     pattern: {
         params: patterns.postcode
     }
});

Alternatively you can just provide the pattern directly

self.postcode = ko.observable().extend({
     required: true,
     pattern:  patterns.postcode
});