Right now you must be thinking “what and the hell is a duns number?” or “I can’t believe my luck, I was looking for an easy way to verify duns numbers on the client side in my app!”. If you are in the first camp, then let me elaborate. The D-U-N-S number is a unique identifier used for keeping track of businesses, and a business is actually required to have one if they are to do work for the US Government, Australian Government, the United Nations, or the European Commission, so yes, you could say that it widely used. What’s really cool for UI developers about the D-U-N-S number is the fact that it is set up with a check digit and you can perform some calculations on the data entered in your apps D-U-N-S field to make sure that the entry is valid. I am sure I don’t have to tell you that eliminating bad data entry is critical to ensuring data integrity, and as with most things in life, it is often easier to take care of issues at the source of the problem before they grow, rather than spend time later trying to clean up the mess.
To set this check up in Extjs we will need to create a custom vType (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.field.VTypes ).
The code is below.
var dunsNbr = /\d{2}-?\d{3}-?\d{4}/i;
// vtype for Duns Number including MOD 10 Check
Ext.apply(Ext.form.field.VTypes, {
// vtype validation function
duns: function(val, field) {
if(dunsNbr.test(val) == true){
return mod10CheckDigit(val);
} else {
return false;
}
},
// vtype Text property: The error text
// to display when the validation
// function returns false
dunsText: 'The D-U-N-S® number is always' +
' presented in a distinct format:' +
' two digits, hyphen, three digits,' +
'hyphen, four digits. ' +
'For example: 04-997-7473.',
// vtype Mask property: The keystroke filter mask
dunsMask: /[\d\-]/i
});
In the code above note that duns is the vtype, and the dunsText will be displayed in a qTip when the user enters the wrong input. The dunsMask is used to filter out keystrokes that do not match the pattern provided. It is important to realize that the mask is not a regex value that matches the specific string that you would like to see in your duns field, but is actually regex that lists the allowed characters in the field. This is a key point!
Now, take a look at the line of code:
if(dunsNbr.test(val) == true){ …}
. This is the code that performs the regex check on the value that has been entered. dunsNbr is declared at the top of our vType. You can find more information about Ext’s regex features here (http://docs.sencha.com/ext-js/4-1/#!/api/RegExp), but the points to remember are 1) you have to add a / before the regex statement and a /i at the end of the statement and 2) never try to plug your regex into the ‘Mask’ property.
I find that it’s easier to test my regex code on a website like: http://www.zytrax.com/tech/web/regex.htm#experiment before I put it in my javascript.
Now suppose you get through the check above, you will notice that the very next line reads:
return mod10CheckDigit(val);
In order to check the D-U-N-S number you would take the first 8 digits in the number. Next loop through the numbers and multiply the even numbers by 2. Now the numbers greater than 10 are separated and you write out the ones and tens place and add all of the numbers together.
D-U-N-S with check digit in the 9th place = 0 4 9 9 7 7 4 73
0 4 9 9 7 7 4 7
x1 x2 x1 x2 x1 x2 x1 x2
0+8+9+1+8+7+1+4+4+1+4 = 47
In this example above , the total is 47. Subtract this total, 47 from the next highest multiple of 10, (that is 50 in this case).
50 – 47 = 3
3 = check digit
The code below uses Modulus 10 + 5, meaning if the original check digit calculation is greater than a 4, then add 5 and then subtract 10 to determine the check digit.
That’s it! So with this quick tutorial you have seen how to apply a function and some serious calculations to an Extjs vType, how you can use regex, and what Mask is all about, and how you can ensure that data gets checked at the client side before hitting your database.
The function you need is below:
function mod10CheckDigit(value) {
//Strip all characters except numbers
var v = value.replace(/[^0-9]+/g,''),
cd = v.substr(8,1),
v = v.substr(0, 8),
total = 0,
temp,
tens,
ones,
modDigit;
//Get Odd Numbers
for (i=0; i <= v.length-1; i=i+2) {
total = total + parseInt(v.substr(i,1));
}
//Get Even Numbers
for (i=1; i<=v.length; i=i+2) {
temp = parseInt(v.substr(i,1)) * 2;
if (temp > 9) {
tens = Math.floor(temp/10);
ones = temp - (tens*10);
temp = tens + ones;
}
total = total + temp;
}
//Determine the checksum
modDigit = (10 - total % 10) % 10;
// Now if the original check digit calculation is greater than a 4, then add
// 5 and then subtract 10 to determine the check digit
if (modDigit > 4){
modDigit = ((parseInt(modDigit) + 5) - 10);
}
// Duns Number Expansion OR original MOD 10 check
if ( modDigit == cd){
return true;
} else {
// alert(modDigit + ' - ' + cd);
Ext.Msg.alert('Invalid D-U-N-S® Number', 'The D-U-N-S® number you entered was in the correct format, however, did not pass the D-U-N-S® validation test. Please correct your input. ')
return false;
}
}

