How do I make jQuery Contains case insensitive, including jQuery 1.8+?
Asked Answered
O

6

94

I'm trying to use "contains" case insensitively. I tried using the solution at the following stackoverflow question, but it didn't work:

Is there a case insensitive jQuery :contains selector?

For convenience, the solution is copied here:

jQuery.extend(
        jQuery.expr[':'], { 
                Contains : "jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0" 
});

Here is the error:

Error: q is not a function
Source File: /js/jquery-1.4.js?ver=1.4
Line: 81

Here's where I'm using it:

  $('input.preset').keyup(function() {
    $(this).next().find("li").removeClass("bold");
    var theMatch = $(this).val();
    if (theMatch.length > 1){
      theMatch = "li:Contains('" + theMatch + "')";
      $(this).next().find(theMatch).addClass("bold");
    }
  });

My use of the original case sensitive "contains" in the same scenario works without any errors. Does anyone have any ideas? I'd appreciate it.

Orsa answered 4/2, 2010 at 0:51 Comment(3)
In case anyone is interested, I've updated my blog post on three additional contains selectors :containsExact, :containsExactCase and :containsRegex selectors to now work in all versions of jQuery.Slavonic
See css-tricks.com/snippets/jquery/…,Hawserlaid
I think .filter() is another good way. ReferenceStole
V
130

This is what i'm using in a current project, haven't had any problems. See if you have better luck with this format:

jQuery.expr[':'].Contains = function(a, i, m) { 
  return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; 
};

In jQuery 1.8 the API for this changed, the jQuery 1.8+ version of this would be:

jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
    return function( elem ) {
        return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

You can test it out here. For more detail on 1.8+ custom selectors, check out the Sizzle wiki here.

Vituline answered 4/2, 2010 at 0:59 Comment(6)
Any chance you could talk about exactly what this is doing?Greenleaf
@ClovisSix - thanks for the heads up, I provided a 1.8+ method of doing the same, let me know if you have any trouble.Vituline
Thanks for the 1.8 change. Had a similar extension that stopped working with with the 1.8 release. Saved my butt.Rosenberry
To Note that this does not replace :contains just add another selector :Contains.Assembled
the selector should be called icontains, or something similar.Hortenciahortensa
I'd suggest that it should be return arg != undefined && jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; to prevent javascript error in case contains is called with empty argFpc
F
43

It's worth noting that the answer is correct but only covers :Contains, and not the alias :contains which could lead to unexpected behavior (or could be used by design for advanced applications that require both sensitive and insensitive search).

This could be resolved by duplicating the extention for the alias:

jQuery.expr[':'].Contains = function(a, i, m) { 
  return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; 
};
jQuery.expr[':'].contains = function(a, i, m) { 
  return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; 
};

Took me a while to work out why it wasn't working for me.

Foxe answered 27/4, 2011 at 4:31 Comment(5)
I would have commented this on above, but apparently I'm not able to.Foxe
I'm not sure what you're getting at here. This overrides the expected, documented behavior of :contains. I think it's clearer to leave the original :contains alone and call your new selector :icontains.Luteolin
That's beside the point of my post. Creating an alternative selector is certainly a valid option, however I was pointing out that extending :contains, but neglecting to extend :Contains could lead to user confusion, when they yield different results.Foxe
Then thank you for sharing this "gotcha." :) Still, I think it's a good idea to mention that it's better not to override the built-in behavior when it's less work to build a non-destructive, parallel behavior.Luteolin
I tried a few different solutions posted for this and this one finally worked. thanks.Intermigration
R
28

I would do something like this

     $.expr[':'].containsIgnoreCase = function (n, i, m) {
        return jQuery(n).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
    };

And Leave :contains Alone...

DEMO

So why jQuery doesn't support it in it's library?! if it is that easy...

because Does your code pass the turkey code?

Redman answered 22/2, 2013 at 21:56 Comment(0)
T
6

May be late.... but,

I'd prefer to go this way..

$.extend($.expr[":"], {
"MyCaseInsensitiveContains": function(elem, i, match, array) {
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});

This way, you DO NOT tamper with jQuery's NATIVE '.contains'... You may need the default one later...if tampered with, you might find yourself back to stackOverFlow...

Topdrawer answered 27/5, 2013 at 16:16 Comment(0)
V
0

i'll allow myself to add my friends:

$.expr[":"].containsNoCase = function (el, i, m) { 
    var search = m[3]; 
    if (!search) return false; 
    return eval("/" + search + "/i").test($(el).text()); 
}; 
Vespid answered 11/2, 2014 at 8:38 Comment(0)
K
0

I was just able to ignore jQuery's case sensitivity altogether to achieve what I want using below code:

            $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function( elem ) {
                return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
            };
        });

You can use this link to find code based on your jQuery versions to ignore case sensitivity, https://css-tricks.com/snippets/jquery/make-jquery-contains-case-insensitive/

Also if you want to use :contains and make some search you may want to take a look at this: http://technarco.com/jquery/using-jquery-search-html-text-and-show-or-hide-accordingly

Kesha answered 11/1, 2016 at 11:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.