Monday, October 27, 2008

jQuery If, ElseIf, and Else plugin

Update
Guys, I have to admit I created silly prototypes while all I need were much more simpler than I though :) Enjoy last version!
-------------------------------------

Try to imagine a page like this one:

<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</body>


.. and now try to imagine something like this:

function oddNumbers(){
// return true if element contain an odd number
return $(this).text() & 1;
};

$(function(){
$("div")
.If(function(){return $(this).text() == "3" || $(this).text() == "5"})
.text("match the 3 or 5 check")
.ElseIf(oddNumbers)
.text("odd numbers")
.ElseIf(function(){return $(this).text() == 2})
.Do(function(){ // if you need a closure ...
$(this).text("text is equal 2");
})
.ElseIf(function(){return $(this).text() == 6})
.text("match the 6 condition")
.Else()
.text("this is 4 or 8");
;
})


... now, try to imagine I created a plugin like this:


;jQuery.fn.extend({
// Andrea Giammarchi - Mit Style Licence - V0.1f
If:function(fn){
var $ = this.filter(fn);
$.__If__ = this.filter(function(){return !~$.index(this)});
return $;
},
ElseIf:function(fn){
var $ = this.__If__.filter(fn);
$.__If__ = this.__If__.filter(function(){return !~$.index(this)});
return $;
},
Else:function(){
return this.__If__;
},
Do:jQuery.fn.each
});


... and now try to enjoy it :D

Kind Regards

8 comments:

Már Örlygsson said...

This was my solution for the same thing:

jQuery.fn.extend({
  if_: function (cond)
  {
    if ($.isFunction(cond)) { cond = cond.call(this); }
    this.if_CondMet = !!cond;
    return this.pushStack(cond ? this : []);
  },
  else_: function (cond)
  {
    var _this = this.end();
    return _this.if_CondMet ?
                _this.pushStack([]):
                _this.if_(arguments.length ? cond : 1);
  },
});

Note how the .else_() method doubles as an "elseif" if you pass an argument to it.

Andrea Giammarchi said...

Már Örlygsson, with the same output and this code

$(function(){
$("div")
.if_(function(){return $(this).text() == "3" || $(this).text() == "5"})
.text("1 - match the 3 or 5 check")
.else_(oddNumbers)
.text("2 - odd numbers")
.else_(function(){return $(this).text() == 2})
.text("3 - text is equal 2")
.else_(function(){return $(this).text() == 6})
.text("4 - match the 6 condition")
.else_()
.text("5 - this is 4 or 8");
;
})

nothing works as expected, the last in the chain overwrite everything or, without, nothing happen. Am I missing something?

Már Örlygsson said...

It seems we're calling the condition-function differently ... and thus solving slightly different problems. :-)

Yours uses `this.filter(fn)`, always running `fn` `this.length` times to build (filter) a new jQuery collection to pass into the condition block.

Mine performs a single `fn.call(this)` returning a simple boolean to decide if the current jQuery object should be passed into the condition block.

Yours is really a beefed up `.filter()`, while mine is a more an implementation of traditional traditional if-else directives.

Már Örlygsson said...

Here's how it might be uesd:

var cond1 = function(){ return this.length % 2; },
    cond2 = function(){ return !cond1.call(this.slice(1)); };

jQuery('p:first')
    .if_(cond1)
        .css('color', 'red')
    .else_(cond2)
        .css('color', 'green')
    .else_()
        .css('color', 'blue')
    .end();

Lars Gunther (itpastorn) said...

Off topic. may i remind you of my question I sent on facebook? (since I don't have your email.)

Andrea Giammarchi said...

Hi Lars, I replied on facebook but generally speaking, please do not write off topics replies, thank you :-)

Magnus Erichsen said...

Hey Andrea

I'm making a website where I have a javascript/jqueried "lightbox"-esque image portfolio which looks something like this. clicknext is applied to a image which works as a button.


$(document).ready(function(){
$("#next").click(function clicknext(){
if (proj=1)
{

if (proj1=1) {

document.getElementById("c1").src ="Website 2.0/Img/ws2_tstimage2.gif";
proj11=2;
return;


} else if (proj11=2){

document.getElementById("c1").src ="Website 2.0/Img/ws2_tstimage3.gif";
proj11=3;
return;


}else{

//return to portfolio

}
}
else if (proj=2)
{
//have the same happen here for other project's images
}

});
});

There will also be a back button which will go back to the previous image or, if on the first image, back to the portfolio. But I think the if else if else isn't working somehow, because it only opens the next image on the first click (ws2_tstimage2.gif), but won' work the second time (ws2_tstimage3.gif). I'd like to try your alternative, but I'm unsure where the values go (or if it will still work today?) That is to say, where the name of the variable goes, where the value goes, and where the code I want executed goes.

As you might guess I'm pretty new to this, so every bit of help is appreciated.

Thanks!
Magnus

macem said...

I look for this, nice and flexible.