If (cond1 || cond2) is there a way to know what condition triggered the if

If I had
if (cond1 || or cond2)
{
do this in case cond1
do this in case cond2
}

is that possible, I was trying with switch but haven´t been able to get what I´m trying to do


if (cond1)
{
  do this in case cond1
}
if (cond2)
{
  do this in case cond2
}

And why didn’t the switch work?

I guess because I don´t know how to apply it on this situation

switch applies to a variable right? I have some conditions, when a user enters numbers in a field or special characters
if (numbers || specialcharacters)
{
switch(what should I put in here?)
{
case numbers:alert(“numbers”);
case specialcharacters:alert("special characters);
}
}

like in this example


function test(event)
{
x = event.value;
if (x == "1" || x == "2")
{
switch(x)
{
case "1":alert("yes");
case "2":alert("no");
}
}
}

where event is coming from an input field.
in there if the field ==2 it alerts no but if it ==1 it alerts yes then no even though x==2 why is it executing both?

I guess I just forgot I am using switch in a diffewrent language, I just figured I have to add break; in order for it to work properly, however I am still having problems with getting switch to work with my code


NOnumbershere=new RegExp(/\\d/);
NOsymbolshere=new RegExp(/[+.,*ª!"·$%&()= ?¿¡º^`´ç;:_-]/);
if (NOnumbershere.test(thevaluetolower) == true || NOsymbolshere.test(thevaluetolower) == true || thevaluetolower.length <= 1)
{

thefield.className="incorrect_field";
error.innerHTML = 'no numbers allowed';
}
//thevaluetolower=(thevalue of an input field)

In the code above it will provide an error saying that no numbers are allowed, but how can I apply that message only when the nonumbershere condition it true so I can add other messages when some other condition is true?

I know I can do else if to test for each condition separately but I want to know if there is any other way where I dont have to have such a big script


NOnumbershere=new RegExp(/\\d/);
NOsymbolshere=new RegExp(/[+.,*ª!"·$%&()= ?¿¡º^`´ç;:_-]/);
switch(true)
{
    case NOnumbershere.test(thevaluetolower):
        thefield.className="incorrect_field";
        error.innerHTML = 'no numbers allowed';
        break;
    case NOsymbolshere.test(thevaluetolower):
        thefield.className="incorrect_field";
        error.innerHTML = 'no symbols allowed';
        break;
} 

No need for the if.

thank you so much, I did not know it could be done this way

Even though it’s possible to code it that way, I find that it’s more difficult to understand what the code is doing. Switch blocks do have their place, but I feel uneasy about this particular one here.

It seems that it’s easier to understand what is happening in the code when it’s like this:


NOnumbershere=new RegExp(/\\d/);
NOsymbolshere=new RegExp(/[+.,*ª!"·$%&()= ?¿¡º^`´ç;:_-]/);
if (NOnumbershere.test(thevaluetolower)) {
    thefield.className="incorrect_field";
    error.innerHTML = 'no numbers allowed';
} else if (NOsymbolshere.test(thevaluetolower)) {
    thefield.className="incorrect_field";
    error.innerHTML = 'no symbols allowed';
} 

I think I am going with the if else since what I wanted to achieve was make the code smaller

I think that is a personal preference, and if you have problems understanding, it surely is better to go for an “if else”, especially since there are only two checks in this case.
I myself have absolutely no problem understanding what a switch true does, and if there would be more than 2 checks, it would be the “if elseif elseif etc” that would become difficult to understand. For me at least :slight_smile:

It seems that you’re already confused though. If more than one case in a switch matches, then each of those separate cases gets run. A switch statement is more like a separate series of if statements, rather than if/else statements.

That’s a confusion that is best to be avoided. Don’t get me wrong about this - switch statements do have their place where they can be used without confusion, but in this situation it can be more confusing to use them than not.

At the end I did this


NOnumbershere=new RegExp(/\\d/);
NOsymbolshere=new RegExp(/[+.,*ª!"·$%&()= ?¿¡º^`´ç;:_-]/);
emailpattern=new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/);
passwordpattern=new RegExp(/(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/);
function check__regular_text_field(event)
{
errorid = event.id + "error";
error = document.getElementById(errorid);
thefield=event;
thevalue=thefield.value;
thevaluetolower=thevalue.toLowerCase();
firstchartoupper = thevaluetolower.charAt(0).toUpperCase() + thevaluetolower.slice(1);
thevalueint = parseInt(thevalue.length);
if (NOnumbershere.test(thevaluetolower) == true && NOsymbolshere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_numbers_or_special_chars_error; ?>';
}
else if (NOnumbershere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_numbers_error; ?>';
}
else if (NOsymbolshere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_special_chars_error; ?>';
}
else if (thevalueint <= 1)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $not_enough_chars_error; ?>';
}
else
{
thefield.className = "correct_field";
thefield.value = firstchartoupper;
error.innerHTML = "";
}
}

Do you guys think I should have gone with switch?

I think that there’s quite a bit of duplication that could be removed, but first, we’ll deal with some common problems.

Fixing common problems

First we run the code through jslint.com with “The Good Parts” enabled, to fix up many easily found issues.

Some highlights are:

Global variables are a curse in JavaScript. It’s best to treat the global namespace as you would a public toilet and reduce your exposure to the environment as much as possible. I brought the regular expressions within the function and defined them as an object. That then allows us to reference them using re.numbers and re.symbols within the code.

The ^ and - characters have special meaning within a regular expression character class, so it’s best to escape those characters.

Variables should also all be declared at the same time, at the start of a function.

Also, in JavaScript, opening braces should always be on the right. This is not a syalistic convention in JavaScript as the script can fail to work as expected with opening braces on the left, thanks to something called automatic semicolon insertion.

The fullstops in the email expression do have some complaints remaining about them, but as it’s not used yet we can wait on that until some later period.

Reduce duplication

Now that the worst sins have been resolved, let’s move on with reducing some duplication within the code.

Instead of having many places where error.innerHTML is set, we could instead set an errormessage variable. At the end of the checks, if errormessage is set, we can display it.


errormessage = '';
...
if (...) {
    errormessage = '<?php echo $no_numbers_or_special_chars_error; ?>';
}
...

if (errormessage > '') {
    thefield.className = "incorrect_field";
    error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/>' . errormessage;
} else {
    thefield.className = "correct_field";
    error.innerHTML = "";
}

Why are you direct-linking to an image from the SitePoint web site? Naughty naughty. I’d change that to “/images/warn.gif” from here on out.

What does that give us so far for the code?


function check__regular_text_field(event) {
    var thefield = event,
        thevalue = thefield.value,
        thevaluetolower = thevalue.toLowerCase(),
        firstchartoupper = thevaluetolower.charAt(0).toUpperCase() + thevaluetolower.slice(1),
        thevalueint = parseInt(thevalue.length, 10),
        re = {
            numbers: new RegExp('/\\d/'),
            symbols: new RegExp('/[+.,*ª!"·$%&()= ?¿¡º\\^`´ç;:_\\-]/'),
            email: new RegExp('/^[a-zA-Z0-9._\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,4}$/'),
            password: new RegExp('/(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/')
        },
        errorid = event.id + 'error',
        error = document.getElementById(event.id + 'error'),
        errormessage = '';

    if (re.numbers.test(thevaluetolower) && re.symbols.test(thevaluetolower)) {
        errormessage = '<?php echo $no_numbers_or_special_chars_error; ?>';
    } else if (re.numbers.test(thevaluetolower)) {
        errormessage = '<?php echo $no_numbers_error; ?>';
    } else if (re.symbols.test(thevaluetolower)) {
        errormessage = '<?php echo $no_special_chars_error; ?>';
    } else if (thevalueint <= 1) {
        errormessage = '<?php echo $not_enough_chars_error; ?>';
    }
    if (errormessage > '') {
        thefield.className = 'incorrect_field';
        error.innerHTML = '<img align="left" src="/images/warn.gif"/>' + errormessage;
    } else {
        thefield.className = 'correct_field';
        thefield.value = firstchartoupper;
        error.innerHTML = "";
    }
}

Refining things
The parameter called event is misleading. It’s not actually an event, but is instead a reference to the form field, so we can remove the declaration of the variable called thefield, and use it instead in the function declaration.


function check__regular_text_field(thefield) {
    ...
}

Why is the regular expression constructor used instead of the regular expression literal? The constructor is normally reserved only for when you are creating expressions from unknown content, such as a user-supplied variables.


var re = {
    numbers: /\\d/,
    symbols: /[+.,*ª!"·$%&()= ?¿¡º\\^`´ç;:_\\-]/,
    ...
};

There’s also another trouble with the regular expressions, where you are black-listing instead of white-listing. By black-listing known numbers and symbols, you are leaving yourself wide open to thousands of other characters that you have not explicitly black-listed.

With the errorid variable, it’s used only once. Incorporating it in to the next line doesn’t lead to overly complicated code, so it seems right to combine the two.


error = document.getElementById(event.id + 'error'),

We still though have a large number of variables in the function:

thevalue = thefield.value,
    thevaluetolower = thevalue.toLowerCase(),
    firstchartoupper = thevaluetolower.charAt(0).toUpperCase() + thevaluetolower.slice(1),
    thevalueint = parseInt(thevalue.length, 10),
    error = document.getElementById(event.id + 'error'),
    errormessage = '',
    re = {
        numbers: /\\d/,
        symbols: /[+.,*ª!"·$%&()= ?¿¡º\\^`´ç;:_\\-]/,
        email: /^[a-zA-Z0-9._\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,4}$/,
        password: /(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/
    };

One effective improvement is to move some code out to a separate function.


function initialCase(value) {
    return value.charAt(0).toUpperCase() +
        value.slice(1).toLowerCase();
}

Now we can remove most of that from the variable declarations, and replace occurances of thevaluetolower and firstchartoupper with just thevalue. We can also remove the parseInt part, because the length is always going to be an integer, so we can make use of the length in the if condition, like this:


} else if (thevalue.length <= 1) {

That reduces the variable declarations to something that’s a bit more reasonable, to this:

var thevalue = initialCase(thefield.value),
    error = document.getElementById(event.id + 'error'),
    errormessage = '',
    re = {
        numbers: /\\d/,
        symbols: /[+.,*ª!"·$%&()= ?¿¡º\\^`´ç;:_\\-]/,
        email: /^[a-zA-Z0-9._\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,4}$/,
        password: /(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/
    };
...
} else if (thevalue.length &lt;= 1) {

Summary

A lot of little steps have been taken up to this point, so it’s now time to see the overall impact that this has had.

The code before the updates is:


NOnumbershere=new RegExp(/\\d/);
NOsymbolshere=new RegExp(/[+.,*ª!"·$%&()= ?¿¡º^`´ç;:_-]/);
emailpattern=new RegExp(/^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$/);
passwordpattern=new RegExp(/(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/);
function check__regular_text_field(event)
{
errorid = event.id + "error";
error = document.getElementById(errorid);
thefield=event;
thevalue=thefield.value;
thevaluetolower=thevalue.toLowerCase();
firstchartoupper = thevaluetolower.charAt(0).toUpperCase() + thevaluetolower.slice(1);
thevalueint = parseInt(thevalue.length);
if (NOnumbershere.test(thevaluetolower) == true && NOsymbolshere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_numbers_or_special_chars_error; ?>';
}
else if (NOnumbershere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_numbers_error; ?>';
}
else if (NOsymbolshere.test(thevaluetolower) == true)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $no_special_chars_error; ?>';
}
else if (thevalueint <= 1)
{
thefield.className = "incorrect_field";
error.innerHTML = '<img align="left" src="http://www.sitepoint.com/forums/images/warn.gif"/><?php echo $not_enough_chars_error; ?>';
}
else
{
thefield.className = "correct_field";
thefield.value = firstchartoupper;
error.innerHTML = "";
}
}

And the code after the updates is as follows:
(note: sitepoint’s highlight feature fails to parse the code properly due to the doublequote in the regular expression - the code is correct though)


function initialCase(value) {
    return value.charAt(0).toUpperCase() +
        value.slice(1).toLowerCase();
}
function check__regular_text_field(thefield) {
    var thevalue = thefield.value,
        error = document.getElementById(event.id + 'error'),
        errormessage = '',
        re = {
            numbers: /\\d/,
            symbols: /[+.,*ª!"·$%&()= ?¿¡º\\^`´ç;:_\\-]/,
            email: /^[a-zA-Z0-9._\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,4}$/,
            password: /(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\
])(?=.*[A-Z])(?=.*[a-z]).*$/
        };

    if (re.numbers.test(thevalue) && re.symbols.test(thevalue)) {
        errormessage = '&lt;?php echo $no_numbers_or_special_chars_error; ?&gt;';
    } else if (re.numbers.test(thevalue)) {
        errormessage = '&lt;?php echo $no_numbers_error; ?&gt;';
    } else if (re.symbols.test(thevalue)) {
        errormessage = '&lt;?php echo $no_special_chars_error; ?&gt;';
    } else if (thevalue.length &lt;= 1) {
        errormessage = '&lt;?php echo $not_enough_chars_error; ?&gt;';
    }
    if (errormessage &gt; '') {
        thefield.className = 'incorrect_field';
        error.innerHTML = '&lt;img align="left" src="/images/warn.gif"/&gt;' + errormessage;
    } else {
        thefield.className = 'correct_field';
        thefield.value = thevalue;
        error.innerHTML = "";
    }
}

There’s only a couple of significant things that might be done with the above code, but what we have there now is a pretty good start in the right direction.