curious1
curious1

Reputation: 14717

JQuery: how to write a selector to find elements with a class ending with a given substring?

I use JQuery for my web application. I don't know how to write a selector for this situation.

<a class="abc def xyz-delete-confirm efg">text</a>

<a class="abc def delete-confirm">text</a>

I need to find all links that has a class ending with "-delete-confirm" or has a class called "delete-confirm".

I know how to handle the situation of having a class called "delete-confirm". How about the "-delete-confirm situation"? Can I have a single selector covering two situations?

Thanks for any input!

Regards.

Upvotes: 1

Views: 4442

Answers (2)

jcsanyi
jcsanyi

Reputation: 8174

Is class just another attribute?

The problem with this type of situation is that treating class as just another attribute, and using attribute selectors will rarely get you what you're looking for in a consistent manner.

Some items to be aware of:

  • Does it work if the item has multiple classes?
  • Does it work if the item has multiple classes and the one you're matching against is the first class that shows up in the attribute value?
  • What about if it's the last one?
  • Does it work if the item has a class that contains the classname you're looking for? (in your example, maybe no-delete-confirm-available)?

Keep in mind too that when you're adding and removing classes dynamically, there's no guarantee which order the classes will show up in when you get the value of the class attribute.

If you have a very strict set of circumstances this will be used in and especially if the element will only have 1 class, an attribute selector may work. Otherwise, I'd recommend that you use a different approach.

A different class

The proper way to handle this is to use a different class - maybe have whatever process is adding the *-delete-confirm classes also add another class - maybe has-delete-confirm or something. Then you can select on that, and not have to worry about the class attribute.

Select all and then filter()

Another option that's not ideal, but will work better than an attribute selector is to select all possible elements, and then filter() your results with a callback function that uses a regular expression to find matching classes.

For example, if the elements are all <a> children of #links, you could use this:

$('#links a').filter(function () {
    return /(^|\s|-)delete-confirm(\s|$)/.test($(this).attr('class'));
});

You may also find this this similar question to be of interest:
jQuery:How to select elements with particular class here?

Upvotes: 3

PSL
PSL

Reputation: 123739

You can combine them like this.

var $allofthem = $('[class$="-delete-confirm"],.delete-confirm');

Note since this is just an attribute value ends with selector if the class name appears in the end of the list of classes for an element and ends with -delete-confirm will be only considered

Use ends-with selector and combination of your class selector.

For pure selection you can do this (Doesn't matter where it appears in the classList or how many classes it has):

var regExp = /-delete-confirm(\s|$)/; //I am sure regex can be improved

var $allofthem = $('a').filter(function(){
    return regExp.test(this.className) || $(this).is('.delete-confirm');
});

Demo

Upvotes: 8

Related Questions