Search code examples
jquerywordpressvalidationcontact-form-7

Validate textfield with 11 check for Dutch BSN


I'm using CF7 on a Wordpress website and would like to validate a textfield if it contains 9 digits and with the so called 11-check. That's an algorithm to validate Dutch SSN (BSN).

It works likes this:

Let's say we perform the 11-check on BSN 123456782

1st digit = 1, 9 * 1 = 9
2nd digit = 2, 8 * 2 = 16
3rd digit = 3, 7 * 3 = 21
4th digit = 4, 6 * 4 = 24
5th digit = 5, 5 * 5 = 25
6th digit = 6, 4 * 6 = 24
7th digit = 7, 3 * 7 = 21
8th digit = 8, 2 * 8 = 16
9th digit = 2, -1 * 2 = -2 (last digit is not added but subtracted)
 
Total is 154
 

Because 154 can be divided by 11 and it's a 9 digit number we can assume it is a valid BSN(154/11=14).

I think this can be done with <script> and </script> and some jQuery. I also found this (part of) code on Github, which I think is useful, but I'm very new to that, so hopefully there's someone out there that can help me out.

function addLeadingZerosToBSN(bsn) {
    return ("000000000" + bsn).slice(-9);
}

function getSumBSN(bsn) {

  var a = parseInt(bsn[0])*9;
  var b = parseInt(bsn[1])*8;
  var c = parseInt(bsn[2])*7;
  var d = parseInt(bsn[3])*6;
  var e = parseInt(bsn[4])*5;
  var f = parseInt(bsn[5])*4;
  var g = parseInt(bsn[6])*3;
  var h = parseInt(bsn[7])*2;
  var i = parseInt(bsn[8])*-1;

  var sum = a+b+c+d+e+f+g+h+i;
  return sum;
}

function isValidBSN(bsn) {
  bsn = addLeadingZerosToBSN(bsn);

 
  if (getSumBSN(bsn) % 11) {
    return false;
  } else {
    return true;
  }
}

Found this code but it doesn’t work with CF7:

function check_bs(){

var fieldRequired = Array("extra_1", "extra_2", "extra_3", "extra_4", "extra_5");
var alertMsg = "De volgende BS-nummers zijn niet correct:\n";
var l_Msg = alertMsg.length;

// loopje van de ingevulde velden
for (var i = 0; i < fieldRequired.length; i++){

bsnr=formobj.elements[fieldRequired[i]];
checksum=0;

// check cijfers
if(isNaN(bsnr) || bsnr.length!=9){
alertMsg += i + ". (te kort)" + "\n"
}
// check elfproef 
else{
for(i=0;i<8;i++){
checksum += (bsnr.charAt(i)*(9-i));
}
checksum -= bsnr.charAt(8);

// ongeldig nummer
if(checksum%11!=0){
alertMsg += i + ". (ongeldig)" + "\n"
}
}

}

if (alertMsg.length == l_Msg){
return true;
} else {
alert(alertMsg);
return false;
}
}

Thanks in advance.

Vasco


Solution

  • I've managed to answer my own question. Hopefully this is helpful for someone in the future. It works with everything that uses the 'eleven check'.

    My code:

    add_filter( 'wpcf7_validate_text*', 'bsn_field_validation', 20, 2 );
    function bsn_field_validation($result, $tag ) {
    
    $fields_to_validate = [
        'field-name'
    ];
    
    if ( in_array($tag->name, $fields_to_validate) ) {
    
    $bsn_number = isset( $_POST[$tag->name] ) ? trim( $_POST[$tag->name] ) : '';
    
        if (strlen($bsn_number) != 9 ) {
            $result->invalidate( $tag, "Field not valid!" );
            return $result;
        }
    
        $number = str_split($bsn_number);
    
        $bsn_counter = 0;
        $sum = 0;
        for ( $i = 9; $i >= 1 ; $i--) {
            if ($i == 1) {
                $sum = $sum - ($number[$bsn_counter] * $i);
            } else {
                $sum = $sum + ($number[$bsn_counter] * $i);
            }
            
            $bsn_counter++;
        }
    
        if ($sum % 11 != 0) {
            $result->invalidate( $tag, "Field not valid!" );
            return $result;
        }
        return $result;
      }
      return $result;
      }
    
    add_action( 'wp_footer', 'validate_cf7_bsn_field' );
    function validate_cf7_bsn_field() {
    ?>
    <script>
    
    jQuery(document).ready(function($) {
    
        const fieldsToValidate = [
            'field-name'
        ];
    
        fieldsToValidate.forEach(function(v, i) {
            $('input[name="' + v + '"]').on('blur', function() {
                const bsnNumber = $(this).val().trim();
                $(this).removeClass('wpcf7-not-valid');
                $(this).parent().find('.wpcf7-not-valid-tip').remove();
                if (bsnNumber.length != 9) {
                    $(this).addClass('wpcf7-not-valid');
                    $(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">Field not valid!</span>');
                    return false;
                } else if (Number(bsnNumber) == NaN) {
                    $(this).addClass('wpcf7-not-valid');
                    $(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">Field not valid!</span>');
                    return false;
                }
    
                bsnCounter = 0;
                sum = 0;
                for ( i = 9; i >= 1 ; i--) {
                    if (i == 1) {
                        sum = sum - (bsnNumber[bsnCounter] * i);
                    } else {
                        sum = sum + (bsnNumber[bsnCounter] * i);
                    }
                    
                    bsnCounter++;
                }
    
                if (sum % 11 != 0) {
                    $(this).addClass('wpcf7-not-valid');
                    $(this).parent().append('<span class="wpcf7-not-valid-tip" aria-hidden="true">Field not valid!</span>');
                } else {
                    $(this).removeClass('wpcf7-not-valid');
                    $(this).parent().find('.wpcf7-not-valid-tip').remove();
                }
            });
        });
        
    });
    </script>
    
    <?php
    }
    

    If you want to add more fields to validate in the same (or another form on the website) you can just add the extra field names below the first one below $fields_to_validate = [ and the same below const fieldsToValidate = [.

    Let's say you want 3 field to validate. It now says:

    $fields_to_validate = [
        'field-name'
    

    Change it to:

    $fields_to_validate = [
        'field-name'
        'second-field-name',
        'third-field-name',
    

    Also for const fieldsToValidate = [ you need to add those field name in the same way:

    const fieldsToValidate = [
        'field-name',
        'second-field-name',
        'third-field-name'