How to write ternary operator condition in jQuery?
Asked Answered
D

9

38

In this fiddle http://jsfiddle.net/mjmitche/6nar4/3/, if you drag, for example, the little blue box into the yellow box, then the big black box will turn pink. All of the 4 boxes along the left can be dragged into the boxes inside the black box.

At the end of the fiddle, you see the code that changes the black box to pink.

However, I want to make that a ternary operator, so that if the box is black, then it turns pink, but if it's been turned pink, then I want it to go back to black.

I know the ternary is like this

x ? y: z

So I tried this, even though I knew it wasn't probably right

$("#blackbox").css({'background':'pink'}); ?

    $("#blackbox").css({'background':'black'}); : 

$("#blackbox").css({'background':'pink'}); 

I think the first line before the question mark is causing the problem, so how to create the if statement?

Dextrosinistral answered 6/7, 2011 at 11:24 Comment(0)
S
74

I would go with such code:

var oBox = $("#blackbox");
var curClass = oBox.attr("class");
var newClass = (curClass == "bg_black") ? "bg_pink" : "bg_black";
oBox.removeClass().addClass(newClass);

To have it working, you first have to change your CSS and remove the background from the #blackbox declaration, add those two classes:

.bg_black { background-color: #000; }
.bg_pink { background-color: pink; }

And assign the class bg_black to the blackbox element initially.

Updated jsFiddle: http://jsfiddle.net/6nar4/17/

In my opinion it's more readable than the other answers but it's up to you to choose of course.

Signatory answered 6/7, 2011 at 11:53 Comment(0)
C
5

I think Dan and Nicola have suitable corrected code, however you may not be clear on why the original code didn't work.

What has been called here a "ternary operator" is called a conditional operator in ECMA-262 section 11.12. It has the form:

LogicalORExpression ? AssignmentExpression : AssignmentExpression

The LogicalORExpression is evaluated and the returned value converted to Boolean (just like an expression in an if condition). If it evaluates to true, then the first AssignmentExpression is evaluated and the returned value returned, otherwise the second is evaluated and returned.

The error in the original code is the extra semi-colons that change the attempted conditional operator into a series of statements with syntax errors.

Catamount answered 6/7, 2011 at 13:59 Comment(0)
C
4

I'd do (added caching):

var bbx = $("#blackbox");
 bbx.css('background-color') === 'rgb(255, 192, 203)' ? bbx.css('background','black') : bbx.css('background','pink')

wroking fiddle (new AGAIN): http://jsfiddle.net/6nar4/37/

I had to change the first operator as css() returns the rgb value of the color

Cinchonism answered 6/7, 2011 at 11:28 Comment(5)
Thanks. In the context of my fiddle, does it need extra brackets? I can't get it to work? jsfiddle.net/mjmitche/6nar4/6Dextrosinistral
sorry, i had a type in there, use commas instead of ':' (in any case your fiddle has some problems on firefox 5)Cinchonism
thanks, but in your fiddle, once the box turns pink, it won't change back to black again. Do you know how to fix it?Dextrosinistral
how exactly do you want it to work?Right now it checks if the background color of the big square is black, if it is black it turns it into pink. do you want to it switch back to black if it's pink?Cinchonism
Some characthers got messed up sorry, this is not my lucky post. try it jsfiddle.net/6nar4/37Cinchonism
D
2

The Ternary operator is just written as a boolean expression followed by a questionmark and then two further expressions separated by a colon.

The first thing that I can see that you have got wrong is that your first expression isn't returning a boolean or anything sensible that could be converted to a boolean. Your first expression is always going to return a jQuery object that has no sensible interpretation as a boolean and what it does convert to is probably an unchanging interpretation. You are always best off returning something that has a well known boolean interpretation, if nothign else for the sake of readability.

The second thing is that you are putting a semicolon after each of your expressions which is wrong. In effect this is saying "end of construct" and so is breaking your ternary operator.

In this situation though you probably can do this a more easy way. If you use classes and the toggleClass method then you can easily get it to switch a class on and off and then you can put your styles in that class definition (Kudos to @yoavmatchulsky for suggesting use of classes up there in comments).

A fiddle of this is found here: http://jsfiddle.net/chrisvenus/wSMnV/ (based on the original)

Duntson answered 6/7, 2011 at 11:45 Comment(2)
Wrong for the same reason the others are. The expression doesn't need to return true or false - step 3 of processing a conditional operator (ECMA-262 11.12) is Call ToBoolean(Result(2)). If the result was expected to be Boolean, there would be no need to call ToBoolean (an error would probably be thrown).Catamount
@RobG: even if it isn't of the type Boolean it should be somethign that can be sensibly converted to a boolean. Most things can be converted to a boolean but that doesn't mean it is sensible to do so. I would say that in this context a jQuery object doesn't count as a boolean because there is no real sensible way to say if a jquery object is true or false whereas if you have an int or a text string there are sensible things that can be done to convert them. I'll edit to make that clearer though.Duntson
P
1

Ternary operator works because the first part of it returns a Boolean value. In your case, jQuery's css method returns the jQuery object, thus not valid for ternary operation.

Psychasthenia answered 6/7, 2011 at 11:27 Comment(1)
-1 because the first statement is plain wrong, read ECMA-262 section 11.12. It doesn't work because of the semi-colons.Catamount
M
1

From what it looks like you are trying to do, toggle might better solve your problem.

EDIT: Sorry, toggle is just visibility, I don't think it will help your bg color toggling.

But here you go:

var box = $("#blackbox");
box.css('background') == 'pink' ? box.css({'background':'black'}) : box.css({'background':'pink'}); 
Mackie answered 6/7, 2011 at 11:29 Comment(2)
o.k, I have that inside my fiddle, but it's not working, do I need extra parentheses jsfiddle.net/mjmitche/6nar4/7Dextrosinistral
Yeah, I left an extra close parentheses in there, fixedMackie
M
1

Here is a working example in side a function:

function setCurrency(){
   var returnCurrent;
   $("#RequestCurrencyType").is(":checked") === true ? returnCurrent = 'Dollar': returnCurrent = 'Euro';
   
   return returnCurrent;
}

In your case. Change the selector and the return values

$("#blackbox").css('background-color') === 'pink' ? return "black" : return "pink";

lastly, to know what is the value used by the browser run the following in the console:

$("#blackbox").css('background-color')

and use the "rgb(xxx.xxx.xxx)" value instead of the Hex for the color selection.

Mealymouthed answered 12/8, 2019 at 13:7 Comment(0)
W
0

Also, the ternary operator expects expressions, not statements. Do not use semicolons, only at the end of the ternary op.

$("#blackbox").css({'background': 
    $("#blackbox").css('background') === 'pink' ? 'black' : 'pink'});
Wriggle answered 6/7, 2011 at 11:29 Comment(1)
Thanks, but I can't get yours to work. Any ideas? jsfiddle.net/mjmitche/6nar4/19Dextrosinistral
C
0

As others have correctly pointed out, the first part of the ternary needs to return true or false and in your question the return value is a jQuery object.

The problem that you may have in the comparison is that the web color will be converted to RGB so you have to text for that in the ternary condition.

So with the CSS:

#blackbox {
    background:pink;
    width:10px;
    height:10px;
}

The following jQuery will flip the colour:

var b = $('#blackbox');
b.css('background', (b.css('backgroundColor') === 'rgb(255, 192, 203)' ? 'black' : 'pink'));

Demo

Cohen answered 6/7, 2011 at 13:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.