A jQuery 'if' condition to check multiple values - javascript

In the code below, is there a better way to check the condition using jQuery?
if(($('#test1').val() == 'first_value')||($('#test2').val() == 'second_value') && ($('#test3').val()!='third_value')|| ($('#test4').val()!='fourth_value'))

Unless there are other concerns, like if you will reuse the #test1, ... fields for more processing, yours should be good.
If you will fetch any of the values again to do something I would recommend storing the $('#test1') result in a variable so that you do not need to requery the dom.
Ex:
var t1 = $('#test1');
if((t1.val() == 'first_value')||($('#test2').val() == 'second_value') && ($('#test3').val()!='third_value')|| ($('#test4').val()!='fourth_value')) {
t1.val('Set new value');
}
This also improves readability of the row ;)

var values = ['first_value', 'second_value', 'third_value', 'fourth_value'];
$('#test1, #test2, #test3, #test4').each(function(index, el) {
if($.inArray(this.value, values)) {
// do some job;
return false; // or break;
}
});

var c=0, b='#test', a=['first_value','second_value','third_value','fourth_value'];
for(var i=0; i<4; i++)
if($(b+i).val() == a[i])
c=1;
if (c) //Do stuff here
This will decrease your code size by 25 bytes;-)

Demo: just another idea is at http://jsfiddle.net/h3qJB/. Please let me know how it goes.
You can also do chaining like:
$('#test1, #test2, #test3, #test4').each(function(){ //...use this.value here });
It might be that De Morgan's laws gives you an idea of how to make the logic a bit more compact (although I am not sure what is the specific case or is it as simple as comparing values).
Code
var boolean1 = (($('#test1').val() == 'first_value')||($('#test2').val() == 'second_value'))
var boolean2 = (($('#test3').val()!='third_value')|| ($('#test4').val()!='fourth_value'))
if (boolean1 && boolean2)
alert("bingo");
else
alert("buzzinga");

Related

what is the order of boolean logic in Javascript?

I wanted to use two Not and one and in booleans to test if the variable is neither upper case nor lower case.
I used this code so far but it didn't work as required:
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toLowerCase()) ){
x.splice(x[i], 1);
}
This code was for a function that sorts entered strings yet uppercase are sorted first.
Here is the full code, I am also open to understanding better ways to create this function apart from boolean logic and the array methods I used.
function alpha(str){ // United States
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
for (var i = 0; i<x.length; i++){
if (x[i] == x[i].toUpperCase()){
cap.push(x[i]);
}
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toUpperCase()) ) {
x.splice(x[i], 1);
}
else {small.push(x[i]);}
}
var z = cap.sort();
var y = small.sort();
return z.concat(y).join("");
}
Please note the second else if statement is only useful because the code adds an empty space string at the beginning of the output, I'm not sure where it comes from, so please let me know if you have any idea how to sort this even without using the second else if.
In the ASCII table, upper case letters come first. That's why they come first when you sort alphabetically. Here's a link to a page on Wikipedia that shows the table with the upper case letters appearing first and their numerical equivalents. It's even printable.
Also, I took the liberty of simplifying your code a little. Seems like .splice() was not necessary.
function alpha( str ) {
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
var length = x.length;
for (var i = 0; i < length; i++) {
if (x[i] === x[i].toUpperCase()) {
cap.push(x[i]);
} else if (x[i] === x[i].toLowerCase()) {
small.push(x[i]);
}
}
return cap.sort().concat(small.sort()).join("");
}
Maybe explain what you're trying to do? It most likely has been done before in some form and you definitely came to the right place to find an answer.
Is this what you want to do?
var str = "United States";
function alpha(str) {
return str.split('').sort().join('');
}
alert(alpha(str));
In all programming languages (as far as i know), boolean expressions are always evaluated from the left to the right with brackets of course.
So in the following example my_func() is called first, and then if there is the chance that the complete expression becomes true my_other_func() is called
if (my_func() && my_other_func()) {
// I only get here if my_func() AND my_other_func() return true
// If my_func() returns false, my_other_func() is never called
}
The same is true for the "or" operator in the following example
if (my_func() || my_other_func()) {
// I only get here if my_func() OR my_other_func() return true
// If my_func() returns true, my_other_func() is not called
}
So back to your code, in details this part (I reformated it a bit for better readability):
if (x[i] == x[i].toUpperCase()){
// only uppercase here
cap.push(x[i]);
} else if (x[i] !== x[i].toUpperCase() && x[i] !== x[i].toUpperCase()) {
// tested twice the same thing, so Im really sure that its not uppercase :D
// only lowercase here
x.splice(x[i], 1);
} else {
// I will never reach this
small.push(x[i]);
}
Im not sure what you want to do, but I hope the comments help to understand your code.

Loop through array checking for indexOf's more simple?

Okay, like the title says. I have a array looking like this:
var hiTriggers = new Array();
hiTriggers = ["hi", "hai", "hello"];
And I'd like to check through it if it finds either of those. I can already achieve this by doing the following:
if(message.indexOf("hi") >= 0) {
// do whatever here!
}
But I'm looking for an more efficient way rather than doing 100 if() checks. Such as loop through an array with the "hiTriggers".
I tried the following:
for(var i; i < hiTriggers.length; i++) {
console.log(hiTriggers[i]); // simply to know if it checked them through)
if(message.indexOf(hiTriggers[i]) >= 0) {
//do stuff here
}
}
Which sadly did not work as I wanted as it does not check at all.
Thanks in advance and I hope I made sense with my post!
Edit; please note that I have 'messaged' already 'declared' at another place.
It doesn't run because you didn't give the i variable an initial value. It is undefined.
Change to use var i=0;:
for(var i=0; i < hiTriggers.length; i++) {
//console.log(hiTriggers[i]); // simply to know if it checked them through)
if(message.indexOf(hiTriggers[i]) >= 0) {
//do stuff here
console.log("found " + hiTriggers[i]);
}
}
Try using a regular expression to match the message. The \b is a word boundary marker, and the words between the | characters are what is being searched for. If any of the words appear in the message, then message.match will return the array of matches, otherwise null.
var pattern = /\b(Hello|Hi|Hiya)\b/i;
var message = "Hello World";
if (message.match(pattern))
{
console.log("do stuff");
}
You can write even simpler using a for in loop:
for(var v in hiTriggers){
if(message.indexOf(hiTriggers[v]) >= 0) {
//do stuff here
console.log("found " + hiTriggers[v]);
}
}
Problem is becoz - you have not initialized your var i, make it var i = 0;
You can try forEach loop.
hiTriggers.forEach(function(e) {
if(message.indexOf(e) >= 0) {
//do sthg here
}
})

Iterate through all but one elements in a form

I would love my while to iterate through all but one of the elements in the form. This is my code:
while (i < elnum && !empty) {
if (form.elements[i].value == "" && form.elements[i] != form.referral) {
error.innerHTML += 'All fields are required.</br>';
empty = true;
}
i++;
}
Where elnum is the number of elements.
Unfortunately, even if I leave only form.referral empty, it still enters inside the if. Basically, I want the check to be done for all fields but for that one.
Rather than trying to compare elements, try something like this:
if( form.elements[i].name == "referral") continue;
Put that just inside the loop, before the condition to check for an empty value.
That being said, it might be better to do something like this:
while(i < elnum) {
if( form.elements[i].hasAttribute("required") && form.elements[i].value == "") {
error.innerHTML += "All fields are required.<br />";
// re-add `empty=true` if the variable is needed elsewhere
// if it's only used to end the loop, then this is better:
break;
}
i++;
}
And make sure you add the required attribute to all required fields. This is a better solution because then it will take advantage of the browser's native ability to handle HTML5 forms, if it has any.

Multiple OR operators with elem.value.match

I've been writing a javascript function which returns true if the value matches one of about 4 values (just 3 in the example below). The problem is, when I have just two values the function works correctly, but adding a third breaks the code.
I'm pretty new to javascript and I'm guessing there's a much better way of doing this? I've tried searching but found nothing as of yet.
Any help is much appreciated.
function isValid(elem, helperMsg){
var sn6 = /[sS][nN]6/;
var sn5 = /[sS][nN]5/;
var sn38 = /[sS][nN]38/;
if(elem.value.match(sn6 || sn5 || sn38)){
//do stuff
return true;
}else{
return false;
}
}
Edit:
Here's my second attempt with an array:
function isLocal(elem, helperMsg){
var validPostcodes=new Array();
validPostcodes[0]= /[wW][rR]12/;
validPostcodes[1]= /[cC][vV]35/;
validPostcodes[2]= /[sS][nN]99/;
validPostcodes[3]= /[sS][nN]6/;
validPostcodes[4]= /[sS][nN]5/;
validPostcodes[5]= /[sS][nN]38/;
validPostcodes[6]= /[oO][xX]29/;
validPostcodes[7]= /[oO][xX]28/;
var i = 0;
for (i = 0; i < validPostcodes.length; ++i) {
if(elem.value.match(validPostcodes[i])){
// do stuff
return true;
}else{
alert(helperMsg);
elem.focus();
return false;
}
}
}
a || b || c
is an expression that evaluates to a boolean. That means that you're running either match(true) or match(false). You must write it as:
match(a) || match(b) || match(c)
Another option would be to store them in an array and loop over it. That would mean if the number of patterns grew you wouldn't have to change code other than the list of patterns. Another approach, though limited to this situation, might be to change the pattern to one that is equivalent to or-ing the three options together (untested, and I'm a bit rusty on regex):
elem.value.match(/[sSnN][6|5|38]/)
Array based example:
var patterns = [/../, /.../];
for (var i = 0; i < patterns.length; ++i) {
if (elem.value.match(patterns[i])) { return true; }
}
In real code, I would probably format it like this:
function isValid(elem, helperMsg){
var patterns = [/../, /.../],
i = 0;
for (i = 0; i < patterns.length; ++i) {
if (elem.value.match(patterns[i])) {
return true;
}
}
}
That's just a habit though since JavaScript hoists variables to the top of their scope. It's by no means required to declare the variables like that.

How to construct a string which will pass if(variable)

I'm a jquery novice. I've boiled my code down to the simplest way to describe my problem. But I am having trouble wording it.
if(var1 && var2){
// this works
}
searchMe = var1+" && "+var2;
if(searchMe){
// this doesn't work
}
searchMe = "var1"+" && "+"var2";
if(searchMe){
// still doesn't work
}
I would like to be able to construct that "searchMe" variable based on user input. Can someone tell me a better way to do this? Thanks!
Not sure but you can make use of eval function
if(eval(searchMe)){
// this doesn't work
}
A possible way to do this without the dreaded eval (which really, you should never use) is to just evaluate as you go, and then end up with one variable at the end which is boolean.
var a = true;
var b = a && (false || true) && (1 < 2);
if (b)
document.write('yes');
else
document.write('no');
var c = b && false;
document.write(', ');
if (c)
document.write('yes');
else
document.write('no');
To relate it to your example
searchMe = var1 && var2;
if(searchMe){
// this does work
}

Categories