Move cursor to next element on enter keeping track of tabindex - javascript

I am using following code to move to next element. Code is working fine except for the tabindex=-1. It does not skip elements with tabindex set to -1.
$('body').on('keydown', 'input, select', function(e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
I have been searching for the solution but could not find one.
Can anyone please help.

You focus specificly the next element, you don't let the browser handle it. Therefor the tabindex=-1 is not working.
To use the tabindex you specified in the HTML you have to specify it in the Javascript aswell ( :not([tabindex="-1"]) ) :
focusable = form.find('input,a,select,button,textarea').filter(':not([tabindex="-1"]):visible');

Related

How do i target or focus drop-down li which is active when a input is focused

JQUERY
$(".share-drop .dropdown-notif").keydown(function (e) {
e.preventDefault();
$(this).parents('.share').find('.share-drop .dropdown-notif').show();
if ($(this).val() == '') {
$('.share-drop .dropdown-notif').hide();
}
if (e.which == 40) {
var next = $('.selected').removeClass('selected').next('li');
next = next.length > 0 ? next : $('.focus li:eq(0)');
next.addClass('selected').children('a').focus();
} else if (e.which == 38) {
var prev = $('.selected').removeClass('selected').prev('li');
prev = prev.length > 0 ? prev : $('.focus li').last();
prev.addClass('selected').children('a').focus();
}
});
I have a drop-down option which will trigger on a keyup function of input text. I need to select those options using my up and down arrow keys I have been trying this using keydown where i couldn't able to move further. Can anyone help me with this. Thanks in advance.
Here is the DEMO
I made a couple of changes to your fiddle and it started working for the up and down key after you do some typing; eg type 'te' then press up and down:
http://jsfiddle.net/c9U3s/2/
The keydown event binding needs to be on the input element itself, and you need to allow preventDefault:
$(".input-hold input").keydown(function (e) {
//e.preventDefault();
and you need an initial selected class somewhere, for your logic to then sucessfully kick in, so I added this to the HTML:
<li class="selected"><a>testmail#test.com</a>
I think there's a couple more bug to step through, (eg what happens when you reach the end of the list with the down key?), but this will hopefully get you started.
This shows you how you can control the scrollTop of the dropdown, so you can scroll to view selected elements:
http://jsfiddle.net/c9U3s/3/
but again, some work needed to refine it to be truly nice.

Focusing to the .next() td textbox in a table row using jQuery

I want to be able to press tab once the .editbox is clicked and it take the focus to the next .editbox. I have been messing with the code for an hour now and cannot "find" the next element.
Here is my code to do it. For help you will likely need more context. I made a jsfiddle to elaborate on what I am dealing with.
//on tab
$(".edit_tr").on('keydown', '.editbox', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var focus = $(document.activeElement);
//console.log(focus);
focus.closest('td').siblings('.editbox').focus();
console.log(focus.parent().next('.editbox'));
}
});
On line #41 you have to go with:
focus.closest('td').next().find(".editbox").show().focus();
This will go back to the current td, look for the following td tag, search for .editbox and before you can focus() on it you have to show() it (make it visible) first.
This solution will only work for 1 line. If you want to move between different lines with the tab key you'll have to do the following:
var nextEditbox = focus.closest('td').next().find(".editbox");
//check if there are still .editboxes on the same line
if(nextEditbox.length){
//go for it and focus the next edit box on the same line
nextEditbox.show().focus();
}
else {
//move to the next line and search for the next editbox
nextEditbox = focus.closest('tr').next().find(".edit_td:first").find(".editbox");
//show and focus
nextEditbox.show().focus();
}
//this will end the focusing and the .change() (which is defined above) will fire and do the ajax
focus.blur();
You'll have to do the hiding of the .text elements yourself.
Edit: Here's the Savebutton-Solution. I didn't test it, but I think it should work.
var changes = [];
$(".editbox").change(function(){
changes.push({ id : $(this).attr("id"), changed : $(this).attr("name"), data : $(this).val() });
});
$(".savebutton").click(function(){
//AJAX SENDING THE changes VAR TO THE PHP FILE
});
It seems that
$(".edit_tr").on('keydown', '.editbox', function(e) {
Should be
$(".edit_td").on('keydown', '.editbox', function(e) {
Besides, JQuery editTable may meets your requirements.

Accordion like form, will not work for me, can anyone see what i've done wrong here?

I'm make a rather long form, and I want to be able to break the form down into tabbable section, then when leaving that last input/select box, the next section will slide open, while the previous slides shut. I'm also wantning to have the fieldset legend, clickable to achieve the same thing.
A good example of what I'm looking for can be found here: http://jsfiddle.net/s4vcX/
Here is what I'm currently working with: http://jsfiddle.net/AUf3U/
If you'd like, you can see the current JavaScript code here:
$("fieldset label").hide();
$("fieldset ul").hide();
$("fieldset:first label").show();
// show when legend is clicked while hiding rest
$("legend").bind("click", function () {
$("fieldset label").not($(this).nextAll("label")).hide();
$(this).nextAll("label").show();
});
//handle shift-tab on first input of each field set
$("fieldset").find("input:first").bind("keydown", function (e) {
if( e.shiftKey && e.which == 9 ) {
$(this).closest(".hidesfieldset").find("label").hide();
var previous = $(this).closest(".hidesfieldset").prev(".hidesfieldset");
if(previous.length==0)
previous = $(this).closest("form").find(".hidesfieldset:last");
previous.find("label").show();
previous.find("input").last().focus();
e.preventDefault();
}
});
//handle tab on last input of each field set
$("fieldset").find("input:last").bind("keydown", function (e) {
if( !e.shiftKey && e.which == 9 ) {
$(this).closest(".hidesfieldset").find("label").hide();
var next = $(this).closest(".hidesfieldset").next(".hidesfieldset");
if(next.length==0)
next = $(this).closest("form").find(".hidesfieldset:first");
next.find("label").show();
next.find("input").first().focus();
e.preventDefault();
}
});
If someone can point out what`s going wrong here, I would be incredibly greatful, this has become a huge pain in the ass, and have to impelment this across about 50 forms, so changing the structure of my form is not necessarily a good thing.
The problem is your input selector, since you are using element selector it selects only elements with tag input but in your first fieldset the last element is a select element.
Try to use the :input selector
//handle shift-tab on first input of each field set
$("fieldset").find(":input:last").bind("keydown", function (e) {
if (e.shiftKey && e.which == 9) {
$(this).closest(".hidesfieldset").find("label").hide();
var previous = $(this).closest(".hidesfieldset").prev(".hidesfieldset");
if (previous.length == 0) previous = $(this).closest("form").find(".hidesfieldset:last");
previous.find("label").show();
previous.find("input").last().focus();
e.preventDefault();
}
});
//handle tab on last input of each field set
$("fieldset").find(":input:last").bind("keydown", function (e) {
if (!e.shiftKey && e.which == 9) {
$(this).closest(".hidesfieldset").find("label").hide();
var next = $(this).closest(".hidesfieldset").next(".hidesfieldset");
if (next.length == 0) next = $(this).closest("form").find(".hidesfieldset:first");
next.find("label").show();
next.find(":input").first().focus();
e.preventDefault();
}
});
Demo: Fiddle

Why when I press GO in iPad, does not focus next input?

Imagine that I have many div in display: none; and just the first one is in visible.
In the view, you can navigate through each one pressing a ENTER or GO (in an iPad). So when you want to advance, change the current div to none, and the next one change it to visible. But right now I wanna also set the focus in an input element where has a focusable class. But it does not set the focus.
Here is my code:
var setFocus = function () {
$("#question-container2").find("#question:visible").find('.focusable')[0].focus();
$("#question-container2").find("#question:visible").find('.focusable')[0].setSelectionRange(0, 0);
};
var nextPage = function () {
if ($currentPage < $totalPages) {
$currentPage++;
$("#question-container2").find("#question:visible").hide().next().show();
}
};
$(".input-area").keypress(function (e) {
if (e.keyCode == 13) {
// Do something
nextPage();
setFocus();
return false;
}
});
Specify a tab index in your elements. This is a browser accessibility attribute which will tell the browser where to navigate to next when you are done with the current field.
See: http://reference.sitepoint.com/html/a/tabindex

prepare to focus first active element in a container

I have a container on a page that should be prepared for focusing, i.e. when user pressed TAB button, the first active element in the container must be focused.
The simplest way I have thought so far is to find the last active element before the container, focus it and then blur it. Will it work? Is there a simpler way? How to find the last active element before the container (cross-browser)?
I do not want to change tabbed elements order, I just want to define the next element that will be selected.
Please use raw javascript, not frameworks.
The only thing I can think of is looping over the container child nodes and try focusing them until you succeed:
<script type="text/javascript">
document.onkeyup = function (e) {
if (!e)
e = window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
FocusFirst(document.getElementById("MyContainer"));
}
}
function FocusFirst(element) {
try {
element.focus();
}
catch(ex) {}
if (document.activeElement == element)
return true;
for (var i = 0; i < element.childNodes.length; i++) {
var oChild = element.childNodes[i];
if (FocusFirst(oChild))
return true;
}
return false;
}
</script>
Sample HTML tested with: (IE, Chrome)
<div id="MyContainer">
<div>hello</div>
<div><span><input type="text" /></span></div>
<div><input type="text" /></div>
</div>
This will focus the first input box of the container upon tab click.
Add a listener to the document and change focus onKeyUp. Remove the listener once tab has been pressed:
document.onkeyup = onKeyEvent;
function onKeyEvent (e) {
if (e.keyCode == 9) {
document.onkeyup = null;
document.getElementById ('whatever').focus();
}
}
Here is the solution that I've used finally.
I just create fake empty link in the beginnig of the container and focus it. The link will be removed when it lose focus.
function prefocusElement(node)
{
var fake = document.createElement("a");
fake.setAttribute("href", "#");
node.insertBefore(fake, node.firstChild);
fake.focus();
fake.addEventListener("blur", function(e) { node.removeChild(fake); }, false);
};

Categories