views:

79

answers:

5

Hi Guys,

I'm doing some simple client side validation with jQuery.

var passedValidation = new Boolean(true);

// Required Field Validators.
if ($('#fbsignup input.firstName').val().trim() == '') {
    $('#fbsignup tr.firstName em').show();
    passedValidation = false;
}
if ($('#fbsignup input.lastName').val().trim() == '') {
    $('#fbsignup tr.lastName em').show();
    passedValidation = false;
}
if ($('#fbsignup input.email').val().trim() == '') {
    $('#fbsignup tr.email em').show();
    passedValidation = false;
}
if ($('#fbsignup input.password').val().trim() == '') {
    $('#fbsignup tr.password em').show();
    passedValidation = false;
}
if ($('#fbsignup input.screenName').val().trim() == '') {
    $('#fbsignup tr.screenName em').show();
    passedValidation = false;
}


if (passedValidation == true) {
    // All validation passed. Hide the modal signup dialog and post back to signup user.
    $('#fbcSignupModal').jqmHide();
    return true;
} else {
    return false;
}

Essentially, i want to ensure all fields are filled in. If any aren't, return false, else return true. Simple.

Can this be refactored to a single line? (perhaps by applying a class to all elements?).

A caveat on the answer, i do NOT want to use the jquery-validate plugin. I know its awesome, but this is not very difficult validation and i do not want to affect the rest of the form (this is a modal popup).

So, that being said - any ideas?

EDIT

Just to clarify, i do need to know which field wan't filled in, so i can show an * next to it.

EDIT2

Updated the original code to indicate i need to show a required field label and return false if validation fails.

EDIT3

Okay i've rethought my solution, and it looks like i'll need to do a server-call to validate the email against the membership schema. So i'm probably going to end up either wrapping the fields in an update panel or doing a web service post (and return errors in a json array). However, i'll leave this question open for a while and pick the answer with the most votes.

ANSWER

So i've gone with a modified version of @box9's answer. I'll still need to do an AJAX call to the server to validate the email (as my edit above suggests), but this will ensure i only do that if all fields are filled in.

$('#fbsignup input.required').each(function (index) {
        if ($(this).val().trim() == '') {
            $(this).next('em').show();
            passedValidation = false;
        }
    });

I have an em element directly after the input fields which are required, so i can easily use the .next([selector]) jQuery selector.

Nice and easy.

Thanks for all the answers.

+1  A: 
function validate() {
    var fields = ['firstName', 'lastName', 'email', 'password', 'screenName'];
    for(fieldIdx in fields) {
        if($('#fbsignup input.' + fields[fieldIdx]).val().trim()) == '' {
            $('#fbsignup input.' + fields[fieldIdx]).after("*");
            return false;
        }
    }
    return true;
}

This does what you want, but has the disadvantage of losing information about which field it was that failed validation (if you wanted to pop up a field-specific message, for example).

Tim
Interesting, but unfortunately i want to display a * against the fields not filled in. Guess this is why we need the validate plugin.
RPM1984
That is going to grab the indexes of each array item, i.e. 0 not 'firstName'
David Dorward
@RPM1984 — your original code didn't do that (and wasn't set up to make it convenient to do that either)
David Dorward
@David - i know, my bad. Q updated.
RPM1984
@David Dorward: thanks, I always forget about that
Tim
@RPM1984: the extra line of jQuery in the edited response adds a `*` after the failed field.
Tim
A: 

If you want to check that all fields are filled, just do:

function validate() {
    ret = true;
    $('#fbsignup input').each(function(index) {
      if ($(this).val().trim()) == '') ret = false;
    });    
    return ret;
}
JochenJung
Doesn't that do each() ?
JochenJung
Yes, JochenJung is right, the each() handles it. However, the return false will not work because it will only return from the inner anonymous function, and not the validate() function.
box9
@box9: Good point. I added a variable to handle that.
JochenJung
A: 

Something like this should work for you.

var failedElements = $("#fbsignup input").filter(".firstname[value=''], .lastname[value=''], .email[value='']");

Here is an example:

http://jsfiddle.net/zfQbz/

EDIT: I just noticed you edited the question again. So if you want to take action against each item that failed just use a for loop to iterate all the items in the collection and do what you need for each one.

spinon
A: 

I recommend you to use this jquery validation plugin , it's easy to use and powerful..

Nelson
-1 The poster specifically said he didn't want to use the jquery validation plugin. I don't think all of the sudden now he is going to change his mind because you said so.
spinon
@spion you took the words right out of my mouth. Why oh why do people ignore caveats? Its like they read the subject and go BOOM, this will do it, not even looking at the actual detail of the question.
RPM1984
+1  A: 

The following code does exactly what your code does:

var passedValidation = true;

$('#fbsignup input').each(function(index) {
    if ($(this).val().trim() == '') {
        $('#fbsignup tr').filter('.' + $(this).attr('class').split(' ').slice(0, 1)).find('em').show();
        passedValidation = false;
    }
});

if (passedValidation) $('#fbcSignupModal').jqmHide();

return passedValidation;

... except for one caveat: it'll only work if the classes "firstName", "lastName", etc... are the FIRST class in the class attributes of your inputs. This limitation, and the convoluted line $('#fbsignup tr').filter('.' + $(this).attr('class').split(' ').slice(0, 1)).find('em').show();, only exists because I don't know the structure of your HTML. The selectors can be a lot cleaner (using .sibling(), .children(), .parent(), etc. if the HTML structure is known.

Alternatively, include an array of all the classnames of your inputs:

var inputClasses = ['firstName', 'lastName', 'email', 'password', 'screenName'];

And iterate through these:

var passedValidation = true;

$.each(inputClasses, function(index, className) {
    if ($('#fbsignup').find('input.' + className).val().trim() == '') {
        $('#fbsignup').find('tr.' + className + ' em').show();
        passedValidation = false;
    }
});

if (passedValidation) $('#fbcSignupModal').jqmHide();

return passedValidation;

The downside to this is that you'll have to manually update the array if you change/add inputs. Your best bet is probably to modify my first solution using the known structure of your HTML, or even convert classes to IDs.

box9
@box9. I likee. =) +1
RPM1984