2

I have a bootstrap form where I want to set the focus to the next 'enabled' input element upon pressing enter key. When I press enter in Barcode input element, I want to set the focus to the Quantity input element since it is the next enabled input element.

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div class="row"> <div class="col-3 pr-0"> <div class="form-group"> <label for="txtBarcode">Barcode</label> <input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm"> </div> </div> <div class="col-7 pl-2 pr-0"> <div class="form-group"> <label for="txtPartDesc">Description</label> <input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled> </div> </div> <div class="col-2 pl-2"> <div class="form-group"> <label for="txtUom">UoM</label> <input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled> </div> </div> </div> <div class="row"> <div class="col-4 pr-0"> <div class="form-group"> <label for="txtQuantity">Quantity</label> <input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm"> </div> </div> </div>

What I have tried so far is:

$(":input").keydown(function(event){ if (event.keyCode === 13) { $(this).nextAll(':input:enabled').first().focus(); } }); 

But this doesn't work as I expect.

1
  • .nextAll only looks at siblings, not the whole HTML Commented Nov 11, 2018 at 6:40

3 Answers 3

3

next(), nextAll(), and the other similar methods are for finding siblings. Since none of your inputs are actual siblings this will not work.

What you can do however is:

  1. Get a jQuery object of all the enabled inputs

    var enabledInputs = $("input:enabled"); 
  2. Get the index of the current input in that jQuery object using index()

    var idx = enabledInputs.index(this); 
  3. Then using that index get the element at index+1 using eq()

    enabledInputs.eq(idx+1).focus(); 

Demo

$(":input").keydown(function(event){ if (event.keyCode === 13) { var enabledInputs = $("input:enabled"); var idx = enabledInputs.index(this); enabledInputs.eq(idx+1).focus() } });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div class="row"> <div class="col-3 pr-0"> <div class="form-group"> <label for="txtBarcode">Barcode</label> <input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm"> </div> </div> <div class="col-7 pl-2 pr-0"> <div class="form-group"> <label for="txtPartDesc">Description</label> <input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled> </div> </div> <div class="col-2 pl-2"> <div class="form-group"> <label for="txtUom">UoM</label> <input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled> </div> </div> </div> <div class="row"> <div class="col-4 pr-0"> <div class="form-group"> <label for="txtQuantity">Quantity</label> <input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm"> </div> </div> </div>

Sign up to request clarification or add additional context in comments.

1 Comment

I was amazed by the prompt response I got. Thank you a lot... It worked.
0

The next input is not a sibling of the #barcode input, so nextAll won't work at that point. Try navigating to the parent's parent, the div class="col-, and then use nextAll to recursively search through that parent's siblings until a matching element is found:

$(":input").keydown(function(event) { if (event.keyCode !== 13) return; $(this) .parent() .parent() // get to the `class=col-#` element .nextAll(':input:enabled') .first() .focus(); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" /> <div class="row"> <div class="col-3 pr-0"> <div class="form-group"> <label for="txtBarcode">Barcode</label> <input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm"> </div> </div> <div class="col-7 pl-2 pr-0"> <div class="form-group"> <label for="txtPartDesc">Description</label> <input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled> </div> </div> <div class="col-2 pl-2"> <div class="form-group"> <label for="txtUom">UoM</label> <input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled> </div> </div> </div> <div class="row"> <div class="col-4 pr-0"> <div class="form-group"> <label for="txtQuantity">Quantity</label> <input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm"> </div> </div> </div>

1 Comment

Thank you for your response. @Patrick's answer worked 'Out of the box' . Anyway I am studying your input as well since I am new to js world (Y)
0

If I understand your question correctly then one solution to this problem is to update your keydown() handler like so:

 if (event.keyCode === 13) { // Get all enabled inputs in the document var inputs = $('input:enabled'); // Iterate all inputs, searching for the index of the "next" input to "this" for(var i = 0; i < inputs.length; i++) { // If the "global" index of "this" input is found if( $(inputs).eq(i).is( $(this) ) ) { // Then select the "next" input by incrementing the index, and call // focus on that input if it exists inputs.eq(i + 1) .css({ border : '1px solid red' }) // Added to help visualise focus, remove this line .focus(); // Exit the loop now that focus has been called on "next" input break } } } 

The idea here is to select the next input element based on the order that they occur in the DOM, rather than to select the next input element based on adjacent siblings to the input that "enter" is pressed. This solution also corrects a few minor errors in your code's selector syntax. Here's a working demo:

$("input").keydown(function(event){ if (event.keyCode === 13) { var inputs = $('input:enabled'); for(var i = 0; i < inputs.length; i++) { if( $(inputs).eq(i).is( $(this) ) ) { inputs.eq(i + 1) .css({ border : '1px solid red' }) // Added to help visualise focus, remove this line .focus() break } } } });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/> <div class="row"> <div class="col-3 pr-0"> <div class="form-group"> <label for="txtBarcode">Barcode</label> <input type="text" id="txtBarcode" name="barcode" class="form-control form-control-sm"> </div> </div> <div class="col-7 pl-2 pr-0"> <div class="form-group"> <label for="txtPartDesc">Description</label> <input type="text" id="txtPartDesc" name="part_desc" value="" class="form-control form-control-sm" disabled> </div> </div> <div class="col-2 pl-2"> <div class="form-group"> <label for="txtUom">UoM</label> <input type="text" id="txtUom" name="barcode" value="" class="form-control form-control-sm" disabled> </div> </div> </div> <div class="row"> <div class="col-4 pr-0"> <div class="form-group"> <label for="txtQuantity">Quantity</label> <input type="text" id="txtQuantity" name="barcode" class="form-control form-control-sm"> </div> </div> </div>

2 Comments

Thank you for your response. @Patrick's answer worked 'Out of the box' . Anyway I am studying your input as well since I am new to js world (Y)
@LakmalPremaratne hey you're welcome! Hope this is of some help to you in your learning :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.