AngularJS navigate Image Carousel with arrow keys - javascript

I have an image carousel built in AngularJS that navigates via two A tags used as buttons with ng-click. I would like to allow the user to also use the arrow keys to navigate left and write. I have found a few examples using ng-keypress, or ng-keyup/keydown, but they all require an input tag to have focus.
I found a solution to get around this, which sets up a keyup event on the $rootScope, which listens for key events.
app.directive('keypressEvents',
function ($document, $rootScope) {
return {
restrict: 'A',
link: function () {
console.log('linked');
$document.bind('keyup', function (e) {
$rootScope.$broadcast('keyup', e, e.keyCode);
});
}
}
});
/////////ARROW KEY SHORTCUTS
$scope.key = 'none'
$rootScope.$on('keyup', function (evt, obj, key) {
$scope.$apply(function () {
$scope.key = key;
//left
if(key == 37) {
///need here to somehow be aware of the current slide index
}
//right
if(key == 39) {
}
});
})
This works, but I cannot figure out how to link these events to the image carousel which knows about the index of the image and performs the logic of showing the next or previous.
//IMAGE CAROUSEL
//sets the current index to 0, the start
$scope.currentSlideIndex = 0;
//allows us to change the index by passing this function a new index
$scope.setCurrentSlideIndex = function (index) {
$scope.currentSlideIndex = index;
};
//returns a boolean value as to whether the current index matches whatever we pass this function
$scope.isCurrentSlideIndex = function (index) {
return $scope.currentSlideIndex === index;
};
$scope.prevSlide = function (text) {
$scope.single = text;
console.log("prevSlide Pressed: ", text.title)
$scope.currentSlideIndex = ($scope.currentSlideIndex < $scope.results.length - 1) ? ++$scope.currentSlideIndex : 0;
};
$scope.nextSlide = function (text) {
$scope.single = text;
console.log("Next Pressed: ", text.title)
$scope.currentSlideIndex = ($scope.currentSlideIndex > 0) ? --$scope.currentSlideIndex : $scope.results.length - 1;
};
html
<div id="Carousel" class = "col-sm-12 col-md-9" ng-show = "results.length < 8 || singleChosen">
<div ng-show="!singleChosen" class="slider">
<div ng-show="!detail">
<div ng-repeat="text in texts | filter: multiFilter as results " ng-hide="!isCurrentSlideIndex($index)">
<img class = "nonDraggableImage slide " ng-src="{{text.large}}" alt="{{text.large}}">
<div keypress-events></div>
<a class="arrow prev" href="#/text" ng-click="nextSlide(results[($index+1)%results.length])"></a>
<a class="arrow next" href="#/text" ng-click="prevSlide((results[(($index-1)<0?results.length-1:$index-1)]))"></a>
</div>
</div>
Is there not a way to just use ng-keyup within the a tags with the ng-click?
something like this
<a class="arrow prev" href="#/text" ng-keyup="$event.keyCode === 37
&& nextSlide(results[($index+1)%results.length])"
ng-click="nextSlide(results[($index+1)%results.length])"></a>

solved with a new directive:
placed logic in the directive, linking scope in
app.directive('arrowNavigate',['$document',function($document){
return{
restrict:'A',
link:function(scope){
$document.bind('keydown',function(e){
if(e.keyCode == 37){
console.log(scope.currentSlideIndex);
scope.currentSlideIndex = (scope.currentSlideIndex < scope.results.length - 1) ? ++scope.currentSlideIndex : 0;
scope.$apply();
e.preventDefault();
}
if(e.keyCode == 39){
console.log(scope.currentSlideIndex);
scope.currentSlideIndex = (scope.currentSlideIndex > 0) ? --scope.currentSlideIndex : scope.results.length - 1;
scope.$apply();
e.preventDefault();
}
});
}
};
}]);

Related

AngularJS focusing elements

I have the following situation:
<input type="text" ng-model="search" />
<div ng-hide="!search.length || selected ">
<ul>
<li ng-repeat="poster in tasks| poster: search track by $index" ng-click="handleSelection(poster)" style="cursor:pointer" ng-class="{active:isCurrent($index)}" ng-mouseenter="setCurrent($index)">
{{poster}}
</li>
</ul>
</div>
This all works fine and the list with the "suggested" items comes out as it should, however I would like when the user reaches certain point and presses arrow down to be able to jump to the suggested list then press enter which will populate the search box and close the suggest list.
I have tried to create a directive that binds to keydown and listen to key code, lets say 40 ( arrow down ), however even when I add tabindex to the LI elements i am not able to set focus on them. Even further I am assuming i need to know the length of the LI's so when the user reaches the last element it just stops. Same logic for going up.
thanks in advance!
EDIT: I got it, I was failing to see this entire time that there is no spoon. How about this?
<input type="text" ng-model="search" ng-keydown="selected=false" ng-keypress="keyChanged($event);" />
<div ng-hide="!search.length || selected ">
<ul>
<li ng-repeat="poster in (filteredResults = (tasks | poster: search)) track by $index" ng-click="handleSelection(poster)" style="cursor:pointer" ng-class=" {active:isCurrent($index+1)}" ng-mouseenter="setCurrent($index+1)">
{{poster}}
</li>
</ul>
</div>
set global
current = 1;
and in the controller like this :
$scope.handleSelection = function( item ) {
$scope.search = item;
$scope.selected = true;
}
$scope.isCurrent = function( index ) {
if( index === current ) {
return true;
}
else {
return false;
}
}
$scope.setCurrent = function( index ) {
current = index;
}
$scope.keyChanged = function( ev ) {
//going down
if( ev.keyCode == 40 && (current+1) <= $scope.filteredResults.length ) {
$scope.setCurrent( current + 1 );
}
//going up
if( ev.keyCode == 38 && (current-1) >= 1 ) {
$scope.setCurrent( current - 1 );
}
//press enter
if( ev.keyCode == 13 ) {
$scope.handleSelection( $scope.filteredResults[current-1]);
}
}
Works both with keyboard and a mouse and will stop and the first/last element.
I have omitted the filters because they are irrelevant to the current situation.
Solution 1:
Use typeahead: http://angular-ui.github.io/bootstrap/
Solution 2, if you really need it custom:
I'd like to know if there are shortcuts but meanwhile this is how my code looks like, those are code snippets and should take them as pseudo-code and adapt it for your own project:
In a service:
searchBoxData.onKeyUpAndDown = function(direction){
searchBoxData.selected_index += direction;
if(searchBoxData.selected_index < 0){
searchBoxData.selected_index = searchBoxData.displayedLength() - 1;
}else if(searchBoxData.selected_index > searchBoxData.displayedLength() - 1){
searchBoxData.selected_index = 0;
}
searchBoxData.selectContent();
};
In a directive
app.directive('fancyinput', [ "$rootScope", "SearchBoxData", function($rootScope, SearchBoxData) {
return {
restrict: "A",
link: function link(scope, element) {
scope.unbind_up_and_down = false;
scope.searchBoxData = SearchBoxData;
element.bind("keydown", function(e){
if(e.keyCode === 13){
scope.searchBoxData.submitQuery(e);
}else{
if ((e.keyCode === 38 || e.keyCode === 40) && scope.unbind_up_and_down === false) {
var direction = +1;
if (e.keyCode === 38){ direction = -1; }
$scope.searchBoxData.onKeyUpAndDown(direction);
}else{
// reset selection if typing
scope.$apply(function () { scope.searchBoxData.selected_index = 10000; });
scope.processBinding(e, this);
}
}
});
}
};
}]);
Let me know if you need anything else. I ll update my answer accordingly.

tabindex issue with select2

I am having an issue with the taborder on my form whilst using select2.
I have an input form that I want the user to be able to tab through in order.
I have been able to order the text input fields but not select2 dropdownlists.
It appears the issue is with them having a default tabindex="-1", as below;
> <div id="s2id_ctl00_MainContent_ddlAreaKept" class="select2-container
> form-control">
> <a class="select2-choice" tabindex="-1" onclick="return false;" href="javascript:void(0)">
> <input id="s2id_autogen4" class="select2-focusser select2-offscreen" type="text" tabindex="0">
> <div class="select2-drop select2-display-none select2-with-searchbox">
> </div>
> <select id="ctl00_MainContent_ddlAreaKept" class="form-control select2-offscreen" name="ctl00$MainContent$ddlAreaKept" tabindex="-1">
I have also written the following javascript to add tabIndex values to the fields but it isn't working how I'd like.
var tabOrder = 0;
document.getElementById("ctl00_MainContent_ddlAreaKept").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_ddlNCDYears").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtVehicleValue").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtAge").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtForename").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtSurname").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtEmail").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_txtPhoneNumber").tabIndex = tabOrder++;
document.getElementById("ctl00_MainContent_btnGetQuote").tabIndex = tabOrder++;
The dropdownlists don't get tabbed into, it skips them and goes through the textboxes as it should.
Any help much appreciated!
SOLVED : I tried:
var tabOrder = 1;
and this has solved the issue. I don't exactly know why or how :|
There is a solution in github, you can create a js file and then you include it under the call of select2, inside this new file you must paste this:
jQuery(document).ready(function($) {
var docBody = $(document.body);
var shiftPressed = false;
var clickedOutside = false;
//var keyPressed = 0;
docBody.on('keydown', function(e) {
var keyCaptured = (e.keyCode ? e.keyCode : e.which);
//shiftPressed = keyCaptured == 16 ? true : false;
if (keyCaptured == 16) { shiftPressed = true; }
});
docBody.on('keyup', function(e) {
var keyCaptured = (e.keyCode ? e.keyCode : e.which);
//shiftPressed = keyCaptured == 16 ? true : false;
if (keyCaptured == 16) { shiftPressed = false; }
});
docBody.on('mousedown', function(e){
// remove other focused references
clickedOutside = false;
// record focus
if ($(e.target).is('[class*="select2"]')!=true) {
clickedOutside = true;
}
});
docBody.on('select2:opening', function(e) {
// this element has focus, remove other flags
clickedOutside = false;
// flag this Select2 as open
$(e.target).attr('data-s2open', 1);
});
docBody.on('select2:closing', function(e) {
// remove flag as Select2 is now closed
$(e.target).removeAttr('data-s2open');
});
docBody.on('select2:close', function(e) {
var elSelect = $(e.target);
elSelect.removeAttr('data-s2open');
var currentForm = elSelect.closest('form');
var othersOpen = currentForm.has('[data-s2open]').length;
if (othersOpen == 0 && clickedOutside==false) {
/* Find all inputs on the current form that would normally not be focus`able:
* - includes hidden <select> elements whose parents are visible (Select2)
* - EXCLUDES hidden <input>, hidden <button>, and hidden <textarea> elements
* - EXCLUDES disabled inputs
* - EXCLUDES read-only inputs
*/
var inputs = currentForm.find(':input:enabled:not([readonly], input:hidden, button:hidden, textarea:hidden)')
.not(function () { // do not include inputs with hidden parents
return $(this).parent().is(':hidden');
});
var elFocus = null;
$.each(inputs, function (index) {
var elInput = $(this);
if (elInput.attr('id') == elSelect.attr('id')) {
if ( shiftPressed) { // Shift+Tab
elFocus = inputs.eq(index - 1);
} else {
elFocus = inputs.eq(index + 1);
}
return false;
}
});
if (elFocus !== null) {
// automatically move focus to the next field on the form
var isSelect2 = elFocus.siblings('.select2').length > 0;
if (isSelect2) {
elFocus.select2('open');
} else {
elFocus.focus();
}
}
}
});
docBody.on('focus', '.select2', function(e) {
var elSelect = $(this).siblings('select');
if (elSelect.is('[disabled]')==false && elSelect.is('[data-s2open]')==false
&& $(this).has('.select2-selection--single').length>0) {
elSelect.attr('data-s2open', 1);
elSelect.select2('open');
}
});
});
This work for me, if you want to know more: https://github.com/peledies/select2-tab-fix
© 2017 GitHub, Inc.
Terms
Privacy
Security
Status
Help
Contact GitHub
API
Training
Shop
Blog
About
focus it after select it!
$('.select2').on('select2:select', function (e) {
$(this).focus();
});
for your code replace .select2-offscreen with my .select2.
S F My English!
You could bind load event and trigger it on first time loaded
As you can see , the tabindex of the select control will become "3" instead of "-1"
$(document).ready(function() {
var $select2 = $("#tab2");
$select2.data('placeholder', 'Please Chhose').select2({
formatNoMatches: function (term) {
return 'No Match "' + term + '" Item';
},
allowClear: true
}).on("load", function(e) {
$(this).prop('tabindex',3);
}).trigger('load');
$("#tab1").prop('tabindex',4);
$("#tab3").prop('tabindex',2);
$("#tab4").prop('tabindex',1);
}
JSBIN
This code worked for me. I focus the first element in the modal:
$('#modalId').on('shown.bs.modal', function () {
$('#FirstElement').focus()
});
TabIndex Issue might happen after the form reset.
As per the documentation You may clear all current selections in a Select2 control by setting the value of the control to null:
$(selector).val(null).trigger("change");

How can I disable mouse hover effect when user is using keyboard?

I'm trying to implement a search as you type feature on my site. I'm working on the front-end side right now and using mockjax to pull in fake data.
My problem: When the drop down menu pops up you have the option to go over your choices (which highlight in yellow). I realized today though that if your using the arrow keys to scroll through your choices and move your mouse over the menu then it will cause two options to be highlighted! I don't want to confuse my users so I only want it to highlight one at a time. If they are using their keyboard and hover over with the mouse than the keyboard selection would jump to where the mouse is.
(In case I'm not being clear and you need an example, go to amazon and use their search with your arrow keys and then hover the mouse over an option, it changes. I want it like that!)
Most of the html, css and mockjax can't be included in this fiddle so it looks funky- but just case someone needs to see my code.
http://jsfiddle.net/2JGHu/
(function (Backbone, _, context) {
"use strict";
var SuggestiveSearch = Backbone.View.extend({
tracking: function (action, label) {
_gaq.push(['_trackEvent', 'SearchAsYouType2.0', action, label]);
},
fetchTemplate: function (name) {
var callback = _.bind(function (template) {
this.template = tmpl(template);
}, this);
$.get("/js/templates/" + name + ".html", callback);
},
close: function () {
this.$suggestionList.addClass("hide");
this.tracking('Close', 'Clicked-Off');
// Reset our list selection index
this.model.set("currentIndex", null);
},
open: function () {
this.$suggestionList.removeClass("hide");
this.tracking('Open', 'Clicked-On');
},
preventCloseHandler: function (e) {
e.stopPropagation();
},
directionSelectionHandler: function (keyCode) {
var currentIndex = this.model.get("currentIndex"),
incr = keyCode === 40 ? 1 : -1,
newIndex = currentIndex + incr,
choicesLen = this.$choices.length - 1,
isOutOfRange = newIndex > choicesLen || newIndex < 0;
// If index is out of range set it either to the first or last choice
if (isOutOfRange) {
newIndex = newIndex < 0 ? choicesLen : 0;
}
// Remove previous selected
// class on li's
this.$choices
.removeClass("is-selected");
this.$choices
.eq(newIndex)
.addClass("is-selected");
// Store our index
this.model.set("currentIndex", newIndex);
},
enterHandler: function (e) {
var currentIndex = this.model.get("currentIndex");
if (currentIndex !== 0) {
this.tracking('Enter', 'Selected-Choice');
window.location = this.$choices.eq(currentIndex).find("a").attr('href');
}
},
keyDownHandler: function (e) {
var keyCode = e.which,
isArrowKeys = keyCode === 40 || keyCode === 38;
if (!isArrowKeys) {
return;
}
e.preventDefault();
},
keyUpHandler: function (e) {
var $input = $(e.currentTarget),
query = $input.val(),
keyCode = e.which;
switch (keyCode) {
case 40:
case 38:
this.directionSelectionHandler(keyCode);
this.tracking('Keyboard navigate', 'Selected-Choice');
e.preventDefault();
break;
case 13:
this.enterHandler(e);
break;
default:
this.model.set("query", query);
}
},
choiceClickHandler: function (e) {
this.tracking('Click', 'Selected-Choice');
e.stopPropagation();
},
render: function () {
this.$suggestionList
.html(this.template(_.pick(this.model.attributes, "ProductSuggestions", "FilterSuggestions")));
// Store our list of choices but also add our already cached input to that collection
this.$choices = this.$suggestionList.find(".autocomplete__choice", this.$el).add(this.$input);
this.open();
},
events: {
"keyup input": "keyUpHandler",
"keydown input": "keyDownHandler",
"click .autocomplete__choice": "choiceClickHandler",
"click": "preventCloseHandler"
},
bindings: function () {
this.listenTo(this.model, "sync", this.render);
$(document).on('click', _.bind(this.close, this));
},
initialize: function () {
this.fetchTemplate("suggestions");
this.$suggestionList = this.$el.find(".autocomplete");
this.$input = this.$el.find("input");
this.bindings();
}
});
context.Views = context.Views || {};
context.Views.SuggestiveSearch = SuggestiveSearch;
}(Backbone, _, =|| {}));
Let me know if I need to include anymore information. Thank you in advance!
Since your JSFiddle doesn't produce the behavior, it's not easy for me to write code that solves your problem, but I can give you advice that might help you do it yourself.
The way I recommend solving this issue is by removing the .hover highlighting in your CSS and implementing a function that adds the class is-selected to an object when it is being hovered over and removing the class from all other elements. That way it will be compatible with your current directionSelectionHandler:

Tinyscrollbar and tab key interaction

How to solve the issue with tab key interaction with tinyscrollbar. When I press tab key to jump to input which is not in view, I get destroyed layout, scroll bars go away, etc. How to solve that?
This is what I have done: Add a tabindex attribute to the element, so that the element can receive focus state from the tab key or mouse click:
<div class="scroll-area" tabindex="1">
<div class="viewport">
<div class="overview">
… CONTENT …
</div>
</div>
<div class="scrollbar">
<span class="track"><span class="thumb"></span></span>
</div>
</div>
Next, I create this function inside the TinyScrollbar plugin to add keyboard support and enable the keyboard navigation on :focus:
$.fn.tinyscrollbar = function(params) {
var options = $.extend({}, $.tiny.scrollbar.options, params),
$this = this;
$this.each(function() {
$(this).data('tsb', new Scrollbar($(this), options));
// Enable keyboard support on focus
$this.on('focus', function () {
$(this).on('keydown', function (e) {
if (e.keyCode == 38 || e.keyCode == 37) {
$(this).tinyscrollbar_keystep(40); // step 40px on single keypress
return false;
} else if (e.keyCode == 40 || e.keyCode == 39) {
$(this).tinyscrollbar_keystep(-40); // step -40px on single keypress
return false;
}
});
});
});
return $this;
};
Then, create .tinyscrollbar_keystep() for updating the scroll step below the .tinyscrollbar_update():
$.fn.tinyscrollbar_update = function(sScroll) {
return $(this).data('tsb').update(sScroll);
};
// Add this functionality for scroll update on keypress (in this case)
$.fn.tinyscrollbar_keystep = function(sScroll) {
return $(this).data('tsb').keystep(sScroll);
};
And .keystep function after initialize()
function initialize() { … }
this.keystep = function(sScroll) {
if (oContent.ratio < 1) {
iScroll -= sScroll;
iScroll = Math.min((oContent[options.axis] - oViewport[options.axis]), Math.max(0, iScroll));
oThumb.obj.css(sDirection, iScroll / oScrollbar.ratio);
oContent.obj.css(sDirection, - iScroll);
}
};
Demo: http://jsbin.com/zaqogidexese/1/edit
I have similar situation here and this is my solution for form input fields:
$(document).on('keydown',function(e) {
switch (e.keyCode ? e.keyCode : e.which) {
case 9: // Tab
if (e.target.localName == 'input') {
content.tinyscrollbar_update($(e.target).position().top);
}
break;
}
});
if you have any wrapper element for each input, update the ".position().top" to ".parent().position().top"

Cycle Focus to First Form Element from Last Element & Vice Versa

I have created a form with malsup's Form Plugin wherein it submits on change of the inputs. I have set up my jQuery script to index drop down menus and visible inputs, and uses that index to determine whether keydown of tab should move focus to the next element or the first element, and likewise with shift+tab keydown. However, instead of moving focus to the first element from the last element on tab keydown like I would like it to, it moves focus to the second element. How can I change it to cycle focus to the actual first and last elements? Here is a live link to my form: http://www.presspound.org/calculator/ajax/sample.php. Thanks to anyone that tries to help. Here is my script:
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
var shiftDown = false;
$('input, select').each(function (i) {
$(this).data('initial', $(this).val());
});
$('input, select').keyup(function(event) {
if (event.keyCode==16) {
shiftDown = false;
$('#shiftCatch').val(shiftDown);
}
});
$('input, select').keydown(function(event) {
if (event.keyCode==16) {
shiftDown = true;
$('#shiftCatch').val(shiftDown);
}
if (event.keyCode==13) {
$('#captured').val(event.target.id);
} else if (event.keyCode==9 && shiftDown==false) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var nextEl = fields.eq(index+1).attr('id');
var firstEl = fields.eq(0).attr('id');
var focusEl = '#'+firstEl;
if (index>-1 && (index+1)<fields.length) {
$('#captured').val(nextEl);
} else if(index+1>=fields.length) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(firstEl);
} else {
event.preventDefault();
$(focusEl).focus();
}
}
return false;
});
} else if (event.keyCode==9 && shiftDown==true) {
return $(event.target).each(function() {
var fields = $(this).parents('form:eq(0),calculator').find('select, input:visible');
var index = fields.index(this);
var prevEl = fields.eq(index-1).attr('id');
var lastEl = fields.eq(fields.length-1).attr('id');
var focusEl = '#'+lastEl;
if (index<fields.length && (index-1)>-1) {
$('#captured').val(prevEl);
} else if (index==0) {
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(lastEl);
} else {
event.preventDefault();
$(focusEl).select();
}
}
return false;
});
}
});
});
});
function setFocus() {
with (document.calculator)
var recap = document.getElementById(recaptured.value);
if (recap!=null) {
setTimeout(function() {
if (recap.getAttribute('type')=='text') {
recap.select();
} else {
recap.focus();
}
}, 100 );
}
}
Edit #1: I made a few minor changes to the code, which has brought me a little closer to my intended functionality of the script. However, I only made one change to the code pertaining to the focus: I tried to to disable the tab keydown when pressed on the last element (and also the shift+tab keydown on the first element) in an attempt to force the focus on the element I want without skipping over it like it has been doing. This is the code I added:
$(this).one('keydown', function (event) {
return !(event.keyCode==9 && shiftDown==true);
});
This kind of works. After the page loads, If the user presses tab on the last element without making a change to its value, the focus will be set to the second element. However, the second time the user presses tab on the last element without making a change to its value, and every subsequent time thereafter, the focus will be set to the first element, just as I would like it to.
Edit #2: I replaced the code in Edit #1, with code utilizing event.preventDefault(), which works better. While if a user does a shift+tab keydown when in the first element, the focus moves to the last element as it should. However, if the user continues to hold down the shift key and presses tab again, focus will be set back to the first element. And if the user continues to hold the shift key down still yet and hits tab, the focus will move back to the last element. The focus will shift back and forth between the first and last element until the user lifts the shift key. This problem does not occur when only pressing tab. Here is the new code snippet:
event.preventDefault();
$(focusEl).focus();
You have a lot of code I didn't get full overview over, so I don't know if I missed some functionality you wanted integrated, but for the tabbing/shift-tabbing through form elements, this should do the work:
var elements = $("#container :input:visible");
var n = elements.length;
elements
.keydown(function(event){
if (event.keyCode == 9) { //if tab
var currentIndex = elements.index(this);
var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
var el = elements.eq(newIndex);
if (el.attr("type") == "text")
elements.eq(newIndex).select();
else
elements.eq(newIndex).focus();
event.preventDefault();
}
});
elements will be the jQuery object containing all the input fields, in my example it's all the input fields inside the div #container
Here's a demo: http://jsfiddle.net/rA3L9/
Here is the solution, which I couldn't have reached it without Simen's help. Thanks again, Simen.
$(document).ready(function() {
var options = {
target: '#c_main',
success: setFocus
};
$('#calculator').live('submit', function() {
$(this).ajaxSubmit(options);
return false;
});
$(this).focusin(function(event) {
$('#calculator :input:visible').each(function (i) {
$(this).data('initial', $(this).val());
});
return $(event.target).each(function() {
$('#c_main :input:visible').live(($.browser.opera ? 'keypress' : 'keydown'), function(event){
var elements = $("#calculator :input:visible");
var n = elements.length;
var currentIndex = elements.index(this);
if (event.keyCode == 13) { //if enter
var focusElement = elements.eq(currentIndex).attr('id');
$('#captured').val(focusElement);
} else if (event.keyCode == 9) { //if tab
var newIndex = event.shiftKey ? (currentIndex - 1) % n : (currentIndex + 1) % n;
var el = elements.eq(newIndex);
var focusElement = el.attr('id');
if ($(this).val() != $(this).data('initial')) {
$('#captured').val(focusElement);
} else if ((currentIndex==0 && event.shiftKey) || (currentIndex==n-1 && !event.shiftKey)) {
event.preventDefault();
if (el.attr('type')=='text') {
$.browser.msie ? "" : $(window).scrollTop(5000);
el.select().delay(800);
} else {
$.browser.msie ? "" : $(window).scrollTop(-5000);
el.focus().delay(800);
}
} else if (el.is('select')) {
event.preventDefault();
if (el.attr('type')=='text') {
el.select();
} else {
el.focus();
}
}
}
});
});
});
});
function setFocus() {
with (document.calculator)
var recap = document.getElementById(recaptured.value);
if (recap!=null) {
setTimeout(function() {
if (recap.getAttribute('type')=='text') {
recap.select();
} else {
recap.focus();
}
}, 1 );
}
}
I put my files available to download in my live link: http://www.presspound.org/calculator/ajax/sample.php

Categories

Resources