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

Question

Question

Replace Digits with Asterisks In Forms

asked on May 24, 2022

We would like to replace digits with asterisks when capturing data on a form. For example, one of the Forms fields ask for a Social Security Number. We want to mask the user input at ***-**-**** without losing the dashes. I found the Answers post on how to do change the type of field to password, but that's not exactly what we are looking for. The Password type turns everything to asterisks which then makes it difficult for the user to know how many digits they entered. Does anyone have examples of how to do this?

0 0

Replies

replied on May 24, 2022 Show version history

Here's how I did it.  There are probably better ways to do this, but this one worked for me.

This is tested in Forms 11 Update 2 Classic Designer.

Add two single-line fields to your form.

Give the first one a variable name like unmasked_ssn, make it required, set a character limit of 9, and a regular expression of \d{9}

Give the second one a variable name like masked_ssn, and then you can leave all the other settings the same.

Now, check the q numbers for the two fields, if they are q1 and q2, then the following Javascript should work without any edits.  If they are different numbers, you'll need to edit all the references throughout the code: 

$(document).ready(function () {
  
  //Load the font-awesome functionality for the "eye" icon.
  $('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">');
  var eyeVisible = false;
  
  //Field1 in this example is the unmasked SSN.
  //On the layout page, that field should be marked as Required, 
  //with Character Limit of 9 and Regular Expression of: \d{9}
  //
  //Field2 in this example is the masked SSN.
  //On the layout page it should just be the single line default settings.
  //
  //If the fields are not q1 and q2, then every reference to Field1, Field2,
  //FieldLabel1, and FieldLabel2 will need to be updated.
  
  //Rearrange the two fields so that they are both combined and the
  //unmasked one is invisible.
  //This will allow errors/warnings on the hidden field to appear
  //beneath the visible field.
  $('#FieldLabel2').after($('#FieldLabel1'));
  $('#FieldLabel2').hide();
  $('#Field2').after($('#Field1'));
  $('#Field1').css('opacity', '0');
  
  //Add the "eye" icon onto the SSN field.
  $('#Field2').after('<i class="fa fa-eye" aria-hidden="true"></i>');
  $('.fa').css('position', 'absolute').css('padding', '5px');
  if($('#Field2').hasClass('cf-small')) {
    $('.fa').css('left', '21%');
  }
  else if($('#Field2').hasClass('cf-medium')) {
    $('.fa').css('left', '46%');
  }
  else if($('#Field2').hasClass('cf-large')) {
    $('.fa').css('left', '71%');
  }
  else if($('#Field2').hasClass('cf-xlarge')) {
    $('.fa').css('left', '88%');
  }
  
  //Turn the visibility off and on via the eye icon. 
  $('.fa-eye').on('mousedown', function() {
    eyeVisible = true;
    $('#Field1').trigger('input');
  });
  $('.fa-eye').on('mouseup', function() {
    eyeVisible = false;
    $('#Field1').trigger('input');
  });
  
  //When user selected the masked SSN field, automatically move the
  //focus into the unmasked field.
  $('#Field2').focus(function(){
	$('#Field1').focus();
  });
  
  //Ensure only numbers can be entered into the SSN field.
  $('#Field1').keypress(function(key) {
    if(key.charCode < 48 || key.charCode > 57) return false;
  });
  
  //Based on the length of the unmasked SSN field, update
  //the text in the masked SSN field.
  $('#Field1').on('input', function() {
    if(eyeVisible) {
      $('#Field2').val($('#Field1').val());
    }
    else {
      if($(this).val().length == 0) {
        $('#Field2').val('');
      }
      else if($(this).val().length == 1) {
        $('#Field2').val('x');
      }
      else if($(this).val().length == 2) {
        $('#Field2').val('xx');
      } 
      else if($(this).val().length == 3) {
        $('#Field2').val('xxx-');
      }
      else if($(this).val().length == 4) {
        $('#Field2').val('xxx-x');
      }
      else if($(this).val().length == 5) {
        $('#Field2').val('xxx-xx-');
      }
      else if($(this).val().length == 6) {
        $('#Field2').val('xxx-xx-x');
      }
      else if($(this).val().length == 7) {
        $('#Field2').val('xxx-xx-xx');
      }
      else if($(this).val().length == 8) {
        $('#Field2').val('xxx-xx-xxx');
      }
      else if($(this).val().length == 9) {
        $('#Field2').val('xxx-xx-xxxx');
      }
    }
  });
    
});

 

The end result should look something like this:

When holding the mouse down on the "eye" icon:

 

Also, I don't have this in a live form currently, because the person who originally requested I do this decided they wanted me to do something different, so I never got beyond testing it.  Therefore, I never bothered to load the font-awesome files into the Forms server and call them from there, so that first bit about loading them from an website is just a placeholder until you have the files on your server and can load them from there instead, which would be a better solution.

3 0
replied on June 24, 2022 Show version history

Greetings,

We took the code provided by Matthew and modified the code slightly so the last 4 digits of the SSN are displayed. Thanks for leading us in the right direction Mathew! With the help of our VAR, OPG-3, this is what we were able to come up with. We set the CSS Class SSNUnmasked on the hidden field and SSNMasked on the field that is displayed to the form submitter. Also, we used the regular expression [xX0-9][xX0-9][xX0-9][\-]?[xX0-9][xX0-9][\-]?\d\d\d\d on the masked field. See screenshot attached and code below.

$(document).ready(function () {
  //Load the font-awesome functionality for the "eye" icon.
  $('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">');
  var eyeVisible = false;

  //Add the "eye" icon onto the SSN field.
  $('.SSNMasked input').after('<i class="fa fa-eye" aria-hidden="true"></i>');
  $('.fa').css('position', 'absolute').css('padding', '5px').css('top', '1px');
  if($('.SSNMasked input').hasClass('cf-small')) {
    $('.fa').css('left', '21%');
  }
  else if($('.SSNMasked input').hasClass('cf-medium')) {
   $('.fa').css('left', '46%');
  }
  else if($('.SSNMasked input').hasClass('cf-large')) {
    $('.fa').css('left', '71%');
  }
  else if($('.SSNMasked input').hasClass('cf-xlarge')) {
    $('.fa').css('left', '80%');
  }

  //Turn the masking off and on via the eye icon. 
  $('.fa-eye').on('mousedown', function() {
    if (eyeVisible == false) {
      // Unmask input
      eyeVisible = true;
      $('.SSNMasked input').val($('.SSNUnmasked input').val());
    } else {
      // Mask input
      eyeVisible = false;
      // Get the unmasked value to mask and strip out non numerics
      var sFormatedMask = $('.SSNUnmasked input').val().replace(/[a-zA-Z ()\-`~!@#$%^&*_=+\\|{}\[\];:'"<>,./?]/g,'');
      // Set mask based on text length
      if(sFormatedMask.length == 0) {
        // Empty Mask
        sFormatedMask = '';
      }
      else if(sFormatedMask.length == 1) {
        // 1 Character Mask
        sFormatedMask = 'X';
      }
      else if(sFormatedMask.length == 2) {
        // 2 Character Mask
        sFormatedMask = 'XX';
      } 
      else if(sFormatedMask.length == 3) {
        // 3 Character Mask
        sFormatedMask = 'XXX';
      }
      else if(sFormatedMask.length == 4) {
        // 4 Character Mask
        sFormatedMask = 'XXX-X';
      }
      else if(sFormatedMask.length == 5) {
        // 5 Character Mask
        sFormatedMask = 'XXX-XX';
      }
      else if(sFormatedMask.length > 5) {
        // More than 5 Character Mask
        sFormatedMask = 'XXX-XX-' + sFormatedMask.slice(5);
      }
      // Apply masked value
      $('.SSNMasked input').val(sFormatedMask);
    }
    $(this).toggleClass("fa-eye fa-eye-slash");
  });
    
    
  $('.SSNMasked input').keydown(function(key) {
    var number
    var sKey = key.key;
    var iStart = key.target.selectionStart;
    var iEnd = key.target.selectionEnd;
    if(sKey === 'Backspace') {
      number = $('.SSNUnmasked input').val();
      if (iStart == iEnd) {
        if ((iStart) == number.length) {
          number = number.substring(0,iStart - 1);
        } else {
          number = number.substring(0,iStart - 1) + number.slice(iEnd);
        }
      } else {
        if ((iStart) == number.length) {
          number = number.substring(0,iStart - 1);
        } else {
          number = number.substring(0,iStart) + number.slice(iEnd);
        }
      }
    } else if (sKey == '1' | sKey == '2' | sKey == '3' | sKey == '4' | sKey == '5' | sKey == '6' | sKey == '7' | sKey == '8' | sKey == '9' | sKey == '0') {
      number = $('.SSNUnmasked input').val();
      if (iStart == iEnd) {
        if ((iStart) == number.length) {
          number = number + key.key;
        } else {
          number = number.substring(0,iStart) + key.key + number.slice(iEnd);
        }
      } else {
        if ((iStart) == number.length) {
          number = number.substring(0,iStart + key.key);
        } else {
          number = number.substring(0,iStart) + key.key + number.slice(iEnd);
        }
      }
    } else {
      return false;
    }
    var sFormatedNumber = number.replace(/[a-zA-Z ()\-`~!@#$%^&*_=+\\|{}\[\];:'"<>,./?]/g,'');
    if(sFormatedNumber.length > 9){
      sFormatedNumber = sFormatedNumber.substring(0,9);
    }
    if(sFormatedNumber.length == 0) {
      sFormatedNumber = '';
    } else if(sFormatedNumber.length < 4) {
      sFormatedNumber = sFormatedNumber;
    } else if(sFormatedNumber.length < 6) {
      sFormatedNumber = sFormatedNumber.replace(/(\d{3})(\d+)/,"$1-$2");
    } else if(sFormatedNumber.length > 5) {
      sFormatedNumber = sFormatedNumber.replace(/(\d{3})(\d{2})(\d+)/,"$1-$2-$3");
    }
    var sFormatedMask = number.replace(/[a-zA-Z ()\-`~!@#$%^&*_=+\\|{}\[\];:'"<>,./?]/g,'');
    
      if(sFormatedMask.length == 0) {
        sFormatedMask = '';
      }
      else if(sFormatedMask.length == 1) {
        sFormatedMask = 'X';
      }
      else if(sFormatedMask.length == 2) {
        sFormatedMask = 'XX';
      } 
      else if(sFormatedMask.length == 3) {
        sFormatedMask = 'XXX';
      }
      else if(sFormatedMask.length == 4) {
        sFormatedMask = 'XXX-X';
      }
      else if(sFormatedMask.length == 5) {
        sFormatedMask = 'XXX-XX';
      }
      else if(sFormatedMask.length > 5) {
        sFormatedMask = 'XXX-XX-' + sFormatedMask.slice(5);
      }
    if (sFormatedMask.length > 11) {
      sFormatedMask = sFormatedMask.substring(0,11);
    }
    $('.SSNUnmasked input').val(sFormatedNumber);
    if (eyeVisible == false) {
      $('.SSNMasked input').val(sFormatedMask);
    } else {
      $('.SSNMasked input').val(sFormatedNumber);
    }
    return false;
  });
  
  $('.SSNMasked').on('blur','input',function() {
    $('#form1').parsley().validate();
  });
  
  // Masks the SSN for Save to Repository image
  if ($('[name=IsLocked]').val() == 'True'){
    // Get the unmasked value to mask and strip out non numerics
      var sFormatedMask = $('.SSNUnmasked .ro').text().replace(/[a-zA-Z ()\-`~!@#$%^&*_=+\\|{}\[\];:'"<>,./?]/g,'');
      // Set mask based on text length
      if(sFormatedMask.length == 0) {
        // Empty Mask
        sFormatedMask = '';
      }
      else if(sFormatedMask.length == 1) {
        // 1 Character Mask
        sFormatedMask = 'X';
      }
      else if(sFormatedMask.length == 2) {
        // 2 Character Mask
        sFormatedMask = 'XX';
      } 
      else if(sFormatedMask.length == 3) {
        // 3 Character Mask
        sFormatedMask = 'XXX';
      }
      else if(sFormatedMask.length == 4) {
        // 4 Character Mask
        sFormatedMask = 'XXX-X';
      }
      else if(sFormatedMask.length == 5) {
        // 5 Character Mask
        sFormatedMask = 'XXX-XX';
      }
      else if(sFormatedMask.length > 5) {
        // More than 5 Character Mask
        sFormatedMask = 'XXX-XX-' + sFormatedMask.slice(5);
      }
      // Apply masked value
      $('.SSNMasked .ro').text(sFormatedMask);
  }
});

 

3 0
replied on June 24, 2022

That's fantastic!

0 0
replied on November 18, 2022 Show version history

Awesome!

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

Sign in to reply to this post.