【问题标题】:Pasting multiple numbers over multiple input fields在多个输入字段上粘贴多个数字
【发布时间】:2012-08-01 23:52:14
【问题描述】:

我的网站上有一个使用 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]">

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

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

【问题讨论】:

标签: javascript jquery html forms webforms


【解决方案1】:

编辑

我不喜欢我在paste 事件中使用的计时器解决方案以及仅使用inputpaste 事件的复杂性。

看了一会儿之后,我添加了一个使用 2 之间混合的解决方案。 代码似乎完成了现在需要的所有工作。

脚本:

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])
    });
};​

DEMO

【讨论】:

    【解决方案2】:

    这是一个 jquery 插件的示例,它与原始答案做同样的事情,只是泛化了。

    我竭尽全力将原始答案(http://jsfiddle.net/D7jVR/)修改为一个 jquery 插件,源代码在这里:https://github.com/relipse/jquery-pastehopacross/blob/master/jquery.pastehopacross.js

    jsfiddle 上的一个例子如下: http://jsfiddle.net/D7jVR/111/

    截至 2013 年 4 月 4 日的来源如下:

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

    【讨论】:

      【解决方案3】:

      这应该不会太难...在第一个 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]);
          }
      });
      

      【讨论】:

      • 哦,我应该提到的一件事:我是一个 js 菜鸟,所以不完全确定如何做到这一点。你有什么例子吗?
      • @flinx777 抱歉,这是一个肮脏的谎言……这不是很简单。请查看我的更新。
      • @dbaseman:您不能多次粘贴。例如粘贴123456,而不是345678。一旦值在框中,粘贴将被忽略。
      • 使用新的剪贴板,在第一个框中选择值 1,然后按 Ctrl+V。 Chrome@Ubuntu 在这里工作。
      • @Niloct:通过选择值然后粘贴你正在替换它,然后它会正常工作,我说的是当你将插入符号放在当前的后面或前面的框中值(不选择或删除它)并粘贴:)
      【解决方案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]);
         }
      });
      

      【讨论】:

        【解决方案5】:

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

        正如 dbasemane 所建议的,您可以监听粘贴事件。您也可以监听 keyup 事件,以允许用户输入数字而无需切换到下一个输入。

        这是一种可能的解决方案:

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

        我在 jsfiddle 上设置了这段代码,所以你可以看看它是如何运行的:http://jsfiddle.net/hallettj/Kcyna/

        【讨论】:

        猜你喜欢
        • 2020-01-28
        • 2011-12-23
        • 2020-07-11
        • 1970-01-01
        • 2021-09-01
        • 2019-10-18
        • 2012-02-07
        • 1970-01-01
        • 2012-06-30
        相关资源
        最近更新 更多