I have a client who wants the Enter/Return key to perform the same function as the tab key on form fields.
Here's my code so far. It won't work. Anyone know why?
<script>
$('input, select').live('keydown', function(e) {
if (e.keyCode === 13) {
if (e.shiftKey) {
var focusable = form.find('input,a,select,button,textarea').filter(':visible');
focusable.eq(focusable.index(this)-1).focus();
}
else {
var focusable = form.find('input,a,select,button,textarea').filter(':visible');
focusable.eq(focusable.index(this)+1).focus();
return true;
}
}
});
</script>
You'll want to prevent the default behavior of the enter key with preventDefault();
You put form.find in there, but I don't see form set anywhere. Maybe try $('form')?
I've set up a basic js fiddle for you to check out. Is this the functionality you were going for?
$('input, select').on('keydown', function (e) {
if (e.keyCode === 13) {
e.preventDefault();
if (e.shiftKey) {
var focusable = $('form').find('input,a,select,button,textarea').filter(':visible');
focusable.eq(focusable.index(this) - 1).focus();
} else {
var focusable = $('form').find('input,a,select,button,textarea').filter(':visible');
focusable.eq(focusable.index(this) + 1).focus();
return true;
}
}
});
Note that .live() is deprecated and you could just use .on()
Related
I am using following code to tab through form elements using enter key. Problem is that this code skip select2 elements.
$('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(':not([disabled]):not([tabindex="-1"]):visible');
next = focusable.eq(focusable.index(this)+1);
if (next.length) {
next.focus();
} else {
//form.submit();
}
return false;
}
});
Change your keydown to keyup
$('body').on('keyup', 'input, select', function(e)
Reason is keydown is already handled in select2 library for choosing an item
I want to use some letters ( keys ) as shortcut for some actions in javascript. I want to check whether the cursor is focused on any textfield, form input, etc. so that the shortcut action will be canceled when user is typing something in a form or textfield.
For example, i want an alert() to be executed when user presses 'A'. But if the user is typing some text in a textarea like 'A website' then he will be pressing 'A', this time alert() should not be executed.
$(document).keydown( function( e ) {
if( e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA" ) return;
if( e.target.isContentEditable ) return;
// Do stuff
}
window.onkeydown = function(e){
if ( e.target.nodeName == 'INPUT' ) return;
handle_shortcut();
};
jQuery
$(window).bind('keydown',function(e){
if(e.target.nodeName.toLowerCase() === 'input'){
return;
}
alert('a');
});
or pure js
window.onkeydown = function(e){
if(e.target.nodeName.toLowerCase() === 'input'){
return;
}
alert('a');
};
What you can do in addition to this is define an array of non-alert element types, so input, textarea etc and then check none of those elements are currently the target.
Demo: http://jsfiddle.net/7F3JH/
You can bind and unbind the shortcut events depending on which element currently has focus on your page.
JavaScript
window.onload = initWindow();
function initWindow () {
attachShortcutHandler();
var inputs = document.getElementsByTagName('input');
for (var i = 0, max = inputs.length; i < max; i++) {
inputs[i].onfocus = removeShortcutHandler;
intputs[i].onblur = attachShortcutHandler;
}
}
function removeShortcutHandler () {
window.onkeypress = null;
}
function attachShortcutHandler() {
window.onkeypress = function () {
//your code here
}
}
jQuery
$(function () {
initShortcutHandler();
$('input, [any other element you want]')
.on('focus', function () {
$('body').off('keypress');
})
.on('blur', function () {
initShortcutHandler();
});
});
function initShortcutHandler() {
$('body').on('keypress', function () {
//do your stuff
});
}
jQuery mouseover()
$('element').mouseover(function() {
alert('over');
});
you need to make a flag as global. and set it false when any textbox has focus.
var flag = true;
$('input:type="text").focus(function(txt) {
flag= false; });
if(flag) //shortcut keys works...
Better use the focusOut method defined in JQuery. As per my understanding you can do something like this
$("input").focusout(function() {
if($(this).val() == "A"{
alert("your message");
return false;
}else{
//do other processing here.
}
});
Hope this helps :)
I have a problem I can't seem to sort out.
I have a form with a custom styled button (input type=button). When typing in the text field, I want people to be able to press the TAB key and go to the button. However, it won't use a tab-index so my solution was to highlight the label and change the CSS to give the button a new border color. However, the border color will not change on keypress in any browser other than Firefox.
Here is what I have:
$(function() {
$("#email").bind("keypress", function(e) {
if (e.keyCode == 13) {
send();
return false;
};
if (e.keyCode == 9) {
$("#submit_btn").removeClass('submit1').addClass('submit1after');
};
});
};
The first enter keypress is to serialize and email the form and all.
I can't seem to get it to work for the life of me. What am I doing wrong? Is there a better solution to what I'm trying to accomplish?
Thanks for taking the time,
Armik
Use keydown instead, for me that works (see demo: http://jsfiddle.net/npGtX/2/)
$(function () {
$("#email").bind("keydown", function (e) {
if (e.keyCode == 13) {
send();
return false;
};
if (e.keyCode == 9) {
$("#submit_btn").removeClass('submit1').addClass('submit1after');
};
});
};
Also I found this: Suppressing keyPress for non-character keys?
keypress is not necessarily triggered when the keypress is not a
character. So the browser may not trigger an event on backspace, F1,
the down key, etc.
You can use the keyup event and event object's which property, jQuery normalizes the which property and it's cross-browser:
$(function() {
$("#email").bind("keyup", function(e) {
if (e.which == 13) {
send();
return false;
};
if (e.which == 9) {
$("#submit_btn").toggleClass('submit1 submit1after');
};
});
};
$(function() {
$("#email").keypress(function(e) {
if (e.keyCode == 13 || e.which== 13) {
send();
return false;
};
if (e.keyCode == 9 || e.which== 9) {
$("#submit_btn").removeClass('submit1').addClass('submit1after');
};
});
};
I have few inputs which you focus them using keycodes.
I am trying to: when focus on inputs, disable the keycodes function and when not focused, enable.
I tried this:
var hotkeys_function = false;
if (!hotkeys_function ){
$(document).keydown(function(e) {
if (e.keyCode == 71) {
$("#input1").fadeIn();
$("#input1").focus().select();
var hotkeys_function = true;
}
});
}
And this:
if ($("#input1").select()) {
var hotkeys_function = true;
}
but none seem to be working.
Not $("#input1").select() but $("#input1").focus().
In fact, no variables are needed, you can just check and return dynamically whether an input is focused or not.
$(document).keydown(function(event) {
if($("#input1").is(":focus")) return; //Will fail if already focused.
if (event.keyCode == 71) { //g
$("#input1").fadeIn();
$("#input1").focus().select();
}
});
Working example.
What you could do is this, without any other variables: http://jsfiddle.net/pimvdb/YnVPQ/.
$(document).keydown(function(e) {
if (e.keyCode == 71) {
if($("input").is(":focus")) return; // abort if any focused textboxes
$("#input1").fadeIn();
$("#input1").focus().select();
}
});
I'm using ASP.NET 2.0 with a Master Page, and I was wondering if anyone knew of a way to detect when the fields within a certain <div> or fieldset have been changed (e.g., marked 'IsDirty')?
You could bind the Change event for all inputs and flag a variable as true. Like this.
var somethingChanged = false;
$(document).ready(function() {
$('input').change(function() {
somethingChanged = true;
});
});
But, keep in mind that if the user changes something, then changes back to the original values, it will still be flagged as changed.
UPDATE: For a specific div or fieldset. Just use the id for the given fieldset or div. Example:
var somethingChanged = false;
$(document).ready(function() {
$('#myDiv input').change(function() {
somethingChanged = true;
});
});
Quick (but very dirty) solution
This is quick, but it won't take care of ctrl+z or cmd+z and it will give you a false positive when pressing shift, ctrl or the tab key:
$('#my-form').on('change keyup paste', ':input', function(e) {
// The form has been changed. Your code here.
});
Test it with this fiddle.
Quick (less dirty) solution
This will prevent false positives for shift, ctrl or the tab key, but it won't handle ctrl+z or cmd+z:
$('#my-form').on('change keyup paste', ':input', function(e) {
var keycode = e.which;
if (e.type === 'paste' || e.type === 'change' || (
(keycode === 46 || keycode === 8) || // delete & backspace
(keycode > 47 && keycode < 58) || // number keys
keycode == 32 || keycode == 13 || // spacebar & return key(s) (if you want to allow carriage returns)
(keycode > 64 && keycode < 91) || // letter keys
(keycode > 95 && keycode < 112) || // numpad keys
(keycode > 185 && keycode < 193) || // ;=,-./` (in order)
(keycode > 218 && keycode < 223))) { // [\]' (in order))
// The form has been changed. Your code here.
}
});
Test it with this fiddle.
A complete solution
If you want to handle all the cases, you should use:
// init the form when the document is ready or when the form is populated after an ajax call
$(document).ready(function() {
$('#my-form').find(':input').each(function(index, value) {
$(this).data('val', $(this).val());
});
})
$('#my-form').on('change paste', ':input', function(e) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
});
$('#my-form').on('keyup', ':input', function(e) {
if ($(this).val() != $(this).data('val')) {
$(this).data('val', $(this).val());
// The form has been changed. Your code here.
}
});
Test it with this fiddle.
A simple and elegant solution (it detects form elements changes in real time):
var formChanged = false;
$('#my-div form').on('keyup change paste', 'input, select, textarea', function(){
formChanged = true;
});
For a form you could serialize the contents on load then compare serialization at a later time, e.g.:
$(function(){
var initdata=$('form').serialize();
$('form').submit(function(e){
e.preventDefault();
var nowdata=$('form').serialize();
if(initdata==nowdata) console.log('nothing changed'); else console.log('something changed');
// save
initdata=nowdata;
$.post('settings.php',nowdata).done(function(){
console.log('saved');
});
});
});
Note this requires form elements to have a name attribute.
Just to clarify because the question is "within a certain fieldset/div":
var somethingChanged = false;
$(document).ready(function() {
$('fieldset > input').change(function() {
somethingChanged = true;
});
});
or
var somethingChanged = false;
$(document).ready(function() {
$('div > input').change(function() {
somethingChanged = true;
});
});
You can give the fieldset or div an ID and bind the change event to it ... the event should propagate from the inner children.
var somethingChanged = false;
$('#fieldset_id').change(function(e)
{
// e.target is the element which triggered the event
// console.log(e.target);
somethingChanged = true;
});
Additionally if you wanted to have a single event listening function you could put the change event on the form and then check which fieldset changed:
$('#form_id').change(function(e)
{
var changedFieldset = $(e.target).parents('fieldset');
// do stuff
});
I came up with this piece of code in CoffeeScript (not really field tested, yet):
Add class 'change_warning' to forms that should be watched for changes.
Add class 'change_allowed' to the save button.
change_warning.coffee:
window.ChangeWarning = {
save: ->
$(".change_warning").each (index,element) ->
$(element).data('serialized', $(element).serialize())
changed: (element) ->
$(element).serialize() != $(element).data('serialized')
changed_any: ->
$.makeArray($(".change_warning").map (index,element) -> ChangeWarning.changed(element)).some (f)->f
# AKA $(".change_warning").any (element) -> ChangeWarning.changed(element)
# But jQuery collections do not know the any/some method, yet (nor are they arrays)
change_allowed: ->
ChangeWarning.change_allowed_flag = true
beforeunload: ->
unless ChangeWarning.change_allowed_flag or not ChangeWarning.changed_any()
"You have unsaved changes"
}
$ ->
ChangeWarning.save()
$(".change_allowed").bind 'click', -> ChangeWarning.change_allowed()
$(window).bind 'beforeunload', -> ChangeWarning.beforeunload()
An alternative to Dw7's answer if you only want the fields inside a fieldset then you can call serialize() on its input values. Note: serialize() will not pickup any elements that do not have a "name" attribute. This will work for select tags as well.
var initialValues = $('#your-fieldset :input').serialize();
$('form').submit(function(e) {
e.preventDefault();
var currentValues = $('#your-fieldset :input').serialize();
if (currentValues == initialValues) {
// Nothing has changed
alert('Nothing was changed');
}
else {
this.submit();
}
});
.live is now deprecated and replaced by .on:
var confirmerSortie = false;
$(document).on('change', 'select', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'input', function() {
confirmerSortie = true;
});
$(document).on('change keypress', 'textarea', function() {
confirmerSortie = true;
});
The following solution worked for me:
$("#myDiv :input").change(function() { $("#myDiv").data("changed",true);});
}
if($("#myDiv").data("changed")) {
console.log('Form data changed hence proceed to submit');
}
else {
console.log('No change detected!');
}
Thanks