简体   繁体   中英

Auto Selecting the next Input field and going Back

Once inputed, a user can't go back to change their input.

 $("form").on("keyup change paste", function(e) { e.preventDefault(); var a = $(this).find("input[type='text'].a"); var b = $(this).find("input[type='text'].b"); var c = $(this).find("input[type='text'].c"); var d = $(this).find("input[type='text'].d"); var e = $(this).find("input[type='text'].e"); var f = $(this).find("input[type='text'].f"); a.val(a.val().replace(/[^0-9]/g, "")); b.val(b.val().replace(/[^0-9]/g, "")); c.val(c.val().replace(/[^0-9]/g, "")); d.val(d.val().replace(/[^0-9]/g, "")); e.val(e.val().replace(/[^0-9]/g, "")); f.val(f.val().replace(/[^0-9]/g, "")); if (a.val().length == a.attr('maxlength')) { a.next("input").focus(); } if (b.val().length == a.attr('maxlength')) { b.next("input").focus(); } if (c.val().length == a.attr('maxlength')) { c.next().next("input").focus(); } if (d.val().length == a.attr('maxlength')) { d.next("input").focus(); } if (e.val().length == a.attr('maxlength')) { e.next("input").focus(); } if (f.val().length == a.attr('maxlength')) { f.next("input").focus(); } });
 input { width: 20px; text-align: center; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form name="code" action="*" method="post" autocomplete="off"> <input type="text" name="code" maxlength="1" autocomplete="off" class="a"> <input type="text" name="code" maxlength="1" autocomplete="off" class="b"> <input type="text" name="code" maxlength="1" autocomplete="off" class="c"> <span>—</span> <input type="text" name="code" maxlength="1" autocomplete="off" class="d"> <input type="text" name="code" maxlength="1" autocomplete="off" class="e"> <input type="text" name="code" maxlength="1" autocomplete="off" class="f last"> </form>

How can that be done?

And is there a more elegant approach to mine above?


Live: jsFiddle

Any time you find yourself finding very repetitious code, always think LOOP.

The below will allow the user to edit their values. It also greatly reduces your code.

$('form').on('input', e => {
    var letters = ['a', 'b', 'c', 'd', 'e', 'f'];
    letters.forEach(letter => {
        let field = $(e.target);
        field.val(field.val().replace(/[^0-9]/g, ''));
        if(field.val().length == field.attr('maxlength')) { field.nextAll('input').first().focus(); }
    });
});

Fiddle .

Notes:

  • Listen for the input event; it has the advantage of covering all the events you were listening for, and, crucially, fires after keypress (meaning you can be sure of grabbing the latest, complete value from the field)
  • avoid repetitious code; the loop allows us to write the business logic once rather than repeatedly
  • there is no need to prevent the event's default action
  • by using nextAll('input').first() , we can be sure of getting the next input , whether it's the next sibling or, as is the case with the third input, separated by another type of element

My idea would be to focus next, and loop when arriving at the last one. Replace the number in case of a new entry.

 // init the html const nbInput = 6; let html = ''; for (let i = 0; i < nbInput; i += 1) { html += `<input type="text" name="code" maxlength="1" autocomplete="off" number="${i}">`; } $('form').html(html); $('form input').on('keypress', function(e) { e.preventDefault(); // Ignore bad values if (/^[^0-9]$/g.test(String.fromCharCode(e.which))) { return; } // Replace the actual value with the keypressed one $(this).val(String.fromCharCode(e.which)); // Reset & focus next if ($(this).val() !== '' && Number($(this).attr('number')) < (nbInput - 1)) { $(`input[number=${Number($(this).attr('number')) + 1}]`).focus(); } else { // Focus the first item when we finished $('input[number="0"]').focus(); } });
 input { width: 20px; text-align: center; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form name="code" action="*" method="post" autocomplete="off"> </form>

Clearing the inputs on focus would do it. (I don't use jQuery much, so apologies if I have any incorrect syntax.)

$("form").focus(function() {

    var a = $(this).find("input[type='text'].a")
    var b = $(this).find("input[type='text'].b") // ...etc  

    a.val("");
    b.val(""); // ...etc
});

That said, Utkanos is 100% correct that a loop is the right way to handle both issues (auto-advancing and allowing edits).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM