5

I have a div that looks like

<div class="draggable resizable abc table shadow"></div>

Clases are in no specific order. If I do $('div').attr('class') then I get a list of all the classes for that div. What I want is to only get classes that are not resizable, draggableor table. In this case i want abc shadow. How do I do this.

Pinkie
  • 10,126
  • 22
  • 78
  • 124
  • So you want the actual class names, not the HTML elements? – Richard JP Le Guen Oct 18 '11 at 19:24
  • 2
    Tip: You'll get better answers if you explain what you are wanting to do instead of (or in addition to) asking about one way you think you might accomplish it. Why do you want a list of classes minus the others? (What are you going to do with them.) – Phrogz Oct 18 '11 at 19:40

8 Answers8

4
var all  = "draggable resizable abc table shadow";
var some = all.replace(/(?:^|\s)(resizable|draggable|table)(?=\s|$)/g, '');

console.log(some);
// " abc shadow"

console.log(some.replace(/^\s+|\s+$/g,''));
// "abc shadow"

console.log(some.split(/\s+/));
// ["", "abc", "shadow"]

Note that you don't need the second replace (you don't need to strip off leading and trailing whitespace) if all you want is a string that's appropriate for setting the className to.

But then, if you're trying to just remove a set of known classes from an element, far better to simply:

$(...).removeClass("draggable resizable table");

Alternative (without needing a regex):

var ignore = {resizable:1, draggable:1, table:1};
var all = "draggable resizable abc table shadow".split(' ');
for (var subset=[],i=all.length;i--;) if (!ignore[all[i]]) subset.push(all[i]);

console.log(subset);
// ["shadow","abc"]

console.log(subset.join(' '));
// "shadow abc"
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • Thanks, but i'm getting comma before every classe `,abc,shadow` I want a space after every class so it looks like `abc shadow` – Pinkie Oct 18 '11 at 19:27
  • @Pinkie: `some.split(/\s+/)` returns an array. You can concatenate its elements in any way you want. – Felix Kling Oct 18 '11 at 19:28
  • Leaving off the split will give you a space-delimited string suitable for setting the class to (if that's what you are trying to do). – Phrogz Oct 18 '11 at 19:32
4

A plugin:

(function($) {
    $.fn.getClasses = function(exclude) {
        var remove = {};

        for(var i = exclude.length; i--;) {
            remove[exclude[i]] = true;
        }

        return $.map(this.attr('class').split(/\s+/g), function(cls) {
            return remove[cls] ? null : cls;
        });
    };
}(jQuery));

Usage:

var classes = $('div').getClasses(['resizable', 'draggable', 'table']);
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Nice. +1 for showing me that `$.map` along with `null` auto-compacts the result. (I might personally rename the method to `getClassesWithout`, but that's more preference than anything else.) – Phrogz Oct 18 '11 at 19:41
  • 2
    @Josh: Not sure why you did this but it does not change anything and in fact JSLint prefers the other way. – Felix Kling Oct 18 '11 at 19:42
  • @FelixKling My bad, you are correct, at first glance I thought it was a typo! – Josh Stodola Oct 18 '11 at 19:43
  • 1
    @DaveMackintosh: You don't understand the question. The OP wants a list of classes, not a list of elements. – Andrew Whitaker Oct 18 '11 at 19:51
  • @Pinkie: There is in error in the last line of your fiddle: `);)` should be `));`. http://jsfiddle.net/rkyqK/2/ – Felix Kling Oct 18 '11 at 19:58
  • Thanks, this is great, but for the simple purpose of the project and the limited use of this feature, phrogz solution will work best for me. – Pinkie Oct 18 '11 at 20:10
1

@Phrogz answer is a good one. Apparently, he's a regex wiz. Since I don't know regex that well, here's my take on it:

var aryClasses = $("div").attr("class").split(" ");
var aryDesiredClasses = new Array();

for(var i = 0; i < aryClasses.length; i++) {
    if(aryClasses[i] != "table" 
                     && aryClasses[i] != "resizable" 
                     && aryClasses[i] != "draggable")
        aryDesiredClasses.push(aryClasses[i]);
}

alert(aryDesiredClasses.join(" "));

Here's a working fiddle to illustrate.

James Hill
  • 60,353
  • 20
  • 145
  • 161
  • 1
    I think you want negation (`if (aryClasses[i]!="resizable" || ...)`) instead of just matching exactly the known classes. – Phrogz Oct 18 '11 at 19:31
1
        function getDesiredClass( removedClassArr ){
            var classArray = $("selector").attr('class').split(" ");
            var desiredClassArray = [];
            for(var i = 0; i < classArray.length; i++ ){
               if ( !isUnDesiredClass(removedClassArr, classArray[i]) ){
                  desiredClassArray .push( classArray[i] );
               }
            }
            return desiredClassArray;
        }
       function isUnDesiredClass( removedClassArr , cls){
         for(var i = 0; i < removedClassArr.length; i++ ){
           if( removedClassArr[i] == cls ){
               return true;
            }
       }
      return false;
    }
Anoop
  • 23,044
  • 10
  • 62
  • 76
0

You can check for individual classes using .hasClass.

$("div").hasClass("class");
Alex Turpin
  • 46,743
  • 23
  • 113
  • 145
0

This was answered here. Get class list for element with jQuery.

You can extend this to just get the strings in the array that are not "resizable, draggable or table"

Community
  • 1
  • 1
Keith.Abramo
  • 6,952
  • 2
  • 32
  • 46
  • This is irrelevant to the question. – Pinkie Oct 18 '11 at 19:28
  • I'm not sure why you think this is irrelevant to the question. The referenced post provides a way to get all of the class names from the element and populates them into an array. You then take that array and parse out the 3 classes you don't want. – Keith.Abramo Oct 18 '11 at 19:37
  • To enhance your answer, you should probably adapt the code found in that answer to the question instead of simply linking to it. – Andrew Whitaker Oct 18 '11 at 19:52
0
var classes = $('div').not('.resizable, .draggable, .table').attr('class').split(' ');
ingo
  • 5,469
  • 1
  • 24
  • 19
0

have a look at this jsFiddle, I have something working like what you wanted.

Also, have a look at jQuery :not selectors

Dave Mackintosh
  • 2,738
  • 2
  • 31
  • 40