编辑屏蔽输入时如何获得正确的值(自定义屏蔽)
How to get the correct value when a masked input is edited(custom masking)
我有两个输入(屏蔽和未屏蔽)和一个用作 show/hide 按钮的切换按钮。它的工作原理与密码屏蔽类似,只是它只屏蔽字符串中的某些字符。无论我在 unmasked
文本框中输入什么,都会调用 createMask
函数,结果显示在 masked
文本框中。
问题是,当显示屏蔽文本框并编辑值时,它应该更新未屏蔽文本框中的值。
例如,12345678
-> 1XXXX678
然后我会把1XXXX678
编辑成1XXXX619
当我点击按钮取消屏蔽时,它应该显示 12345619
为了更好地理解,这里是完整的代码:jsfiddle
您可以将实际值存储在输入元素的数据属性中,这样您就有了单一的真实来源。
当您切换时,您可以获取实际值并显示 masked/unmasked。
你还需要有一个 masked/unmasked 的状态,所以当你更新值时,你知道未屏蔽的值可以直接替换为值,屏蔽的值将只是第一个字母,其余的字母你必须从最后一个已知值中选择蒙版区域
现在,当处于屏蔽状态的用户更改任何 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>
我有两个输入(屏蔽和未屏蔽)和一个用作 show/hide 按钮的切换按钮。它的工作原理与密码屏蔽类似,只是它只屏蔽字符串中的某些字符。无论我在 unmasked
文本框中输入什么,都会调用 createMask
函数,结果显示在 masked
文本框中。
问题是,当显示屏蔽文本框并编辑值时,它应该更新未屏蔽文本框中的值。
例如,12345678
-> 1XXXX678
然后我会把1XXXX678
编辑成1XXXX619
当我点击按钮取消屏蔽时,它应该显示 12345619
为了更好地理解,这里是完整的代码:jsfiddle
您可以将实际值存储在输入元素的数据属性中,这样您就有了单一的真实来源。
当您切换时,您可以获取实际值并显示 masked/unmasked。
你还需要有一个 masked/unmasked 的状态,所以当你更新值时,你知道未屏蔽的值可以直接替换为值,屏蔽的值将只是第一个字母,其余的字母你必须从最后一个已知值中选择蒙版区域
现在,当处于屏蔽状态的用户更改任何 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>