17

For a web application I'm building privacy is very important and so is the format users input their data.

To help with this I have inserted a jquery library that will help mask the fields http://igorescobar.github.io/jQuery-Mask-Plugin/

However, I seem to be having trouble masking social security numbers. For instance, the format is coming through nicely 567-78-7890, but I can't seem to figure out how to mask or hide those first four numbers... like *--7890.

My html is just an input field

<input class='social' />

and with this plugin I have tried masking it as

$('.social').mask('000-00-0000');

This is just providing formatting

$('.newsocial').mask('xxx-xx-0000');

This will just replace the numbers they have entered with x's.

I have also set up a jsFiddle to help http://jsfiddle.net/w2sccqwy/1/

Any help would be wonderful!

P.S. I cannot use a password field because the last four numbers have to be shown to the user and I cannot have more than one field. This is a company requirement. I cannot change a company requirement as much as I want to.

zazvorniki
  • 3,512
  • 21
  • 74
  • 122
  • 8
    You're more likely to have problems with hackers pulling these numbers out of your database, than with casual lookers reading SSNs over the user's shoulder. Leave it in plain sight, and if you're using SSNs to uniquely identify users -- don't. – Blazemonger Aug 18 '14 at 15:50
  • I'm working on a kiosking system...people looking over their shoulder is a huge issue. I can't just let them in plain sight besides the fact that it against so many of my companies policies. – zazvorniki Aug 18 '14 at 15:51
  • 3
    Where do those people live, entering confidential information on public computers? – Daniel W. Aug 18 '14 at 15:52
  • If it really is that much of a risk, surely the user shouldn't be putting their SSN in in public anyway? – ggdx Aug 18 '14 at 15:52
  • 4
    Honestly, the fact that you're having trouble with this step suggests that you probably aren't securing the SSNs properly anyway. Security is far more important than privacy. – Blazemonger Aug 18 '14 at 15:53
  • I am working on a medical kiosk. This is necessary. – zazvorniki Aug 18 '14 at 15:53
  • Unless you have a VERY valid reason to actually store SSN.....it's generally speaking, a terrible idea to do so. – user2366842 Aug 18 '14 at 15:53
  • 9
    I HAVE a very valid reason. We're pulling up their medical records. And, I'm doing my end and the other programmers are dealing with the backed. All, I need to do is hide the numbers they're entering. – zazvorniki Aug 18 '14 at 15:55
  • You know you can use external resources in jsfiddle right? You don't have to paste the plugin right into the javascript. – Marcel Aug 18 '14 at 15:56
  • 1
    what underlying server language are you using if any? TextMode="password" is built into .NET. – RandomUs1r Aug 18 '14 at 15:57
  • Yes, I know. I just didn't want to find the actual github page and I had the plugin already open on my computer. – zazvorniki Aug 18 '14 at 15:57
  • If I use type='password' then the entire field will be masked...I need to show the last four numbers...and the other programmers are in asp. – zazvorniki Aug 18 '14 at 15:58
  • do 3 separate textboxes then? one for each section of the SSN...mask whichever one(s) you want and pull the value out programmatically, format as needed. – user2366842 Aug 18 '14 at 15:59
  • 1
    We're trying to get away from three separate text boxes and just use the one. Hence why I was trying to use this plugin. – zazvorniki Aug 18 '14 at 16:00
  • 1
    What is the problem? The masking on newsocial works fine for me. The other one is not set up to be masked. – Marcel Aug 18 '14 at 16:00
  • I'd make it a password field with a confirmation - no need to mask anything. – Daniel A. White Aug 18 '14 at 16:02
  • @Marcel, yes the x's are there...but the x's are replacing the numbers you enter not covering them up. Just type one number in the box and you can see what it's doing. – zazvorniki Aug 18 '14 at 16:02
  • 1
    @DanielA.White, I can't do that...I have to show the last four numbers. – zazvorniki Aug 18 '14 at 16:02
  • use 2 password boxes and one plain text then. then repeat for a confirmation. – Daniel A. White Aug 18 '14 at 16:04
  • 1
    @DanielA.White, I cannot use a more than one field and I cannot use a password field. That is why I am trying to use this plugin. – zazvorniki Aug 18 '14 at 16:05
  • 1
    @zazvorniki this plugin does not appear to operate like a password field for certain chars. – Daniel A. White Aug 18 '14 at 16:06
  • @DanielA.White, exactly...I'm trying to figure out a way to make this work even if I have to add separate jquery or a regex to make it work. – zazvorniki Aug 18 '14 at 16:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/59522/discussion-between-daniel-a-white-and-zazvorniki). – Daniel A. White Aug 18 '14 at 16:09
  • 4
    Sorry people are all angsty that you're dealing with SSNs, I've had it happen to me here before. It's like they never heard of such a thing... – Wesley Murch Aug 18 '14 at 16:16
  • 8
    @WesleyMurch, thank you...I hate having to explain myself when I really just asking for help...I guess I shouldn't have mentioned it was for ss numbers. – zazvorniki Aug 18 '14 at 16:18
  • 4
    late to the game but i like your solution. I dont get why anyone would waste time lecturing you. Give an answer or dont. – Leonardo Wildt Dec 28 '17 at 22:33

6 Answers6

14

For anyone who might run into this in the future I was able to figure out a solution that will mask any kind of field and format it without messing with any other plugin.

In the html you would need two inputs

<input class='number' />
<input class='value' />

and then position the number field over the value

and then in your javascript

 $('.value').on('keydown keyup mousedown mouseup', function() {
     var res = this.value, //grabs the value
         len = res.length, //grabs the length
         max = 9, //sets a max chars
         stars = len>0?len>1?len>2?len>3?len>4?'XXX-XX-':'XXX-X':'XXX-':'XX':'X':'', //this provides the masking and formatting
        result = stars+res.substring(5); //this is the result
     $(this).attr('maxlength', max); //setting the max length
    $(".number").val(result); //spits the value into the input
});

And a jsFiddle for those who would like to see the result. http://jsfiddle.net/gtom9tvL/

zazvorniki
  • 3,512
  • 21
  • 74
  • 122
  • it's not working when ssn is entered and then try to change its value at x character location. – dev verma May 05 '17 at 07:39
  • @devverma, I am not sure what you mean? Are you trying to change the value of one of the x's? If so the jsfiddle above is working. – zazvorniki May 16 '17 at 14:47
  • 1
    This is an interesting answer, however, you can see the invisible field if you highlight the text – RIanGillis Mar 12 '18 at 18:17
  • @Rlan, yes you can. I tweeted it considerably after this was posted and was able to fix that. I don't remember what that was though – zazvorniki Mar 12 '18 at 19:13
4

This is code I adapted from pure javascript mask for phone from Javascript phone mask for text field with regex. I created a codepen here http://codepen.io/anon/pen/LxWVoV

function mask(o, f) {
    setTimeout(function () {
        var v = f(o.value);
        if (v != o.value) {
            o.value = v;
        }
    }, 1);
}

function mssn(v) {
    var r = v.replace(/\D/g,"");
    if (r.length > 9) {
        r = r.replace(/^(\d\d\d)(\d{2})(\d{0,4}).*/,"$1-$2-$3");
        return r;
    }
    else if (r.length > 4) {
        r = r.replace(/^(\d\d\d)(\d{2})(\d{0,4}).*/,"$1-$2-$3");
    }
    else if (r.length > 2) {
        r = r.replace(/^(\d\d\d)(\d{0,3})/,"$1-$2");
    }
    else {
        r = r.replace(/^(\d*)/, "$1");
    }
    return r;
}

To use it, add onblur and onkeyup to the input field

<input type="text" value="" id="ssn" onkeyup="mask(this, mssn);" onblur="mask(this, mssn)">
Community
  • 1
  • 1
Nicolas Giszpenc
  • 677
  • 6
  • 11
  • Out of curiosity I put this in a fuddle and it doesn't seem to be working. https://jsfiddle.net/ne3LL9k3/ – zazvorniki Jan 17 '17 at 19:12
  • I tried your fiddle, and it failed on 'Uncaught ReferenceError: mask is not defined'. I created a working sample for you to review on my site: http://kustomweb.com/mask.php – Nicolas Giszpenc Jan 18 '17 at 19:20
  • Typically on here people post jsFiddles or another website that acts as a code bin. Eventually you will change that link and then it will no longer be applicable for this question. I posted the fiddle above to show you that the code you posted above does not work. – zazvorniki Jan 18 '17 at 20:06
  • I switched to CodePen to show that the code works. Thanks for the help. http://codepen.io/anon/pen/LxWVoV – Nicolas Giszpenc Jan 19 '17 at 19:33
  • No problem. You may also want to include all the code here as well. Lots of people just copy from the answers and don't read the comments – zazvorniki Jan 19 '17 at 20:47
  • if you use r.length > 5 and r.length > 3 then you don't have to use the setTimeout – chandler Sep 19 '17 at 20:06
2
$(".social, .newsocial").on("keydown keyup", function(e) {
    $(this).prop("value", function(i, o) {
        if (o.length < 7) {
          return o.replace(/\d/g,"*")
        }
    })
})

http://jsfiddle.net/w2sccqwy/3/

guest271314
  • 1
  • 15
  • 104
  • 177
  • I need to be able to use the plugin I mentioned. This will nullify the formatting. – zazvorniki Aug 18 '14 at 16:12
  • 1
    @zazvorniki That plugin is not for the purpose you're trying to use it for. It's for formatting. – Wesley Murch Aug 18 '14 at 16:13
  • I need to use that plugin for the formatting and validation that they are entering numbers and not letters. This was a decision made higher up than me...I need to work with it. – zazvorniki Aug 18 '14 at 16:15
  • 1
    You could however use this answer and duplicate the correct value as it is typed into a hidden field. – Wesley Murch Aug 18 '14 at 16:15
  • @WesleyMurch Last comment was ultimate approach of post. Thanks – guest271314 Aug 18 '14 at 16:16
  • But this code interacts with the plugin...if you notice all of the plugin code is commented out in that fiddle to make it work. – zazvorniki Aug 18 '14 at 16:17
  • @zazvorniki Not certain about "plugin" . js "masks" all except last 4 characters of input field - without a "plugin". As suggested by Wesley Murch, the actual data to be submitted could be concurrently entered into hidden element fields , then submitted when all 10 numbers, or 12 total characters are entered into visible ("masked") fields. – guest271314 Aug 18 '14 at 16:21
  • @guest271314 I have no choice, the people above me want to use this plugin to format data. I need to be able to do something that will not interact with it. – zazvorniki Aug 18 '14 at 16:23
  • 1
    @zazvorniki The plugin replaces characters with x when the form is submitted. Unless the only want to validate with the last four digits, tell them you can't use it. – Marcel Aug 18 '14 at 16:28
  • I wish I could, but I like my job very much and I don't want to lose it. That is why I'm trying to work with this thing instead of against it. – zazvorniki Aug 18 '14 at 16:31
1

I'm coming across this in 2020 during some UI/UX research. What I'm seeing a lot of right now are variations on the following:

<input id='set1' type='password' maxLength='3' minLength='3'>
"-"
<input id='set2' type='password' maxLength='2' minLength='2'>
"-"
<input id='set3' type='text' maxLength='4' minLength='4' pattern='[0-9]*'>

You can also add inputmode='numeric' to enable the number-based type pad on mobile.

John Meade
  • 142
  • 6
0

This should work.

var app = angular.module('myapp', []);
app.controller('MainCtrl', function($scope) {
  $scope.modelssn = '';
});

app.directive("ssnInput",function(){
    return {
        require:'ngModel',
        link: function(scop, elem, attr, ngModel){
            $(elem).mask("999-99-9999");
            var temp;
            var regxa = /^(\d{3}-?\d{2}-?\d{4})$/;
            $(elem).focusin(function(){
                $(elem).val(temp);
            });
            $(elem).on('blur',function(){
                temp = $(elem).val();
                if(regxa.test($(elem).val())){
                   $(elem).val("XXX-XX" + temp.slice(6));
               }
            });
        }
    }
});
<!DOCTYPE html>
<html ng-app="myapp">
  <head>
    <script src="https://code.jquery.com/jquery.js"></script>
    <script src="https://cdn.rawgit.com/digitalBush/jquery.maskedinput/master/src/jquery.maskedinput.js"></script>
    <script data-require="angular.js@1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
    <script src="app.js"></script>
  </head>
  <body ng-controller="MainCtrl">
    Enter SSN <input type="text" ng-model="modelssn" ssn-input >
    <p>Real SSN {{modelssn}} </p>
  </body>
</html>
ideeps
  • 379
  • 4
  • 15
0

In case its ever useful to others, I wanted to get this working with MVC model and MVC Validation with DataAnnotation. And I couldnt use any of the plugins and library. Finally was able to get this working with the script below with the caveat that it will mask after you tab out from field instead of masking at the time of typing each character.

    $('#SSN').mask("999-99-9999", { placeholder: 'nnn-nn-nnnn' });
    var temp;
    var regxa = /^(\d{3}-?\d{2}-?\d{4})$/;
    $('#SSN').focusin(function () {
        $('#SSN').val(temp);
    });
    $('#SSN').on('blur', function () {
        temp = $('#SSN').val();
        if (regxa.test($('#SSN').val())) {
            $('#SSN').val("XXX-XX" + temp.slice(6));
        }
    });

You will need a reference to jquery and jquery mask.

Vipul
  • 3
  • 3