7

我的网站上有一个使用 6 个输入字段的表单。网站访问者只需在这 6 个框中输入一个 6 位代码。问题是他们将获得 6 位代码,理想的做法是让他们简单地将我们发送给他们的 6 位代码复制到这些输入字段中,只需将粘贴到第一个输入字段并让剩下的 5 位数字去进入剩余的 5 个输入字段。它只会比手动将每个数字输入每个输入字段更容易。

这是我们当前使用的代码,但可以很容易地对其进行更改以完成上述内容:

<input type="text" maxlength="1" class="def-txt-input" name="chars[1]">
<input type="text" maxlength="1" class="def-txt-input" name="chars[2]">
<input type="text" maxlength="1" class="def-txt-input" name="chars[3]">
<input type="text" maxlength="1" class="def-txt-input" name="chars[4]">
<input type="text" maxlength="1" class="def-txt-input" name="chars[5]">
<input type="text" maxlength="1" class="def-txt-input" name="chars[6]">

我在这里看到了类似的帖子:Pasing of serialnumber over multiple textfields

但它没有我正在寻找的解决方案。理想情况下,这可以使用 jQuery 或纯 JavaScript 实现。

4

5 回答 5

10

Edit

I didn't like the timer solution I used in the paste event and the complexity of just using the input or paste event.

After looking at this for a while I added a solution which uses a hybrid between the 2. The code seems to do all that is required now.

The Script:

var $inputs = $(".def-txt-input");
var intRegex = /^\d+$/;

// Prevents user from manually entering non-digits.
$inputs.on("input.fromManual", function(){
    if(!intRegex.test($(this).val())){
        $(this).val("");
    }
});


// Prevents pasting non-digits and if value is 6 characters long will parse each character into an individual box.
$inputs.on("paste", function() {
    var $this = $(this);
    var originalValue = $this.val();

    $this.val("");

    $this.one("input.fromPaste", function(){
        $currentInputBox = $(this);

        var pastedValue = $currentInputBox.val();

        if (pastedValue.length == 6 && intRegex.test(pastedValue)) {
            pasteValues(pastedValue);
        }
        else {
            $this.val(originalValue);
        }

        $inputs.attr("maxlength", 1);
    });

    $inputs.attr("maxlength", 6);
});


// Parses the individual digits into the individual boxes.
function pasteValues(element) {
    var values = element.split("");

    $(values).each(function(index) {
        var $inputBox = $('.def-txt-input[name="chars[' + (index + 1) + ']"]');
        $inputBox.val(values[index])
    });
};​

See DEMO

于 2012-08-03T23:21:03.027 回答
3

Here is an example of a jquery plugin that does the same thing as the original answer only generalized.

I went to great lengths to modify the original answer ( http://jsfiddle.net/D7jVR/ ) to a jquery plugin and the source code is here: https://github.com/relipse/jquery-pastehopacross/blob/master/jquery.pastehopacross.js

An example of this on jsfiddle is here: http://jsfiddle.net/D7jVR/111/

The source as of 4-Apr-2013 is below:

/**
 * PasteHopAcross jquery plugin
 * Paste across multiple inputs plugin, 
 * inspired by http://jsfiddle.net/D7jVR/
 */
(function ($) {
    jQuery.fn.pastehopacross = function(opts){ 
       if (!opts){ opts = {} }
        if (!opts.regexRemove){
            opts.regexRemove = false;   
        }
        if (!opts.inputs){
           opts.inputs = [];   
        }
        if (opts.inputs.length == 0){
            //return 
            return $(this);   
        }

        if (!opts.first_maxlength){
            opts.first_maxlength = $(this).attr('maxlength');
            if (!opts.first_maxlength){
                return $(this);
            }
        }

       $(this).on('paste', function(){

           //remove maxlength attribute
           $(this).removeAttr('maxlength'); 
           $(this).one("input.fromPaste", function(){
               var $firstBox = $(this);

                var pastedValue = $(this).val();
                if (opts.regexRemove){
                     pastedValue = pastedValue.replace(opts.regexRemove, "");
                }

                var str_pv = pastedValue;
                $(opts.inputs).each(function(){
                    var pv = str_pv.split('');
                    var maxlength;
                    if ($firstBox.get(0) == this){
                       maxlength = opts.first_maxlength;   
                    }else{
                       maxlength = $(this).attr('maxlength'); 
                    }
                    if (maxlength == undefined){
                        //paste them all!
                        maxlength = pv.length;   
                    }
                    //clear the value
                    $(this).val('');
                    var nwval = '';           
                    for (var i = 0; i < maxlength; ++i){
                        if (typeof(pv[i]) != 'undefined'){
                           nwval += pv[i];
                        }
                    }
                    $(this).val(nwval);
                    //remove everything from earlier
                    str_pv = str_pv.substring(maxlength);
                });

                //restore maxlength attribute
                $(this).attr('maxlength', opts.first_maxlength);
            });    

       });

       return $(this);
    }
})(jQuery);
于 2013-04-05T03:18:18.540 回答
2

这应该不会太难......在第一个input上为paste事件添加一个处理程序,然后根据要求进行处理。

编辑

实际上这比我想象的要棘手得多,因为似乎没有办法获得粘贴的文本。您可能不得不使用类似这样的东西(半工作)......(参见JSFiddle)来破解这个功能。

$(document).on("input", "input[name^=chars]", function(e) {
    // get the text entered
    var text = $(this).val();

    // if 6 characters were entered, place one in each of the input textboxes
    if (text.length == 6) {
        for (i=1 ; i<=text.length ; i++) {
            $("input[name^=chars]").eq(i-1).val(text[i-1]);
        }    
    }
    // otherwise, make sure a maximum of 1 character can be entered
    else if (text.length > 1) {
        $(this).val(text[0]);
    }
});
于 2012-08-03T22:31:11.600 回答
1

HTML

<input id="input-1" maxlength="1" type="number" />
<input id="input-2" maxlength="1" type="number" />
<input id="input-3" maxlength="1" type="number" />
<input id="input-4" maxlength="1" type="number" />

jQuery

$("input").bind("paste", function(e){
   var pastedData = e.originalEvent.clipboardData.getData('text');
   var num_array = [];
   num_array = pastedData.toString(10).replace(/\D/g, '0').split('').map(Number); // creates array of numbers
   for(var a = 0; a < 4; a++) {  // Since I have 4 input boxes to fill in
     var pos = a+1;
     event.preventDefault();
     $('#input-'+pos).val(num_array[a]);
   }
});
于 2020-04-13T06:22:24.970 回答
0

您将不得不纠正一些自定义代码。您可能必须删除 maxlength 属性并使用 javascript 来强制每个输入一个数字的限制。

As dbasemane suggests, you can listen for a paste event. You can listen to keyup events too to allow the user to type out numbers without having to switch to the next input.

Here is one possible solution:

function handleCharacter(event) {
    var $input = $(this),
        index = getIndex($input),
        digit = $input.val().slice(0,1),
        rest = $input.val().slice(1),
        $next;

    if (rest.length > 0) {
        $input.val(digit);  // trim input value to just one character
        $next = $('.def-txt-input[name="chars['+ (index + 1) +']"]');

        if ($next.length > 0) {
            $next.val(rest);  // push the rest of the value into the next input
            $next.focus();
            handleCharacter.call($next, event);  // run the same code on the next input
        }
    }
}

function handleBackspace(event) {
    var $input = $(this),
        index = getIndex($input),
        $prev;

    // if the user pressed backspace and the input is empty
    if (event.which === 8 && !$(this).val()) {
        $prev = $('.def-txt-input[name="chars['+ (index - 1) +']"]');
        $prev.focus();
    }
}

function getIndex($input) {
    return parseInt($input.attr('name').split(/[\[\]]/)[1], 10);
}

$('.def-txt-input')
    .on('keyup paste', handleCharacter)
    .on('keydown', handleBackspace);

I have this code set up on jsfiddle, so you can take a look at how it runs: http://jsfiddle.net/hallettj/Kcyna/

于 2012-08-03T23:07:55.470 回答