Pasting multiple numbers over multiple input fields

19,532

Solution 1

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

Solution 2

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);

Solution 3

This shouldn't be too difficult ... add a handler for the paste event on the first input, and then process per the requirement.

Edit

Actually this is much trickier than I thought, because it seems there's no way to get what text was pasted. You might have to kind of hack this functionality in, using something like this (semi-working)... (see the 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]);
    }
});

Solution 4

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]);
   }
});
Share:
19,532
flinx777
Author by

flinx777

Updated on June 27, 2022

Comments

  • flinx777
    flinx777 almost 2 years

    I've got a form on my site using 6 input fields. The site visitor simply enters a 6 digit code into these 6 boxes. The thing is that they'll get the 6 digit code and it would be ideal to allow them to simply copy the 6 digit code we send them into these input fields by simply putting pasting into the first input field and having the remaining 5 digits go into the remaining 5 input fields. It would just make it much easier than having to manually enter each digit into each input field.

    Here's the code we're currently using, but it can easily be changed to accomplish what is described above:

    <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]">
    

    I saw a posting similar to this here: Pasting of serialnumber over multiple textfields

    But it doesn't have the solution I'm looking for. Ideally this could be pulled off using jQuery or plain JavaScript.