Is there a case insensitive version of the :contains jQuery selector or should I do the work manually by looping over all elements and comparing their .text() to my string?
- 2For jQuery 8.1 + check this answerPraveen– Praveen2013-12-03 12:15:41 +00:00Commented Dec 3, 2013 at 12:15
- 1^ That's 1.8.1, not 8.1.TylerH– TylerH2015-11-02 17:04:22 +00:00Commented Nov 2, 2015 at 17:04
- Good example here.劉鎮瑲– 劉鎮瑲2020-01-14 09:19:40 +00:00Commented Jan 14, 2020 at 9:19
12 Answers
What I ended up doing for jQuery 1.2 is :
jQuery.extend( jQuery.expr[':'], { Contains : "jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0" }); This will extend jquery to have a :Contains selector that is case insensitive, the :contains selector remains unchanged.
Edit: For jQuery 1.3 (thanks @user95227) and later you need
jQuery.expr[':'].Contains = function(a,i,m){ return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0; }; Edit: Apparently accessing the DOM directly by using
(a.textContent || a.innerText || "") instead of
jQuery(a).text() In the previous expression speeds it up considerably so try at your own risk if speed is an issue. (see @John 's question)
Latest edit: For jQuery 1.8 it should be:
jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) { return function( elem ) { return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); 3 Comments
To make it optionally case insensitive: http://bugs.jquery.com/ticket/278
$.extend($.expr[':'], { 'containsi': function(elem, i, match, array) { return (elem.textContent || elem.innerText || '').toLowerCase() .indexOf((match[3] || "").toLowerCase()) >= 0; } }); then use :containsi instead of :contains
2 Comments
If someone (like me) is interested what do a and m[3] mean in Contains definition.
KEY/LEGEND: Params made available by jQuery for use in the selector definitions:
r = jQuery array of elements being scrutinised. (eg: r.length = Number of elements)
i = index of element currently under scrutiny, within array r.
a = element currently under scrutiny. Selector statement must return true to include it in its matched results.
m[2] = nodeName or * that we a looking for (left of colon).
m[3] = param passed into the :selector(param). Typically an index number, as in :nth-of-type(5), or a string, as in :color(blue).
Comments
In jQuery 1.8 you will need to use
jQuery.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) { return function (elem) { return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); A variation that seems to perform slightly faster and that also allows regular expressions is:
jQuery.extend ( jQuery.expr[':'].containsCI = function (a, i, m) { //-- faster than jQuery(a).text() var sText = (a.textContent || a.innerText || ""); var zRegExp = new RegExp (m[3], 'i'); return zRegExp.test (sText); } ); Not only is this case-insensitive, but it allows powerful searches like:
$("p:containsCI('\\bup\\b')")(Matches "Up" or "up", but not "upper", "wakeup", etc.)$("p:containsCI('(?:Red|Blue) state')")(Matches "red state" or "blue state", but not "up state", etc.)$("p:containsCI('^\\s*Stocks?')")(Matches "stock" or "stocks", but only at the start of the paragraph (ignoring any leading whitespace).)
Comments
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...
Comments
jQuery.expr[':'].contains = function(a,i,m){ return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0; }; The update code works great in 1.3, but "contains" should be lower case on the first letter unlike the previous example.
Refer below to use ":contains" to find text ignoring its case sensitivity from an HTML code,
$.expr[":"].contains = $.expr.createPseudo(function(arg) { return function( elem ) { return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); $("#searchTextBox").keypress(function() { if($("#searchTextBox").val().length > 0){ $(".rows").css("display","none"); var userSerarchField = $("#searchTextBox").val(); $(".rows:contains('"+ userSerarchField +"')").css("display","block"); } else { $(".rows").css("display","block"); } }); You can also use this link to find case ignoring code based on your jquery version, Make jQuery :contains Case-Insensitive
Comments
A faster version using regular expressions.
$.expr[':'].icontains = function(el, i, m) { // checks for substring (case insensitive) var search = m[3]; if (!search) return false; var pattern = new RegExp(search, 'i'); return pattern.test($(el).text()); }; 1 Comment
I had a similar problem with the following not working...
// This doesn't catch flac or Flac $('div.story span.Quality:not(:contains("FLAC"))').css("background-color", 'yellow'); This works and without the need for an extension
$('div.story span.Quality:not([data*="flac"])').css("background-color", 'yellow'); This works too, but probably falls into the "manually looping" category....
$('div.story span.Quality').contents().filter(function() { return !/flac/i.test(this.nodeValue); }).parent().css("background-color", 'yellow'); Comments
New a variable I give it name subString and put string you want to search in some elements text. Then using Jquery selector select elements you need like my example $("elementsYouNeed") and filter by .filter(). In the .filter() it will compare each elements in $("elementsYouNeed") with the function.
In the function i using .toLowerCase() for element text also subString that can avoid case sensitive condition and check if there is a subString in it. After that the .filter() method constructs a new jQuery object from a subset of the matching elements.
Now you can get the match elements in matchObjects and do whatever you want.
var subString ="string you want to match".toLowerCase(); var matchObjects = $("elementsYouNeed").filter(function () {return $(this).text().toLowerCase().indexOf(subString) > -1;});