Reputation: 172
I have many forms on a website and I'd like to use jQuery to transverse so that when you press PgUp / PgDn it will go to the next <textarea>
field. I got it working when the <textarea>
's were siblings, but if they're in a separate form (with different parents) I can't figure it out.
The HTML is like:
<form action="#" method="post">
<textarea id="numOne" name="numOne" class="num" ></textarea>
</form>
<form action="#" method="post">
<textarea id="numtwo" name="numtwo" class="num" ></textarea>
</form>
<form action="#" method="post">
<textarea id="numthree" name="numthree" class="num" ></textarea>
</form>
This worked when they were siblings:
$('.num').keydown(function (e) {
if (e.which == 34) {
$(this).next().focus();
e.preventDefault();
return false;
}
if (e.which == 33) {
$(this).prev().focus();
e.preventDefault();
return false;
}
});
Upvotes: 4
Views: 82
Reputation: 206121
$('.num').keydown(function (e) {
if (e.which == 34) {
$(this).closest('form').next('form').find('.num').focus();
return false;
}
if (e.which == 33) {
$(this).closest('form').prev('form').find('.num').focus();
return false;
}
});
As you can see I used .closest('form')
it will allow you one day to use your textarea
inside a fieldset
without taking care of the jQuery, cause it'll always traverse the DOM the right way.
Another nice way: DEMO
$('.num').keydown(function (e) {
var k = e.which;
if ( k==34 || k==33 ){
$(this).closest('form')[k==34?'next':'prev']('form').find('.num').focus();
e.preventDefault();
}
});
Another nice DEMO
var $num = $('.num').keydown(function(e) {
var k=e.which, c=$num.index(this);
if(k==34||k==33) $num[k==34?++c:--c].focus();
});
Let's go through the last one:
var $num = $('.num') // Create a jQuery Array collection
// of all the .num in the DOM.
.keydown(function(e) { // On keydown pass the (e)vent.
var k=e.which, // Var k is now the "which keyCode"
c=$num.index(this); // Var c will be the index of the clicked
// element taken from the collection.
if(k==34||k==33) // Only IF pgUp/pgDn
$num[k==34?++c:--c] // increment or decrement c and get that el.
// out of the array ( e.g: $num[1] )
.focus(); // and set focus to it.
});
Upvotes: 1
Reputation: 318212
You should use the collection of elements to get the next and previous elements, that way the DOM structure doesn't matter and you can nest the elements any way you like :
var elems = $('.num');
elems.on('keydown', function (e) {
var n = e.which === 34 ? 1 : e.which === 33 ? -1 : 0,
next = elems.eq(elems.index(this) + (n));
if (n) {
e.preventDefault();
next.length ? next.focus() : elems.first().focus();
}
});
Upvotes: 2
Reputation: 86240
You can use .index
and .eq
to perform next/prev searches on a selector. In this case, we look at all textareas on the page, and figure out which one we're currently in, say the 22nd textarea. Then we either select the 21st or 23rd textarea, and focus it.
This is more robust than other solutions which rely on the DOM structure. This simply relies on the DOM order. It can further be refined by changing $('textarea')
to $('#scope textarea')
where scope is the highest parent you wish to look inside.
If your HTML will be changing (new or removed textarea
s) then don't cache the result as I did. However, it improves performance if your HTML won't be changing in this area.
var $textareas = $('textarea');
$('.num').keydown(function (e) {
if (e.which == 34) {
var index = $textareas.index(this)
$textareas.eq(index + 1).focus();
e.preventDefault();
return false;
}
if (e.which == 33) {
var index = $textareas.index(this)
$textareas.eq(index - 1).focus();
e.preventDefault();
return false;
}
});
Upvotes: 1