Masking last 4 digits in JavaScript

The Function will mask first 12 digits of card number as displayed below :-

Input : 4444444444444444

Output : **** **** **** 4444

function formatCardNumber(event, element) {
	if (isNaN(event.key) && !isAllowedKey(event)) {
		event.preventDefault();
	} else {
		if (event.keyCode != 8) {
			if(element.value.length > 14) {
				var position = element.selectionStart;
				element.value = element.value.replace(/\W/gi, '').replace(/^(.{4})(.{4})(.{4})(.*)$/, "$1 $2 $3 $4");
				if(element.value.length != 19) {
					element.setSelectionRange(position, position);
				}
			}
			else {
				element.value = element.value.replace(/\W/gi, '').replace(/(.{4})/g, '$1 ');
			}
		}
	}		
}

function isAllowedKey(event) {
	var allowed = false;
	if (event.keyCode === 8 || event.keyCode === 9 || event.keyCode === 37 || event.keyCode === 39) {
		allowed = true;
	}
	return allowed;
}

function limit(event, element, max_chars) {
	if(isTextSelected(element)){																		//
		max_chars += 1;
	}
	if (element.value.length >= max_chars && !isAllowedKey(event)) {
		event.preventDefault();
	}
}

function showCardValue() {
	document.getElementById("cardNo").value = document.getElementById("cardNoSafe").value;
}

function isTextSelected(input) {
	var startPosition = input.selectionStart;
	var endPosition = input.selectionEnd;

	var selObj = document.getSelection();
	var selectedText = selObj.toString();

	if (selectedText.length != 0) {
		input.focus();
		input.setSelectionRange(startPosition, endPosition);
		return true;
	} else if (input.value.substring(startPosition, endPosition).length != 0) {
		input.focus();
		input.setSelectionRange(startPosition, endPosition);
		return true;
	}
	return false;
}

function hideCardValue(val) {
	document.getElementById("cardNoSafe").value = val;
	var len = val.length;
	if (len >= 14) {
		const regex = /\d{4}(?= \d{1})/g;
		const substr = "****";
		document.getElementById("cardNo").value = val.replace(regex, substr);
	}
}
<div class="form-group">
	<input name="AccountNo" id="cardNo" placeholder="Card Number" title="Card Number" class="form-control" onfocus="showCardValue()" onblur="hideCardValue(this.value)" onkeypress="formatCardNumber(event, this); limit(event, this, 19) " onpaste="return false" oncut="return false" tabindex="2" autocomplete="nope" type="text">
<span class="placeholder-text" style="display: none;">Please enter Card Number</span>
<input name="cardNoSafe" id="cardNoSafe" value="" style="display:none;">
</div>

You can use:

str = str.replace(/\d(?=\d{4})/g, "*");

to mask all but last 4 digits in a given number of more than 4 digits.

RegEx Demo

Explanation:

  • This reges uses a positive lookahead (?=\d{4}) which means match should be followed by 4 digits.
  • \d matches a single digit with above lookahead condition and replaces that by *

If somebody has a card placeholder through space, like "4242 4242 4242 4242", then you have to use other regular expression: \d{4}(?= \d{4}) and replace on "****":

Full example:

str = str.replace(/\d{4}(?= \d{4})/g, "****");

It will replace card "4242 4242 4242 4242" as "**** **** **** 4242"

Test example


Here is a Javascript approach without the use of RegEx:

Check jsFiddle demo

var mainStr = '1234567891234567',
    vis = mainStr.slice(-4),
    countNum = '';

for(var i = (mainStr.length)-4; i>0; i--){
    countNum += '*';
}

alert(countNum+vis);