How to validate a form with jQuery? - javascript

I tried to find the answer in other questions but actually nothing worked -.- Somehow I hate JavaScript ... Anyway! My Code looks like:
function validate()
{
if ($(":input").length == 0)
{
$(":input").addClass("notvalid");
return false;
}
else
{
$(":input").removeClass("notvalid");
return true;
}
return true;
}
$(":input").blur(validate());
$(":input").keyup(validate());
$("#customForm").submit(function(){
if(validate()){
return true;
}
else
{
return false;
}
});
I just want to test every tag to be not empty. The test should be done when the focus is lost or after every key type. And of course after the submit button has been clicked.
It doesn't work. Firefox error console says something like: unknown pseudoclass or pseudoelement 'input'. What does this mean?

You can alway use AJAX to validate your fields if you are more familiar with server side scripting like PHP.
Back to JS here what i think you want to accomplish:
$("input:text").bind("blur, keyup", function(){
if($(this).val().length > 0){
//Valid not empty
$(this).removeClass("notvalid");
}else{
//invalid empty
$(this).addClass("notvalid");
}
});
$("#customForm").submit(function(){
$("input:text").keyup(); //triggers the keyup event on input fields
//which then validates your fields according the
//code above.
if($("form .notvalid").length > 0){
//You got some invalid fields in form
return false;
}else{
//All fields are valid continue
return true;
}
});
it may look a whole different then your approach but if you want to learn jQuery is better to get familiar with it. I commented some of the process, but if you have any doubt of the methods or functions used in code above you just google it. Good Luck!

The error says the jQuery doesn't know what elements to select with :input. Just replace :input but input:text in your selectors. You could also take a look at the jquery.validate plugin which will simplify your validation logic. There are many demos on the site that should help you get started.
UPDATE:
My mistake. There's :input selector according to the documentation.

Instead of:
function validate()
{
if ($(":input").length == 0)
{
$(":input").addClass("notvalid");
return false;
}
else
{
$(":input").removeClass("notvalid");
return true;
}
return true;
}
Use:
function validate()
{
$(":input").each(function(){
if ($(this).val() === '')
{
$(this).addClass("notvalid");
return false;
}
else
{
$(this).removeClass("notvalid");
return true;
}
});
return true;
}

If your using jQuery already you should really use jquery.validate plugin like Darin said.
This will make you code much cleaner and easier to add standard validation rules like valid email, URL, min length, max length etc. Also removes the need of having to add and remove classes at does it for you.

Related

Simple jQuery function not picking up click function

I am having a go at my very first jQuery function. What needs to happen is that a form will be assigned to the function. When a user clicks on the submit button it needs to first do validation on each :input field within the the function.
I am assigning a form as the selector for my function:
$("form[name='form_name']").validator();
This then gets passed into the function and is assigned to a function property called "selected_form". Within my jQuery function I have another function which needs to wait for the submit button to be clicked, and after that it needs to iterate through all of the :input form elements and handle simple validation.
The issue now is:
a) Within my jQuery function I am making a call to return validate(); Validate then checks to see whether the button as clicked. I suspect that because the function is run and there was no button clicked, it continues and basically returns the validate() function back as false without doing any checks. I assume I will need to customize this to almost wait until the button is pressed, but I really have no idea how to do that.
b) $(selected_form+" :input").each(function() { ... } does not work as it appears to not be able to use that as a selected. I need to iterate through the "selected_form" property and select only the :input fields. Any assistance?
c) If you have any other suggestions or best practices for me regarding building a proper jQuery function please assist, this is my first attempt and I would rather learn the best practices now as appose to following my own ideas.
(function($) {
$.fn.validator = function(user_options) {
var default_options = {
exclusions: false,
rules: false,
submit_btn_name: 'event_form_submit'
};
var selected_form = this;
var selected_element = false;
var element_type = false;
var options = $.extend(default_options,user_options);
function validate() {
// Run only if form has been submitted: (this does not appear to work now, the form gets submitted without the return false;
$("input[type='"+options.submit_name+"']").click(function(event) {
event.preventDefault();
// The selector here appears to be wrong?
$(selected_form+" :input").each(function() {
// Individual element validation will happen here, for now I am just looking to log the element types :)
selected_element = this;
console.log(get_element_type());
});
return false;
});
return false;
};
function get_element_type() {
return element_type = element.type;
}
return validate();
}
})(jQuery);
// Run the validator:
$(document).ready(function() {
$("form[name='tepg_form_processor']").validator();
});
As jalynn2 and others have mentioned, my selector was incorrect. Fixed and working :)

Find out if html form has changed

Using jquery I've added a change handler to a form.
This works when any input is changed BUT only if the user manually changes an input and not when some other code changes the input.
Is there any way to detect if a form has changed even if its inputs are changed by code?
Yes, there seems to be some confusion over this. In an ideal world you would expect the onchange event to happen whenever the inputs change but thats not what happens. I'm sure for good reasons to - maybe not.
One way I've overcome this obstacle is to capture the form state into a variable just after displaying it and then just before submitting it to check if the state has changed and to act accordingly.
An easy state to store is what the serialize function returns. An easy place to store the state is using the data functionality. Both serialize and data are available with jquery.
Of course you can use other different forms of state (some form of hash) or storage for this state (standard global variable for example).
Here is some prototype code:
If your form id is 'xform' then you can call the following code when the form has displayed:
$('#xform').data('serialize',$('#xform').serialize());
And then, when you need to check, for example just before a button submit you can use:
if($('#xform').serialize()!=$('#xform').data('serialize')){
// Form has changed!!!
}
You could wrap all this up into a copy & paste javascript snippet that will give you a formHasChanged() function to call wherever you need it (NOT TESTED):
$(function() {
$('#xform').data('serialize',$('#xform').serialize());
});
function formHasChanged(){
if($('#xform').serialize()!=$('#xform').data('serialize')){
return(true);
}
return(false);
}
But I'll stop here otherwise I'll create yet another jquery plugin.
Serializing the form is certainly an option, but it will not work if:
you want to know which fields have changed
it only needs to check a subset of the fields
dynamically adding or removing fields.
Fortunately, every form element has a default value associated with its object:
input, textarea : defaultValue
checkbox, radio : defaultChecked
select: defaultSelected
for ex: to ckeck if input or textarea has changed:
var changed = false;
$(":text,textarea").each(function(){
changed = this.value != this.defaultValue;
return !changed; // return if at least one control has changed value
});
This is easily achieved in JavaScript without jQuery. initChangeDetection() can be called multiple times:
function initChangeDetection(form) {
Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}
Test on JS Bin
For older browsers that don't support newer arrow/array functions:
function initChangeDetection(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
el.dataset.origValue = el.value;
}
}
function formHasChanges(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
return true;
}
}
return false;
}
Not in a regular way.
You can change with input and then trigger the change event.
$('#inputId').val('foo').trigger('change');
or with this:
$('#inputId').val('foo').change();
Here is what i did (i found my solution using zaf's answer)
$("form").change(function() {
$(this).data("changed","true");
});
$("input[type='submit']").click(function() {
if($("form").data("changed") == "true") {
var discard = confirm("Some unsaved changes. Discard them ?");
if(!discard) return false;
}
});
Try onchange attribute
According to W3c it should trigger anytime the content of an element, the selection, or the checked state have changed.

jQuery form validation questions?

I am new to jQuery and javascript and I am used mainly to php. I am upgrading my site so it contains a little ajax to improve usability and to keep me busy!
I am using this simple little script I threw together for the login page. All works well at the minute but I have a couple of questions I'd like to ask!
$('#loginForm .submit').click(function(event) {
$('.error').hide();
event.preventDefault();
var errors = 0;
var loginEmail = $('#loginEmail').val();
var loginPassword = $('#loginPassword').val();
if (loginEmail.length == 0) {
$('#loginEmail').after('<div class="error"></div>');
errors++;
}
if (loginPassword.length == 0) {
$('#loginPassword').after('<div class="error"></div>');
errors++;
}
if (!errors) {
$('.submit').submit();
}
});
You will notice that the first line of code within the function is;
$('.error').hide();
Now in php I would normally use;
if (isset(........)) {
Is there a simliar way to do this in javascript as when the user first activates the function there will be no html with the class .error?
Also I am trying to add a new parameter to the function as well as the event parameter, how would I do this? I have tried the following?
$('#loginForm .submit').click(function(event, var) {
$('#loginForm .submit').click(function(event var) {
$('#loginForm .submit').click(function('event', 'var') {
And all seem not to work. Then again I am going by php, jQuery/javascript is not my strong point!
Thanks
Before performing an action, you can check if the function $() selected element by using the following syntax:
if ($('.error').length)
{
// actions
}
If the .error - div exists in the DOM by default and is just hidden, you can't just check the length of $('.error'), because even if it's empty, length will return 1.
You could do something like this:
if($('.error').html().length !== 0){
//do something
}
This will check the containing string of the error-div, so if it's empty, length will return 0.
Still I would recommend setting a boolean var. If errors occur, it gets set to false and you can check the var and you do not have to query for DOM-elements for such a simple task.
To your second question, try something like this:
$('#loginForm .submit').bind("click", {variable1: var}, handleSubmit);
function handleSubmit(event){
var passedVar = event.data.variable1;
}

Is there a way to validate a Sizzle selector?

Is there a way to validate (verify that its constructed correctly) a Sizzle selector without running it?
Well, as Russ says, since Sizzle interprets the selector, it cannot validate it without evaluating it.
However, you can catch the exception thrown by Sizzle to determine if a selector is valid or not:
function isSelectorValid(selector)
{
try {
$(selector);
} catch (x) {
return false;
}
return true;
}
Your can test this solution here.
EDIT: For the sake of history, my original (and overengineered) answer was:
However, it's possible to temporarily override Sizzle's error management in order to extract a boolean value from the error status of its last parse operation. The following solution takes advantage of the fact that jQuery exposes Sizzle through $.find (so far):
function isSelectorValid(selector)
{
var oldErrorMethod = $.find.error;
try {
$.find.error = function(msg) {
valid = false;
oldErrorMethod(msg);
};
$(selector);
return true;
} catch (x) {
return false;
} finally {
$.find.error = oldErrorMethod;
}
}
That can arguably be considered as a horrible hack, but it works: you can test it here.
Not quite, the Sizzle engine isn't compiled so the only way to check the validity of the selector is to select it.
However, you can do something like this:
var selector = ...construct your selector ...
if ($(selector).length > 0) {
// it worked.
}

Is there a 'has focus' in JavaScript (or jQuery)?

Is there something I can do like this (perhap via a plugin)
if ( ! $('form#contact input]').hasFocus()) {
$('form#contact input:first]').focus();
}
Basically, set focus to the first input, but only if the user has not already clicked into anything?
I know this will work too, but is there anything more elegant?
$(function() {
var focused = false;
$('form#contact input]').focus(function() {
focused = true;
});
setTimeout(function() {
if ( ! focused) {
$('form#contact input:first]').focus();
}
}, 500);
});
There is no native solution but yes there is a more elegant way you can do it:
jQuery.extend(jQuery.expr[':'], {
focus: "a == document.activeElement"
});
You're defining a new selector. See Plugins/Authoring. Then you can do:
if ($("...").is(":focus")) {
...
}
or:
$("input:focus").doStuff();
$('input:focus')
It's CSS. You don't need to create a "custom selector." It already exists! http://www.w3schools.com/CSS/pr_pseudo_focus.asp
Just attach whatever process you want to do to that selector, and it will weed it out if the element in question is not focused. I did this recently to keep a keyup from instantiating an email input error check when the e-mail input wasn't being used.
If all you're trying to do is check if the user has focused on anything themselves, just do this:
if($('input:focus').size() == 0){
/* Perform your function! */
}
jQuery 1.6 now has a dedicated :focus selector.
I had trouble with cletus approach, using jQuery 1.3.2 and Firefox 3.6.8, because the string "a == document.activeElement" was not a valid function.
I fixed it defining a function for the focus key. In fact, all other keys defined in jQuery.expr[':'] are defined as functions. Here's the code:
jQuery.extend(jQuery.expr[':'], {
focus: function(e){ return e == document.activeElement; }
});
So, now it works as expected.
However, I was experiencing some strange behaviour in Firefox 3.6.8 (maybe a bug in FF?). If I clicked on an input text while the page was rendering, and if I called is(":focus") on page load, I would get an error from the browser, reported by FireBug, and the script would break.
To solve this, I surrounded the code with a try...catch block, returning false on error. Use it if you want to prevent your users from experiencing the same error:
jQuery.extend(jQuery.expr[':'], {
focus: function(e){
try{ return e == document.activeElement; }
catch(err){ return false; }
}
});
Frustratingly difficult to find a solution to this problem considering the solution is actually very simple:
if (document.activeElement == this) {
// has focus
}
if (document.activeElement != this) {
// does not have focus
}
No, there isn't.
However, you can simulate it like this:
$(':input')
.data('focused', false)
.focus(function() { $.data(this, 'focused', true); })
.blur(function() { $.data(this, 'focused', false); });
There is a plugin http://plugins.jquery.com/project/focused
Also you can check Using jQuery to test if an input has focus
Here is a succinct way to do it.
$(document.activeElement)
or to plug it into your example..
if ($('form#contact input]')[0]!=$(document.activeElement)) { ... }
I know this is an old question, but may be my solution will help someone :)
since this didnt worked for me:
if ($(this)!=$(document.activeElement)) { ... }
..were "this" is returned from blur function. So i did this:
if ($(document.activeElement).attr("class") != "input_textbox"){ ... }
$('*:focus')
(Necro ftw, but still valid and useful)

Categories

Resources