Reputation: 11760
I have two groups and I want to separate navigation for them and on last tab control of the group when tab key is pressed then the iteration cycle should be restarted and the focus should move to the initial element of the group (which would be the 0 index)
In given below Example I have added two groups and in the group I have added some text-boxes and assigned not serial order.
Problems
Note: I am making an angularjs app and this is just a dummy to provide a clear view of my problem
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div role="group" tabindex="-1">
<h1>Group 1</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="6" />
<br>
<input type="text" tabindex="4" />
<br>
<input type="text" tabindex="2" />
<br>
<input type="text" tabindex="5" />
<br>
<input type="text" tabindex="2" />
<br>
<button tabindex="7">Submit</button>
</div>
<hr>
<div>
<div role="group" tabindex="-1">
<h1>Group 2</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="6" />
<br>
<input type="text" tabindex="4" />
<br>
<input type="text" tabindex="2" />
<br>
<input type="text" tabindex="5" />
<br>
<input type="text" tabindex="2" />
<br>
<button tabindex="7">Submit</button>
</div>
</div>
</body>
</html>
Upvotes: 5
Views: 12187
Reputation: 11760
Many thanks @Kiran Nawaleand @Gökhan Kurt for guiding me to the solution.
I have created a generic directive which is reusable for any angular app.
Dependencies
In directive I have added comments which will guide you through the way the directive is working.
How to use?
Add the given below attributes and the directive in your element
tab-man tab-index="0" tab-group="g1"
tab-man : the directive
tab-index : it is the index of the element in the group
tab-group : name of the group
Note:
There should always be a 0
index in every group otherwise the cycle will not restart.
If any index is skipped like 0,1,2,4...
(3
is skipped) then after 2 the focus move to 0
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script>
var app = angular.module('myapp', []); /// angular app
app.directive('tabMan', function() { ///directive
return {
restrict: 'A', /// accessible only by attribute
scope: {}, /// scope is not needed
link: function(scope, element, attrs) { ///link function to add key-down event on the target element
var gotoElement = function(grp, idx) {
/// get next element
var nextElement = $("input[tab-group='" + grp + "'][tab-index='" + idx + "']")[0];
/// if there is not next element then go to the 0 index
if (nextElement == undefined) {
if (idx != 0) { /// if the index is 0 then do not do any thing
gotoElement(grp, 0); /// restart the cycle
}
} else {
nextElement.focus(); /// succesfully give focus to the next
}
};
var tabIndex = attrs.tabIndex;
var tabGroup = attrs.tabGroup;
$(element).keydown(function(event) {
if (event.keyCode == 9) { /// go inside if tab key is pressed
var tIdx = $(event.target).attr("tab-index"); /// get the current index of element
var nextTid = parseInt(tIdx.toString()) + 1; /// get the next index of element
nextTid = Number(nextTid); /// turn the index into number
var tGrp = $(event.target).attr("tab-group"); /// get the group of the element
gotoElement(tGrp, nextTid); /// go to the next element
/// the work of tab is done by the directive so remove the default and stop the bubbeling
event.stopPropagation()
event.preventDefault();
}
});
}
};
});
</script>
</head>
<body ng-app="myapp">
<div role="group" tabindex="-1">
<h1>Group 1</h1>
<br>
<input type="text" tab-man tab-index="0" tab-group="g1" />
<br>
<input type="text" tab-man tab-index="5" tab-group="g1" />
<br>
<input type="text" tab-man tab-man tab-index="2" tab-group="g1" />
<br>
<input type="text" tab-man tab-index="3" tab-group="g1" />
<br>
<input type="text" tab-man tab-index="4" tab-group="g1" />
<br>
<input type="text" tab-man tab-index="1" tab-group="g1" />
<br>
<button>Submit</button>
</div>
<hr>
<div>
<div role="group" tabindex="-1">
<h1>Group 2</h1>
<br>
<input type="text" tab-man tab-index="0" tab-group="g2" />
<br>
<input type="text" tab-man tab-index="5" tab-group="g2" />
<br>
<input type="text" tab-man tab-man tab-index="2" tab-group="g2" />
<br>
<input type="text" tab-man tab-index="3" tab-group="g2" />
<br>
<input type="text" tab-man tab-index="4" tab-group="g2" />
<br>
<input type="text" tab-man tab-index="1" tab-group="g2" />
<br>
<button>Submit</button>
</div>
</div>
</body>
Upvotes: 5
Reputation: 8277
tabindex works globally in a window. You can achieve what you want with javascript. Your groups must have a class "closedFocus" and your elements should have a tabIndex. You can change the code to achieve the effect you want:
$(".closedFocusGroup [tabindex]").on("keydown", function(e) {
if (e.which == 9) {
var parentGroup = this.closest(".closedFocusGroup");
var allChildren = $(parentGroup).find("[tabindex]");
allChildren.sort(function(a,b){ return a.tabIndex-b.tabIndex});
var thisIndex = allChildren.index(this);
var nextIndex = (thisIndex + 1) % allChildren.length;
var nextItem = allChildren[nextIndex];
if (nextItem) nextItem.focus();
e.preventDefault();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div role="group" class="closedFocusGroup" tabindex="-1">
<h1>Group 1</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="6" />
<br>
<input type="text" tabindex="4" />
<br>
<input type="text" tabindex="2" />
<br>
<input type="text" tabindex="5" />
<br>
<input type="text" tabindex="2" />
<br>
<button tabindex="7">Submit</button>
</div>
<hr>
<div>
<div role="group" class="closedFocusGroup" tabindex="-1">
<h1>Group 2</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="6" />
<br>
<input type="text" tabindex="4" />
<br>
<input type="text" tabindex="2" />
<br>
<input type="text" tabindex="5" />
<br>
<input type="text" tabindex="2" />
<br>
<button tabindex="7">Submit</button>
</div>
</div>
Upvotes: 1
Reputation: 11
Unfortunately, you can't do that without JavaScript.
Here I have implemented the JavaScript/jQuery code to handle tabbing between two groups.
Also please make a note that For moving to the second group you/user have to decide when to move to second group of inputs.
HTML
<div id="group-1" role="group" tabindex="0">
<h1>Group 1</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="button" value="submit" tabindex="1" />
<div id="focusguard-1" tabindex="1"></div>
</div>
<hr>
<div>
<div id="group-2" role="group" tabindex="0">
<h1>Group 2</h1>
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="text" tabindex="1" />
<br>
<input type="button" value="submit" tabindex="1" />
<div id="focusguard-2" tabindex="1"></div>
</div>
</div>
JavaScript/JQuery
$('#focusguard-1').on('focus', function() {
$('#group-1 input:first').focus();
});
$('#focusguard-2').on('focus', function() {
console.log("Focus in");
$('#group-2 input:first').focus();
});
Upvotes: 1