You are viewing limited content. For full access, please sign in.

Question

Question

Validate a Canadian SIN (Social Insurance Number)

asked on April 6, 2017 Show version history

We've been asked to validate a Canadian SIN in an LF Forms

The rules for validation are: 

I've found this snippet of code on the web but don't know how too adapt it to work inside Forms for Validation of the SIN field. If any coders out there want to take a crack at this, Canadian Form makers will be very happy :)

Thanks

/**
 * Validate a Canadian Social Insurance Number (SIN)
 * @param  {num || str} sin   A 9-digit Canadian SIN
 * @return {bool}             Validity of the input SIN
 */
function validateSIN (sin) {
  var check, even, tot;

  if (typeof sin === 'number') {
    sin = sin.toString();
  }

  if (sin.length === 9) {
    // convert to an array & pop off the check digit
    sin = sin.split('');
    check = +sin.pop();

    even = sin
      // take the digits at the even indices
      .filter(function (_, i) { return i % 2; })
      // multiply them by two
      .map(function (n) { return n * 2; })
      // and split them into individual digits
      .join('').split('');

    tot = sin
      // take the digits at the odd indices
      .filter(function (_, i) { return !(i % 2); })
      // concatenate them with the transformed numbers above
      .concat(even)
      // it's currently an array of strings; we want numbers
      .map(function (n) { return +n; })
      // and take the sum
      .reduce(function (acc, cur) { return acc + cur; });

    // compare the result against the check digit
    return check === (10 - (tot % 10)) % 10;
  } else throw sin + ' is not a valid sin number.';
}
 

0 0

Replies

replied on April 7, 2017

For reference, this is known as the Luhn checksum algorithm and is used more broadly than just Canadian SINs.  Searching it by name may turn up other usable implementations.

1 0
replied on April 7, 2017

Hi Steve,

If you are using Forms 10.2 and above, you could add your validation function as parsley custom validator like this:


  window.Parsley.addValidator('sin', {
    validateString: function(value) {
      return validateSIN(value);
    },
    messages: {
      en: 'Not valid sin.'
    }
  });
  $('.sin input').attr('data-parsley-sin','');

Add your function together and change the "throw sin + ' is not a valid sin number.'" to "return false" so it tells parsley the validation has failed.

For Forms 10.1 and below, Webshim is used instead of Parsley. So you could add webshim custom validation like this:

  $.webshims.ready('form-validators', function () {
    $.webshims.addCustomValidityRule('sin', function (elem, value) {
      if (value && $(elem).closest('li').hasClass('sin')) {
        return !validateSIN(value);
      }
      return false;
    }, 'Not valid sin.');
  });

 

0 0
replied on April 7, 2017

Hi Rui, thanks for your information, I am using Forms 10.2

Unfortunately I'm not a coder and need more hand holding.

My SIN field variable should be "sin"?

Also, when you say Add you function together, you lose me. I tried this but it doesn't work. If you could provide me baby steps that would be greatly appreciated. Thanks

/**
 * Validate a Canadian Social Insurance Number (SIN)
 * @param  {num || str} sin   A 9-digit Canadian SIN
 * @return {bool}             Validity of the input SIN
 */
function validateSIN (sin) {
  var check, even, tot;

  if (typeof sin === 'number') {
    sin = sin.toString();
  }

  if (sin.length === 9) {
    // convert to an array & pop off the check digit
    sin = sin.split('');
    check = +sin.pop();

    even = sin
      // take the digits at the even indices
      .filter(function (_, i) { return i % 2; })
      // multiply them by two
      .map(function (n) { return n * 2; })
      // and split them into individual digits
      .join('').split('');

    tot = sin
      // take the digits at the odd indices
      .filter(function (_, i) { return !(i % 2); })
      // concatenate them with the transformed numbers above
      .concat(even)
      // it's currently an array of strings; we want numbers
      .map(function (n) { return +n; })
      // and take the sum
      .reduce(function (acc, cur) { return acc + cur; });

    // compare the result against the check digit
    return check === (10 - (tot % 10)) % 10;
  } else return false;
}

window.Parsley.addValidator('sin', {
  validateString: function(value) {
    return validateSIN(value);
  },
  messages: {
    en: 'Not valid sin.'
  }
});
$('.sin input').attr('data-parsley-sin','');


 

0 0
replied on April 9, 2017 Show version history

For the field, set its CSS class to be "sin".

For the code, I guess you didn't add the document ready? The whole code to put in the custom javascript should look like this:

$(document).ready(function(){
//your code
});

 

0 0
replied on April 7, 2017

I viewed the page source of http://www.runnersweb.com/running/sin_check.html and borrowed the javascript from there.

$(document).ready(function () {
  $('.Submit').attr('disabled', true);
    
    $('.sin input').on('change',function () {
      isNum($(this).val());
    });
   
    var esum = 0;
    var enumbers = "";
    var checknum = 0;
    var ch_sum = "";
    var checkdigit = 0;
    var sin = "";
    var lastdigit = 0;

    function isNum(text) {              
	  if(text == "") {
        alert("You left the SIN field blank.");
        $('.Submit').attr('disabled', true);
        return false;
	  }
  
      inStr = text;
      sin = text;
      inLen = inStr.length;
	  if (inLen > 11 || inLen < 11) {
        alert("SIN must be 11 characters long");
        $('.Submit').attr('disabled', true);
	    return false;
      }
  
      for (var i = 0; i < text.length; i++) {
        var ch = text.substring(i, i + 1)
        if ((ch < "0" || "9" < ch) && (ch != "-"))  {
          alert("You must enter 9 digits and two dashes.\nFormat 999-999-999.")
          $('.Submit').attr('disabled', true);
          return false;
        }
        if ((i == 3 || i == 7) && (ch != "-")) {
          alert("Invalid character in position 4 or 8;\nMust be a dash!");
          $('.Submit').attr('disabled', true);
          return false;
        }
	  }
  
      lastdigit = text.substring(10, 10 + 1);
      // add numbers in odd positions; IE 1, 3, 6, 8		
      var odd = ((text.substring(0,0 + 1)) * (1.0)  + (text.substring(2,2 + 1)) * (1.0) +(text.substring(5, 5+1)) * (1.0) + (text.substring(8,8 + 1)) * (1.0));
      // form texting of numbers in even positions IE 2, 4, 6, 8
      var enumbers =  (text.substring(1,1 + 1)) + (text.substring(4,4 + 1)) + (text.substring(6,6 + 1)) + (text.substring(9,9 + 1));
      // add together numbers in new text string
      // take numbers in even positions; IE 2, 4, 6, 8
      // and double them to form a new text string
      // EG if numbers are 2,5,1,9 new text string is 410218
      for (var i = 0; i < enumbers.length; i++) {
        var ch = (enumbers.substring(i, i + 1) * 2);
        ch_sum = ch_sum + ch;
      }
      for (var i = 0; i < ch_sum.length; i++) {
        var ch = (ch_sum.substring(i, i + 1));
        esum = ((esum * 1.0) + (ch * 1.0));
      }
			
      checknum = (odd + esum);
			
      // subtextact checknum from next highest multiple of 10
      // to give check digit which is last digit in valid SIN
      if (checknum <= 10) {
        (checdigit = (10 - checknum));
      }
      if (checknum > 10 && checknum <= 20) {
        (checkdigit = (20 - checknum));
      }
      if (checknum > 20 && checknum <= 30) {
        (checkdigit = (30 - checknum));
      }
      if (checknum > 30 && checknum <= 40) {
        (checkdigit = (40 - checknum));
      }
      if (checknum > 40 && checknum <= 50) {
        (checkdigit = (50 - checknum));
      }
      if (checknum > 50 && checknum <= 60) {
        (checkdigit = (60 - checknum));
      }
      if (checkdigit != lastdigit) {
        alert(sin + "  is an invalid SIN; \nCheck digit incorrect!\nShould be: " + checkdigit);
        $('.Submit').attr('disabled', true);
        return false;
      }	
      $('.Submit').attr('disabled', false);
      return true;
    } 
});

Just give a single line field the "sin" CSS class. Also, keep in mind that the string needs to be like 999-999-999. The code just disables the submit button until a valid SIN is entered in.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.