Javascript 在输入的每 4 个字符后插入破折号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11632525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert dash after every 4th character in input
提问by mrchad
I want insert a dash after every 4th character in input. I have a credit card input box. When a user is typing and reaches each 4th character, then jQuery will insert a hyphen (-
).
我想在输入的每 4 个字符后插入一个破折号。我有一个信用卡输入框。当用户输入并到达每个第 4 个字符时,jQuery 将插入一个连字符 ( -
)。
For example: 1234-5678-1234-1231
例如: 1234-5678-1234-1231
UPDATE:I'm trying some codes and i think i'm so close to correct code but i have some problems. Here is my code sample;
更新:我正在尝试一些代码,我认为我非常接近正确的代码,但我有一些问题。这是我的代码示例;
$('.creditCardText').keyup(function() {
var cardValue = $('.creditCardText').val(),
cardLength = cardValue.length;
if ( cardLength < 5 ) {
if ( cardLength % 4 == 0 ) {
console.log('4 lük geldi');
cardValue += "-";
$('.creditCardText').val(cardValue);
}
} else {
if ( cardLength % 5 == 0 ) {
console.log('5 lük geldi');
cardValue += "-";
$('.creditCardText').val(cardValue);
}
}
});
采纳答案by RecursivelyIronic
This jquery extension will insert a space every four characters: https://github.com/stripe/jquery.payment
这个 jquery 扩展将每四个字符插入一个空格:https: //github.com/stripe/jquery.payment
回答by Nick
I absolutely love this plugin for automatic formatting: here.
我非常喜欢这个用于自动格式化的插件: 这里.
So long as you're already using JQuery, that is.
只要您已经在使用 JQuery,那就是。
You could easily force the dashes in with a single line of code, like follows:
您可以使用一行代码轻松地强制使用破折号,如下所示:
$("#credit").mask("9999-9999-9999-9999");
When the user types in the field, the dashes will automatically appear in the right spot, and they will not be able to delete them.
当用户在该字段中键入时,破折号将自动出现在正确的位置,他们将无法删除它们。
In addition, you can accommodate for different lengths or formats of credit cards with the ?
character in your mask. For example, to accept inputs of 14 and 16 digits, you would do the following:
此外,您可以使用?
面具中的字符来适应不同长度或格式的信用卡。例如,要接受 14 位和 16 位数字的输入,您可以执行以下操作:
$("#credit").mask("9999-9999-9999-99?99");
Do keep in mind that this is only a client side validation
请记住,这只是客户端验证
Edit: The mask plugin assumes that there is one, or finitely many, correct formats for the field. For example, there are only a few formats that credit card numbers come in. The plugin is there to ensure that your input will onlybe in one of those formats.
编辑:掩码插件假定该字段有一种或有限多种正确格式。例如,信用卡号码只有几种格式。该插件可确保您的输入仅采用其中一种格式。
So technically, if you want a dash after every four digits, but for anynumber of digits, then this plugin is not right for you.
所以从技术上讲,如果你想在每四位数字后加一个破折号,但对于任意数量的数字,那么这个插件不适合你。
I would suggest you restrict the possible inputs to be reasonable, as there is certainly no such thing as a 1000-digit long credit card. But if you really want that functionality, you'll have to write the script yourself or find another plugin. As of this time I'm not aware of one.
我建议您将可能的输入限制为合理,因为肯定没有 1000 位长信用卡这样的东西。但是,如果您真的想要该功能,则必须自己编写脚本或寻找其他插件。截至目前,我不知道一个。
回答by Lucas
I've fixed up your code, but still strongly suggest server validation andusing four text boxes, and smartly switching between them:
我已经修复了您的代码,但仍然强烈建议服务器验证并使用四个文本框,并在它们之间巧妙地切换:
$('.creditCardText').keyup(function() {
var foo = $(this).val().split("-").join(""); // remove hyphens
if (foo.length > 0) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
$(this).val(foo);
});
回答by rap-2-h
Based on @think123 answer, in vanilla JS, without JQuery:
基于@think123 的答案,在 vanilla JS 中,没有 JQuery:
document.querySelector('.creditCardText').addEventListener('input', function (e) {
var foo = this.value.split("-").join("");
if (foo.length > 0) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
this.value = foo;
});
I know the question is about JQuery but I think this answer could help too.
我知道这个问题是关于 JQuery 的,但我认为这个答案也有帮助。
回答by pmrotule
If you are looking for a pure Javascript solution, look at my function below. It supports the American Express format (15 digits) as well as Visa, MasterCard and others (16 digits).
如果您正在寻找纯 Javascript 解决方案,请查看下面我的函数。它支持 American Express 格式(15 位)以及 Visa、MasterCard 等(16 位)。
Watch out for the simple solutions that will replace the whole value and always put the focus at the end of the input: it can be annoying if the user edits what he previously entered.
注意将替换整个值并始终将焦点放在输入末尾的简单解决方案:如果用户编辑他之前输入的内容,可能会很烦人。
DEMO: https://jsfiddle.net/pmrotule/217u7fru/
演示:https: //jsfiddle.net/pmrotule/217u7fru/
input_credit_card = function(input)
{
var format_and_pos = function(char, backspace)
{
var start = 0;
var end = 0;
var pos = 0;
var separator = "-";
var value = input.value;
if (char !== false)
{
start = input.selectionStart;
end = input.selectionEnd;
if (backspace && start > 0) // handle backspace onkeydown
{
start--;
if (value[start] == separator)
{ start--; }
}
// To be able to replace the selection if there is one
value = value.substring(0, start) + char + value.substring(end);
pos = start + char.length; // caret position
}
var d = 0; // digit count
var dd = 0; // total
var gi = 0; // group index
var newV = "";
var groups = /^\D*3[47]/.test(value) ? // check for American Express
[4, 6, 5] : [4, 4, 4, 4];
for (var i = 0; i < value.length; i++)
{
if (/\D/.test(value[i]))
{
if (start > i)
{ pos--; }
}
else
{
if (d === groups[gi])
{
newV += separator;
d = 0;
gi++;
if (start >= i)
{ pos++; }
}
newV += value[i];
d++;
dd++;
}
if (d === groups[gi] && groups.length === gi + 1) // max length
{ break; }
}
input.value = newV;
if (char !== false)
{ input.setSelectionRange(pos, pos); }
};
input.addEventListener('keypress', function(e)
{
var code = e.charCode || e.keyCode || e.which;
// Check for tab and arrow keys (needed in Firefox)
if (code !== 9 && (code < 37 || code > 40) &&
// and CTRL+C / CTRL+V
!(e.ctrlKey && (code === 99 || code === 118)))
{
e.preventDefault();
var char = String.fromCharCode(code);
// if the character is non-digit
// OR
// if the value already contains 15/16 digits and there is no selection
// -> return false (the character is not inserted)
if (/\D/.test(char) || (this.selectionStart === this.selectionEnd &&
this.value.replace(/\D/g, '').length >=
(/^\D*3[47]/.test(this.value) ? 15 : 16))) // 15 digits if Amex
{
return false;
}
format_and_pos(char);
}
});
// backspace doesn't fire the keypress event
input.addEventListener('keydown', function(e)
{
if (e.keyCode === 8 || e.keyCode === 46) // backspace or delete
{
e.preventDefault();
format_and_pos('', this.selectionStart === this.selectionEnd);
}
});
input.addEventListener('paste', function()
{
// A timeout is needed to get the new value pasted
setTimeout(function(){ format_and_pos(''); }, 50);
});
input.addEventListener('blur', function()
{
// reformat onblur just in case (optional)
format_and_pos(this, false);
});
};
input_credit_card(document.getElementById('credit-card'));
回答by Su Ming Yuan
By modifying the suggestion of @think123and @TheStoryCoder, I added selectionStart and SelectionEnd for cursor. After that increase cursor position at suitable place and modify the cursor position. It should solve the cursor position is at not as expected position.
通过修改@think123和@TheStoryCoder的建议,我为光标添加了 selectionStart 和 SelectionEnd 。然后在合适的地方增加光标位置并修改光标位置。它应该解决光标位置不在预期的位置。
$('.creditCardText').keyup(function() {
var ss, se, obj;
obj = $(this);
ss = obj[0].selectionStart;
se = obj[0].selectionEnd;
var curr = obj.val();
var foo = $(this).val().split("-").join(""); // remove hyphens
if (foo.length > 0) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
if(( (curr.length % 5 == 0) && ss == se && ss == curr.length ) || (ss == se && (ss % 5 == 0))){
ss += 1;
se += 1;
}
if (curr != foo){
$(this).val(foo);
obj[0].selectionStart = ss;
obj[0].selectionEnd = se;
}
});
回答by Brajinder Singh
All others who have answered above me are right and their code is definitely short and neat, but is a bit advance, in the sense that they are either using regular expressions or a plugin. Something like this can also be achieved with basic js/jquery, which, judging from your sample code you are trying to achieve. As this question is around 3 years old, you must've gotten what you had wanted by now, but yes, you were close.. This is what you should have tried:
在我上面回答的所有其他人都是对的,他们的代码绝对简短而整洁,但有点超前,因为他们要么使用正则表达式,要么使用插件。这样的事情也可以通过基本的 js/jquery 来实现,从你试图实现的示例代码来看。由于这个问题是 3 岁左右,你现在一定已经得到了你想要的,但是,你已经接近了..这是你应该尝试的:
//Html
/* <input type="text" class="creditCardText" maxlength="19" /> */
$('.creditCardText').keyup(function () {
var cctlength = $(this).val().length; // get character length
switch (cctlength) {
case 4:
var cctVal = $(this).val();
var cctNewVal = cctVal + '-';
$(this).val(cctNewVal);
break;
case 9:
var cctVal = $(this).val();
var cctNewVal = cctVal + '-';
$(this).val(cctNewVal);
break;
case 14:
var cctVal = $(this).val();
var cctNewVal = cctVal + '-';
$(this).val(cctNewVal);
break;
default:
break;
}
});
回答by tnkh
You can achieved with vanilla JS and do not require plugin to do that. Refer to the code below. You can change the var split
to suit your needs. Credits to https://webdesign.tutsplus.com/tutorials/auto-formatting-input-value--cms-26745.
您可以使用 vanilla JS 来实现,并且不需要插件来做到这一点。请参考下面的代码。您可以更改var split
以适合您的需要。归功于https://webdesign.tutsplus.com/tutorials/auto-formatting-input-value--cms-26745。
(function($, undefined) {
"use strict";
// When ready.
$(function() {
var $form = $( "#form" );
var $input = $form.find( "input" );
$input.on( "keyup", function( event ) {
console.log('sss')
// When user select text in the document, also abort.
var selection = window.getSelection().toString();
if ( selection !== '' ) {
return;
}
// When the arrow keys are pressed, abort.
if ( $.inArray( event.keyCode, [38,40,37,39] ) !== -1 ) {
return;
}
var $this = $(this);
var input = $this.val();
input = input.replace(/[\W\s\._\-]+/g, '');
var split = 4;
var chunk = [];
for (var i = 0, len = input.length; i < len; i += split) { chunk.push( input.substr( i, split ) );
}
console.log(chunk)
$this.val(function() {
return chunk.join("-");
});
} );
/**
* ==================================
* When Form Submitted
* ==================================
*/
$form.on( "submit", function( event ) {
var $this = $( this );
var arr = $this.serializeArray();
for (var i = 0; i < arr.length; i++) {
arr[i].value = arr[i].value.replace(/[($)\s\._\-]+/g, ''); // Sanitize the values.
};
console.log( arr );
event.preventDefault();
});
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form" method="post" action="">
<label for="number">Enter number</label>
<div class="flex">
<input id="number" name="number" type="text" maxlength="15" />
</div>
</form>