0

I have simple code that will replace the characters in a string with '*' and only displays the last 4 characters of the string. Example:

string = 424242424242

Should become:

********4242

The code that does that is this:

var str = $('.cc').val();

var trailingCharsIntactCount = 4;
str = new Array(str.length - trailingCharsIntactCount + 1).join('*') + str.slice( -trailingCharsIntactCount);

$('.cc').val(str);

Now, I need to reverse that when the users focus on an input field. This is a working fiddle:

https://jsfiddle.net/s66k9x1s/1/

Basically, I need to show/hide the input's value the same way I demonstrated in my fiddle.

Could someone please advice on how I can achieve this?

1
  • 1
    You can't really reverse it. You need to save the original value somewhere. Commented Oct 8, 2017 at 8:54

2 Answers 2

2

The string replacement cannot be reversed from thin air, you need to save the original value somewhere. You could use jQuery's .data(), for example. Store the original value with .data('value', str), and when the field receives the focus, restore it from .data('value').

function getMaskedValue(str) {
  var trailingCharsIntactCount = 4;
  return new Array(str.length - trailingCharsIntactCount + 1).join('*') + str.slice(-trailingCharsIntactCount);
}

var $cc = $('.cc');
var str = $cc.val();
$cc.data('value', str);

$cc
  .val(getMaskedValue(str));
  .focus(function() {
    $(this).val($(this).data('value'));
  });

And as @aaron pointed out, after focus is lost, you also want to restore the masked value:

$cc
  .focus(function() {
    $(this).val($(this).data('value'));
  })
  .blur(function() {
    str = $(this).val();
    $(this).data('value', str);
    $(this).val(getMaskedValue(str));
  });

He is also right that you don't need .data(), you could store the real value in a variable. It will be good to hide it within a closure. (See fiddle.)

(function() {
  function getMaskedValue(s) {
    var masklen = s.length - 4;
    return s.substr(0, masklen).replace(/./g, '*') + s.substr(masklen);
  }

  var $cc = $('.cc');
  var value = $cc.val();

  $cc
    .val(getMaskedValue(value))
    .focus(function() {
      $(this).val(value);
    })
    .blur(function() {
      value = $(this).val();
      $(this).val(getMaskedValue(value));
    });
})();

I also simplified the implementation of computing the masked value, which should perform better, eliminating array operations.

Sign up to request clarification or add additional context in comments.

Comments

2

Leave the original value in str. Here's a clean and simple answer that includes re-hide on blur:

var cc = $('.cc');
var str;
var trailingCharsIntactCount = 4;

function getHiddenValue() {
  str = cc.val();
  return new Array(str.length - trailingCharsIntactCount + 1).join('*') + str.slice(-trailingCharsIntactCount);
}

cc.val(getHiddenValue());
cc.focus(function() { cc.val(str); });
cc.blur(function() { cc.val(getHiddenValue()); });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.