3

In my HTML there are number of divs each having names inside. I have to implement alphabetic filter in it. If user clicks on button 'A-J' the list will make only divs where first letter of name is between A-J and similarly for other letter groups. I have written following piece of code till now :

        $("#jfmfs-filter-selected-aj").click(function(event) {
            event.preventDefault();
            for (i = 0; i < all_friends.length ; i++)
            {
                var aFriend = $( all_friends[i] );
                if(!(/^[a-jA-J]+$/.test(aFriend.find(".friend-name").html().charAt(0)))){
                    aFriend.addClass("hide-filtered");
                }
            }
            $(".filter-link").removeClass("selected");
            $(this).addClass("selected");
        });

This Code works fine but hides div in a loop and hence it takes time. Is there a way i can write the above code in single line to add "hide-filtered" class to all divs which meets my criteria in one go Something like this?

all_friends.not( {divs with inner html starting with letters a-j} ).addClass("hide-non-selected");
all_friends.not( /^[a-jA-J]+$/.test(all_friends.find(".friend-name").html().charAt(0)) ).addClass("hide-non-selected");

Final Solution I used using jquery filter (Barmar's answer):

all_friends.filter(function() {
                      return(!(/^[a-fA-F]+$/.test($(this).find(".friend-name").html().charAt(0))))
                    }).addClass("hide-non-selected");
2
  • Looks like [this][1] is the kind of stuff you're looking for.. [1]: stackoverflow.com/questions/190253/… Commented Dec 1, 2012 at 9:04
  • @AidanEwen jQuery regex selectors can only be applied to attributes, not to text. Commented Dec 1, 2012 at 9:07

2 Answers 2

2

Try this:

var AJ_regex = /^[a-jA-J]/;
$('.friend-name', aFriend).filter(function() {
    return !(AJ_regex.test($(this).html()));
}).addClass("hide-filtered");
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks I have updated my question with the final solution I used.
The simplest and biggest efficiency saving you could make is to create the regular expression outside the loop (and .filter() is effectively a loop).
@Beetroot-Beetroot Thanks for the suggestion, I made that change to my answer. This also suggests that if he has different filters, he could use a single function and pass the RE as a parameter.
By the way, your solution (before moving the regexp out of the loop), although concise, is probably less efficient than the OP's original in that it loops three times - once to apply the selector, once to filter, and once to apply the class. Only the first is a big deal. On efficiency grounds, it is better to use a preformed collection rather than make a new one, especially when making/changing the selection involves the DOM.
@Beetroot-Beetroot That's probably true of many chained jQuery operations, since each step in the chain is another loop over the collection, and this is a common idiom. It's not usually a problem if the collection is small.
|
0

Have a look at this jquery filter by James Padolsey. It looks like you could use this to do the kind of thing you're looking for.

For your purposes it would look something like -

$('div.friend-name').filter('div:regex(innerHTML, ^[a-jA-J])').addClass("hide-non-selected");

(that will probably need tweaking - I've not tested it).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.