Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pasting multiple numbers over multiple input fields

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.

like image 251
flinx777 Avatar asked Aug 03 '12 22:08

flinx777


2 Answers

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

like image 50
Nope Avatar answered Nov 03 '22 00:11

Nope


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);
like image 24
relipse Avatar answered Nov 02 '22 22:11

relipse