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
Related
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()
If I paste text using ctrl c and ctrl v on table1(For example on "Apple"), duplicate text on input on table2 still change, but If i paste using right click and paste,duplicate input on table 2 does NOT change. :( Ive created two different event(keyup and change) but nothing seems to work when text is paste using right click. Please see below :
Keypress fiddle demo
$(document).off('keydown').on('keydown', $('#table1 tbody tr td input:eq(0)'), function (e) {
var oldValue =$(e.target).val();//get the input value before keypress or edit
$(document).on('keyup', $('#table1 tbody tr td input'),function(e){
$('#table2').find('td input').each(function(){
if($(this).val() === oldValue){
$(this).val($(e.target).val());
}
$(document).off('keyup');
});
});
});
on change fiddle demo
var oldValue;
$(document).on('keydown', '.main', function (e) {
oldValue = $(this).val();
foo(oldValue);
});
var newValue;
$(document).on('keyup', '.main', function (e) {
newValue = $(this).val();
foo(oldValue);
});
function foo(oldValue) {
$('#table1').find('tbody tr').find('td input').change(function (i) {
var orig = $(this).val();
$('#table2 tbody tr').find('td input').each(function (i) {
if (oldValue == $(this).val()) {
$(this).val(orig);
}
});
});
}
You can count the characters onChange (since you can only enter one character at a time.
Edit:
Why it wasn't working:
on your jsfiddle remember to set onDomReady in the frameworks & extension for the equivalent of $(document).ready(handlerFn)
When you use on('change', handlerFn) or .change(handlerFn) on an input it will fire only after the textbox loses focus ( blur ). The response is not instantaneous like when you use select on your forms. Use bind("input", handlerFn) instead of on(change) for inputs.
The code below will update the matching word on #table2 from the one being edited on #table1. Updating will work for copy-paste CTRL C/V or on mouse copy/paste events. It will also alert if the user copy/paste by comparing the length of the old and new value.
$("#table1 >* input").each(function() {
var elem = $(this),
oldValue;
elem.on('focus', function () {
elem.data('oldVal', elem.val());
elem.data('oldLen', elem.data('oldVal').length);
});
// Look for changes in the value,
// bind 'input' event to the textbox to fire the function
// every time the input changes (paste, delete, type etc.)
elem.bind("input", function(event){
oldValue = elem.data('oldVal');
// update oldVal
elem.data('oldVal', elem.val());
// check if pasted
if (elem.val().length - elem.data('oldLen') > 1 ) {
alert('Most certainly pasted');
}
// update input value length
elem.data('oldLen', elem.data('oldVal').length);
// update #table2
foo(oldValue, elem.val()) ;
});
});
And the function to update #table2
function foo(oldValue, newValue) {
$('#table2')
.find('input')
.each(function (i) {
if (oldValue === $(this).val()) {
$(this).val(newValue);
}
});
}
here's a jsfiddle for you to play with
Check this code, Hope this will help you:
jQuery('#some_text_box').on('input propertychange paste', function() {
var text1 = $('#some_text_box').val();
//alert(text1);
$('#tab2').val(text1);
});
This is your first text box #some_text_box.
<input type='text' value = "Apple" id='some_text_box' />
And this is table 2 text box #tab2
<input type='text' value="Apple" id='tab2'/>
JSFiddle
Ok well this will detect for you if the user uses Ctrl + V etc but thats it. If they right click and paste then you will need another expression to capture that. I left this open by using keydownand keyupso you can capture more variations if needed.
This is jQuery so you will need the library to cover this.
$(document).ready(function()
{
var ctrlDown = false;
var ctrlKey = 17, vKey = 86, cKey = 67;
$(document).keydown(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = true;
}).keyup(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = false;
});
$("#no-copy-paste").keydown(function(e)
{
if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)) return false;
});
});
Here is an article on handlers that may be some help to you as well.
http://unixpapa.com/js/key.html
-Epik
Is there a generic solution to determining which input (e.g., text, submit button, etc.) was used to submit a form using jQuery or plain Javascript?
I'm well aware that you can bind to click events on submit buttons:
$('[type=submit]').on('click', function(event) {
event.preventDefault();
var $submit = $(this);
$submit.closest('form').trigger('submit', [$submit]);
});
I'm also aware that you can listen for the Enter key on text inputs:
$('input').on('keypress', function(event) {
if (event.which == 13) {
event.preventDefault();
var $input = $(this);
$input.closest('form').trigger('submit', [$input]);
}
});
Where the form listens for the submit event:
$('#the_form').on('submit', function(event, $submit) {
// ...
});
But is there a more generic solution without the need for special logic for submit buttons and text inputs (and any future type of input)?
Have you considered seeing what element has the focus on submit?
$(document).ready(function() {
var target = null;
$('#the_form :input').focus(function() {
target = this;
alert(target);
});
$('#the_form').submit(function() {
alert(target);
});
});
i am capturing an event on enter through a selector. but it is not capturing.
var trID;
row.click(function() {
var tr = $(watchRow).find('tr');
$('tr').not(this).removeClass('highlight');
$(this).toggleClass('highlight');
trID = $(this).attr('id');
alert(trID);
});
row.find('trID').keypress(
function(event) {
if (event.keyCode == 13) {
//selfReference.addSymbolToWatch();
alert("You Press Enter!");
}
});
i am getting trID but actually what i want to do is when the row is selected then it is able to trigger an enter event on pressing enter.
You'll need to make the tr focusable by adding the attribute focusable to be able to capture keypresses.
I have tried this and it works as you requested when the 'TR' is selected
$(document).ready(function(){
$('tr').live('keypress',function(){
if (event.keyCode == 13) {
alert("You Press Enter!");
}
});
});
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