Dan
Dan

Reputation: 10351

If/else conditional based on character count jQuery

I'm trying to create a jQuery function that counts the character length of each anchor tag & applies a class if the character count is greater than "5". Additionally, if the character count is greater than 7 (4 + 3) then apply a different class.

This is where I got to (JSFIDDLE: http://jsfiddle.net/2mg3q/):

HTML

<div id="global-nav">
    <ul id="nav">
        <li><a href="#">One</a></li>
        <li><a href="#">Item5</a></li>
        <li><a href="#">Item with11</a></li>
        <li><a href="#">One</a></li>
    </ul>
</div>

CSS

#nav{
    list-style:none;
    margin:0;
    padding:0;
}
#nav li a{
    display:block;
    padding:5px;
    border:1px solid #ccc;
}

#nav li a.TEST1{
    border-color:red;
}

#nav li a.TEST2{
    border-color:blue;
}

JS

var navChars = 4;

$('#global-nav #nav li a').filter(function() {

    if($(this).text().length > navChars){
        $('#global-nav #nav li a').addClass('TEST1');

    }else if($(this).text().length > navChars + 3){
        $('#global-nav #nav li a').addClass('TEST2');
    }

});

Without the "else" statement, both TEST1 & TEST2 classes were being applied to the anchor tags. With the else statement, only TEST1 is applied to the anchor tags.

The original JS I was using & that I have based the above on worked great for a singular condition but now I need to accommodate for at least 2 possible character lengths.

Original JS that I have altered (hacked):

var navChars = 13;

$('#global-nav #nav li a').filter(function() {
    return $(this).text().length > navChars;
}).addClass('navMultiLine');

Upvotes: 0

Views: 6462

Answers (9)

marsze
marsze

Reputation: 17084

The single-line filter does not work, because it will apply the class only for those objects, for which the condition is true.

Also, mind the order of conditions, it's crucial here! (Longest lengths first!)

Try this:

$('#global-nav #nav li a').each(function() {
    // save this jQuery-obj & it's length, for better performance!
    var $obj = $(this);
    var charLen = $obj.text().length;
    // mind the order of conditions! longest lengths first!
    if (charLen > navChars + X) {
        $obj.addClass('TestX');
    }
    else if (charLen > navChars + 3) {
        $obj.addClass('Test2');
    }
    else if (charLen > navChars) {
        $obj.addClass('Test1');
    }
});

Upvotes: 1

Bas van Dijk
Bas van Dijk

Reputation: 10713

This is a solution with an each loop. You made probably a typo by using #global-nav in your HTML instead of id="gobal-nav"

The fiddle could be found at http://jsfiddle.net/3DU9t/

var navChars = 4;

$('#global-nav #nav a').each(function() {

    if($(this).html().length > navChars + 3){

        $(this).addClass('TEST2');

    } else {

        if($(this).html().length > navChars){
            $(this).addClass('TEST1');

        }

    }

});

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388406

id should not start with #

<div id="global-nav">

then

$('#global-nav #nav li a').each(function () {
    var $this = $(this),
        length = $.trim($this.text()).length;
    if (length > navChars + 3) {
        $this.addClass('TEST2');
    } else if (length > navChars) {
        $this.addClass('TEST1');
    }
});

Demo: Fiddle

Upvotes: 2

Thayne
Thayne

Reputation: 7002

The line $('#global-nav #nav li a').addClass('TEST1'); adds the TEST1 class to ALL links inside a li inside a #nav inside a #global-nav. In order to just apply the class to the current element you should use $(this).addClass('TEST1'). Also, you should use .each() to iterate over the elements instead of .filter().

Also, @Arun was referring to the id in the HTML, not in the javascript.

Upvotes: 1

Pete TNT
Pete TNT

Reputation: 8403

var navChars = 4;

$('#global-nav #nav li a').filter(function() {

//bigger than 4 but smaller than 7
if($(this).text().length > navChars && $(this).text().length < 7){
    $('#global-nav #nav li a').addClass('TEST1');

}
//bigger than 7 
if($(this).text().length > navChars+3){
    $('#global-nav #nav li a').addClass('TEST2');
}

});

Upvotes: 1

codingrose
codingrose

Reputation: 15709

Replace

<div id="#global-nav">

with

<div id="global-nav">

Try:

$('#global-nav #nav li').each(function() {
    var len = $(this).find("a").text().length;    
    if(len > 7){
        $(this).find("a").addClass("TEST2");
    }
    else if(len > 4){
        $(this).find("a").addClass("TEST1");
    }
});

DEMO here.

Upvotes: 5

When the condition is FIRST - if > 4 SECOND - if > 7 then the second gets never hit.. You should change the order to: FIRST - if > 7 SECOND -if > 4

Upvotes: 1

tewathia
tewathia

Reputation: 7308

Remove the else statement and remove the Test1 class for the second condition.

var navChars = 4;

$('#global-nav #nav li a').filter(function() {

    if($(this).text().length > navChars){
        $('#global-nav #nav li a').addClass('TEST1');

    }
    if($(this).text().length > navChars + 3){
        $('#global-nav #nav li a').removeClass('TEST1');
        $('#global-nav #nav li a').addClass('TEST2');
    }

});

Upvotes: 0

Ringo
Ringo

Reputation: 3965

Try this:

var navChars = 4;

$('#global-nav #nav li a').filter(function() {

    if($(this).text().length > navChars){
        $('#global-nav #nav li a').addClass('TEST1');

    }else if($(this).text().length > Number(navChars + 3)){
        $('#global-nav #nav li a').addClass('TEST2');
    }

});

Upvotes: -1

Related Questions