Change event to check change on any form element - javascript

I have a from with disabled button, which gets enabled when the form is valid. With the function below I'm checking for changes and it works if the form consists only of inputs. How can I check for change on other elements like select or checkbox?
$("#create-rule-form").parsley();
$('input').on('keyup', function() {
$("#create-rule-form").parsley().validate();
if ($("#create-rule-form").parsley().isValid()) {
$('#create-rule-btn').prop('disabled', false);
} else {
$('#create-rule-btn').prop('disabled', 'disabled');
}
});

Use jQuery's :input selector, it matches all tags that are used for form input.
$(":input").on('edit change').function() {
// code here
});

You can use $('form').find('*') to select all of the form's children and grandchildren, and then apply the event to all of them like below.
Also, on a side note, I believe the event you should handle is change instead of keyup, as keyup will not work with checkboxes and dropdowns.
$('form').find('*').on('change', function() {
//do stuff
});

Related

Detect form onchange and which form elements had change at once

I am trying to detect form onchange using jQuery
But, can I get specific changed elements while form onchange detected?
$(document.forms['form-id']).change(function () {
if (element1 changed) {
do something
}
if (element2 changed) {
do something
}
});
Non-jQuery solution are welcome :)
The target property can be the element that registered for the event or a descendant of it. You can check e.target.
$(document.forms['form-id']).change(function (e) {
console.log(e.target)
});

jQuery - bind multiple events and exclude other events

I've got a search form that has both <input type="text"> and <select> form elements. Listening in to that form I've got this jQuery...
$('#searchform :input').stop().on('keyup change',function(){
// do some ajax stuff
})
The tricksy bit is the way the script listens for multiple events using .on('keyup change' etc.). This works great but there's a problem...
When the input fields lose focus the script jquery listener is triggered.
Here's a demonstration to explain what I mean https://jsfiddle.net/o2k4jf90/1/
I want to do something like this...
$('#searchform :input').stop().on('keyup change not:blur',function(){
// do some ajax stuff
})
...but clearly that's nonsense. What can I do?
Try substituting input event for change , keyup events
$(document).ready(function () {
$(':input').on('input',function(e) {
$('#report').append('stuff happened<br />');
})
});
jsfiddle https://jsfiddle.net/o2k4jf90/3/
The issue is because the change event fires when an input field loses focus, and when the chosen option of a select is modified. To achieve what you need, you would need to bind the events separately. Try this:
$(document).ready(function () {
$('input').keyup(stuffHappened);
$('select').change(stuffHappened);
})
function stuffHappened() {
$('#report').append('stuff happened<br />');
}
Updated fiddle
You can still use a single event handler if you hook the event to the form, however you would need to check the type and target.tagName of the event to achieve the same logic, which is not pretty at all:
$('form').on('keyup change', function(e) {
if ((e.type == 'change' && e.target.tagName == 'SELECT')
|| (e.type == 'keyup' && e.target.tagName == 'INPUT')) {
$('#report').append('stuff happened<br />');
}
});
For this reason, I would suggest using the former method.

.focus() doesn't work on cloned object?

Hope you are all doing well!
So I have a form that contains list of input text in a row. the form can contains as many rows as possible as there is an 'add row' button that allows user to add dynamically
I use clone() to this 'add row' function and it's working perfectly
Next,each input in a row can only be edited if the corresponding checkbox is checked
I have put the code to the fiddle: FIDDLE DEMO
Now, when the checkbox is checked, we directly put the focus to the first input (which I defined the input class ='first'), once this input is filled, it directly focuses to the next input. and it's working fine, EXCEPT: if I add new row, the focus function doesn't work anymore.
My focus function is:
$("input").keyup(function (event) {
if ($(this).val() != "") {
$(this).next('input').focus();
if ($(this).next('input[type="text"]').val() == "X") {
$(this).closest('.me').find('input').focus();
}
}
});
Is that supposed to be that way? Or is there anything I need to add to the script?
Thanks!!
Use clone(true) instead of clone()
Code
var new_line = $('#content div.2dtme:last').clone(true).append();
DEMO
OR
You need to use Event Delegation. You have to use .on() using delegated-events approach.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the event binding call.
i.e.
$(document).on('event','selector',callback_function)
Example
$('form').on('keyup', 'input', function (event) {
//Your code
});
instead of
$("input").keyup(function (event) {
//Your code
});
DEMO

Event Listener valid for HTML5 forms

New on HTML5 there's an "invalid" event, to which you can add a listener:
document.addEventListener('invalid', function(e){
var element = $(e.target);
element.addClass("invalid");
element.parent().addClass("invalid");
}, true);
Please note, this event just works when submitting the form... If I style the input input:invalid { background: red }, the style is applied when the user starts typing and his input is not valid. Is that event only fired on submit? I tried adding the listener to the inputs themselves instead of the document and it didn't work.
I add a listener in order to apply a style to the input's parent... Now, when the user corrects it, it's valid again... I know there's not a "valid" event, so, how can I accomplish it?
Ok, so here's a fiddle --> http://jsfiddle.net/Osoascam/ceArQ/7/
The invalid listener seems to be only fired on submit... I just wanted to know whether there's a way to add a handler just like there is for focus. See that if you type a
Thanks in advance,
Óscar
You should use the :invalid pseudo selector and the input or the change event, to solve your problem.
$(document).bind('change', function(e){
if( $(e.target).is(':invalid') ){
$(e.target).parent().addClass('invalid');
} else {
$(e.target).parent().removeClass('invalid');
}
});
Here is a simple fiddle http://jsfiddle.net/trixta/YndYx/.
If you want to remove the error class as soon as possible you should add the error class on change and remove it on the input event (Note: input event is much better than here suggested keyup, simply because it also is triggered on paste etc., but it only works with input elements, not textarea.)
And here is a fiddle using a mixture of input and change event:
http://jsfiddle.net/trixta/jkQEX/
And if you want to have this cross browser you can simply use webshims lib to polyfill. Here is a x-browser example:
http://jsfiddle.net/trixta/RN8PA/
Since these classes are always added when a form is submit, remove the class prior validating:
$('#myForm').submit(function(){
$('.invalid', this).removeClass('invalid'); // Remove all invalid classes
$(this).removeClass('invalid'); // If the parent = form.
// Normal validation procedure.
});
Expected result:
User initiates submit
onsubmit is triggered > All invalid class names within the form are removed.
The invalid events are triggered, and the invalid classes are added when necessary
Update
Added an extra block to your fiddle, see updated fiddle: http://jsfiddle.net/ceArQ/10/. I have implemented the checkValidity() method and the validity.valid property. Now, the classes are automatically added when the input is invalid.
document.addEventListener('keyup', function(e){
var input = e.target;
if (!$.nodeName(input, 'input')) return;
input.checkValidity();
var element = $(input).parent();
if(input.validity.valid) {
element.removeClass('invalid');
element.parent().removeClass('invalid');
} else { //Remove the lines below if you don't want to automatically add
// classes when they're invalid.
element.addClass('invalid');
element.parent().removeClass('invalid');
}
});
On key-up, the validity of an input element is checked. If it's valid, the invalid class is removed from its parent.
You could bind your validation logic to the focus and blur events, or to be even more responsive, to the keyup event.
$('input').keyup(function() {
if(isValid(this)) {
$(this).removeClass('invalid').parent().removeClass('invalid');
$(this).addClass('valid').parent().addClass('invalid');
}
else {
$(this).removeClass('valid').parent().removeClass('valid');
$(this).addClass('invalid').parent().addClass('invalid');
}
});
Have you tried using :valid to give an indicator as to whether a field is valid. and having forms that are invalid just keep their default styling.
Then calling form.checkValidity() in the submit handler? (The browser should then tell the end-user which form element is not valid).

Jquery : how to trigger an event when the user clear a textbox

i have a function that currently working on .keypress event when the user right something in the textbox it do some code, but i want the same event to be triggered also when the user clear the textbox .change doesn't help since it fires after the user change the focus to something else
Thanks
The keyup event will detect if the user has cleared the box as well (i.e. backspace raises the event but backspace does not raise the keypress event in IE)
$("#inputname").keyup(function() {
if (!this.value) {
alert('The box is empty');
}
});
jsFiddle
As Josh says, this gets fired for every character code that is pressed in the input. This is mostly just showing that you need to use the keyup event to trigger backspace, rather than the keypress event you are currently using.
The solution by Jonathon Bolster does not cover all cases. I adapted it to also cover modifications by cutting and pasting:
$("#inputname").on('change keyup copy paste cut', function() {
//!this.value ...
});
see http://jsfiddle.net/gonfidentschal/XxLq2/
Unfortunately it's not possible to catch the cases where the field's value is set using javascript. If you set the value yourself it's not an issue because you know when you do it... but when you're using a library such as AngularJS that updates the view when the state changes then it can be a bit more work. Or you have to use a timer to check the value.
Also see the answer for Detecting input change in jQuery? which suggests the 'input' event understood by modern browsers. So just:
$("#inputname").on('input', function() {
//!this.value ...
});
Another way that does this in a concise manner is listening for "input" event on textarea/input-type:text fields
/**
* Listens on textarea input.
* Considers: undo, cut, paste, backspc, keyboard input, etc
*/
$("#myContainer").on("input", "textarea", function() {
if (!this.value) {
}
});
You can check the value of the input field inside the on input' function() and combine it with an if/else statement and it will work very well as in the code below :
$( "#myinputid" ).on('input', function() {
if($(this).val() != "") {
//Do action here like in this example am hiding the previous table row
$(this).closest("tr").prev("tr").hide(); //hides previous row
}else{
$(this).closest("tr").prev("tr").show(); //shows previous row
}
});
Inside your .keypress or .keyup function, check to see if the value of the input is empty. For example:
$("#some-input").keyup(function(){
if($(this).val() == "") {
// input is cleared
}
});
<input type="text" id="some-input" />

Categories

Resources