Как получить правильное значение при редактировании маскированного ввода (пользовательская маскировка) - PullRequest
1 голос
/ 03 октября 2019

У меня есть два входа (замаскированный и немаскированный) и кнопка переключения, которая служит кнопкой для показа / скрытия. Он работает аналогично маскировке пароля, за исключением того, что он маскирует только определенные символы в строке. Что бы я ни вводил в текстовое поле unmasked, вызывается функция createMask, а результат отображается в текстовом поле masked.

Проблема заключается в том, что отображается замаскированное текстовое поле, и я редактируюзначение, оно должно обновить значение в немаскированном текстовом поле.

Например, 12345678 -> 1XXXX678

Затем я отредактирую 1XXXX678 в 1XXXX619

Когда я нажимаю кнопку, чтобы снять маску, она должна показывать 12345619

Для лучшего понимания вот полный код: jsfiddle

1 Ответ

0 голосов
/ 03 октября 2019

Вы можете сохранить реальное значение в атрибуте данных входного элемента, таким образом, у вас будет единственный источник правды.

Пока вы переключаетесь, вы можете получить это реальное значение и отобразить маскированный / немаскированный.

Также вам необходимо иметь состояние, которое маскируется / не маскируется, поэтому при обновлении значений вы знаете, что немаскированные значения могут напрямую заменять значение, а маскированное значение будет только первой буквой и остальными буквами, которые вы должны выбратьобласть маскирования от последнего известного значения

Теперь, когда в маскированном состоянии пользователь изменяет любое из значений X, которое я дал функции, если это 'XXXX', оно примет старое значение, если что-либо еще попытаетсяобновить значение. Я сохранил позицию курсора, где находится пользователь. Если вы хотите проявить творческий подход, вы можете поработать над логикой здесь.

$(function() {
  $('#SSN').on('input', function(e) {
    const this$ = $(this);
    const val = $(this).val();

    if (this$.data('unmask')) {
      this$.data('val', val);
    } else {
      const oldParams = getMask(this$.data('val'), false);
      const newParams = getMask(val, false);
      const newMaskArea = getUpdatedMaskArea(e.target.selectionStart, oldParams.maskArea, newParams.maskArea);
      const newValue = newParams.first + newMaskArea + newParams.rest;
      this$.data('val', newValue);
    }
  }).on('blur', function() {
    const this$ = $(this);
    this$.val(getMask(this$.data('val'), !this$.data('unmask')).value);
  }).data('val', $(this).val())

  $('#toggle').on('click', toggle).trigger('click');
});

function toggle() {
  $(this).find('i').toggleClass('fa-eye-slash');
  $('#SSN').data('unmask', !$(this).find('i').hasClass('fa-eye-slash')).trigger('blur');
}

function getUpdatedMaskArea(position, oldMask, newMask){
  if(position>=2 && position<=5){
    if(newMask.indexOf('X')===-1){
      return newMask;// user input new value
    } else if(newMask.length === oldMask.length){
      return newMask.replace(/X/g, (v,i)=>oldMask.charAt(i));//user updates 'X'
    } else {
      //when there are less than desired X ? I am not sure how to handle this
    }
  }
  return oldMask;
}

function getMask(val, mask) {
  const first = val.substring(0, 1);
  const maskArea = val.substring(1, 5);
  const rest = val.substring(5, val.length);
  const value = first + (mask ? maskArea.replace(/./g, 'X') : maskArea) + rest;
  return {first, maskArea, rest, value};
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="div">
  <input id="SSN" maxlength="8">
  <button id="toggle" type="submit">
    <i class="fa fa-eye"></i>
  </button>
</div>
...