6

I'm using following line and I would like to make it case-insensitive:

var matches = $(this).find('div > span > div#id_to_find[attributeName ^= "filter"]');
if (matches.length > 0) {
}

My question is that how can I make the selector ^= to be case-insensitive? Maybe changing to filter and then some regexp?

Tx3
  • 6,796
  • 4
  • 37
  • 52
  • I thing here is the answer too: http://stackoverflow.com/questions/187537/is-there-a-case-insensitive-jquery-contains-selector – Diego Oct 19 '10 at 11:42

3 Answers3

9

To do a case-insensitive attribute selection, you need to write a custom selector function.

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {
    var opts = meta[3].match(/(.*)\s*,\s*(.*)/);
    return (opts[1] in obj) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0);
};

You can use this like this:

$('input:iAttrStart(type, r)')

This will match any input elements whose type attribute begins with R or r (so it would match RADIO, radio, RESET or reset). This is a pretty silly example, but it should do what you need.


Re the comment that the function is hard to understand, I'll explain it a little.

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {

This is the standard signature for creating custom selectors.

var opts = meta[3].match(/(.*)\s*,\s*(.*)/);

meta is an array of details about the call. meta[3] is the string passed as the parameter. In my example, this is type, r. The regex matches type and r separately.

return (opts[1] in obj) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0);

Return if both these are true:

  1. The requested attribute exists on this object (opts[1] in obj)
  2. The search term (changed to lower-case) is found at the very beginning of the element's attribute value, also changed to lower case.

I could have made this easier to read using jQuery syntax rather than native JS syntax, but that would have meant reduced performance.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • Thanks for the solution! Took little bit time to figure out what function does, but now when I understand it's kinda nice. – Tx3 Oct 19 '10 at 14:22
2

Here you can see:

http://www.ericmmartin.com/creating-a-custom-jquery-selector/

What you have to do is to create a custom jquery selector:

jQuery.extend(jQuery.expr[':'], {
    exactIgnoreCase: "(a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase() == (m[3]).toLowerCase()"
});

And then just use it:

$("#detail select.fields option:exactIgnoreCase(" + q.val() + "):first");
Diego
  • 16,436
  • 26
  • 84
  • 136
0

There's a slight problem when using lonesomeday's answer.

To reproduce the error, try this: HTML tag on page is a common Facebook meta tag:

<meta content="Title of og tag" property="og:title" />

Selector:

$('meta:attrCaseInsensitive(property, og:site_name)')

This will not work. The reason is because when the selector code gets to the statement (opts[1] in obj) it will execute ("property" in obj) which returns false. (I don't know why)

To fix this problem, I just changed the last line to use jQuery's attr() method

$.expr[':'].iAttrStart = function(obj, params, meta, stack) {
    var opts = meta[3].match(/(.*)\s*,\s*(.*)/);
    return (undefined != $(obj).attr(opts[1])) && (obj[opts[1]].toLowerCase().indexOf(opts[2].toLowerCase()) === 0)
};
awaage
  • 2,669
  • 1
  • 17
  • 15