views:

146

answers:

4

There are several divs on my page with classes my_widget-2, my_widget-8, etc. What javascript or jQuery code can I use to get the number "2" (ie. the number that appends the first matching widget)?

Thanks in advance for your input.

Note: If I were to write this question again, I would change the order of these class names and ask for a way to get "8" in order not to possibly give the impression that I want the smaller number.

+2  A: 
$( "[class*='my_widget']" ).each ( function () {
    var elClasses = $( this ).attr ( 'class' ).split ( ' ' );

    for ( var index in elClasses ) {
        if ( elClasses[index].match ( /^my_widget-\d+$/ ) ) {
            var classNum = elClasses[index].split ( '-' )[1];
            alert ( classNum );
            break;
        }
    }
} );

Use the "attributeContains" selector to get all elements that have a class my_widget-*, and then loop trough all the classes the element has searching for you class. Once you find it, extract the number part.

Jan Hančič
What if the element has multple classes? The startswith wouldn't work for them.
BalusC
He didn't say that he has multiple classes ...
Jan Hančič
Make it "[class*='my_widget']" and it should work in the case of multiple classes.
ryanulit
@ryanulit: hehe, was adding that, didn't see your comment :)
Jan Hančič
What about class names just containing `my_widget` like `not_my_widget`?
Gumbo
It now only matches classes in the form "my_widget-NUM"
Jan Hančič
@Jan Hančič: No, it doesn’t. It will also match `not_my_widget-N` and `my_widget-N-foobar`. :-)
Gumbo
Ups, you are right. Fixed it.
Jan Hančič
This is almost there. I am getting two results: 2 and 8 as a result of this. How can I get only the first one ("2")?If left to me, I will try to insert a loop and a counter but I am pretty sure you jQuery experts know a better way.
Necati
I figured it out by using `:first`. It is fine for the answer to stay as it is, so more people can make use of it.
Necati
A: 

If you want to get the DIV elements with a class my_widget-2, use this selector:

$("div.my_widget-2")

But if you want to get all DIV elements with a class of the form my_widget-N where N is an arbitrary number, try this:

$("div[class]").each(function() {
    var matches = this.className.match(/(?:^|\s+)my_widget-(\d+)(?:\s+|$)/g);
    if (matches !== null) {
        alert(matches);
    }
})
Gumbo
Why the down vote?
Gumbo
I downvoted your original answer that didn't make any sense. Now I can't undo :\
Jan Hančič
@Jan Hančič: And why didn’t it make any sense? He just asked how to get the “number 2” of some DIV elements with classes like `my_widget-2` and `my_widget-8`. If “number 2” refers to the DIV elements with the class `my_widget-2` my previous answer makes perfect sense.
Gumbo
No, he wants to get elements that have a class like my_widget-AND SOME NUMBER. And originally you had the wrong selector even for that what you are saying :)
Jan Hančič
@Jan Hančič: And where did he say that?
Gumbo
I think it's clear from his question. Why would he need to get "2" if he already knew the full class name "my_widget-2"?
Jan Hančič
I neutralized the downvote. Jan: you can remove the downvote if Gumbo has edited the message.
BalusC
Yeah I know, but somehow I can't ...
Jan Hančič
A: 

This should do the trick:

$("[class^='my_widget']").each(function() {
    var classParts = $(this).attr('class').split('-');
    var number = classParts.pop();
});

Please note that it will only work if there is a singular class, otherwise you'd get something like 8 otherclass as a result.

cballou
Another tricky part here is that I only want the first number suffix ('2'), not the others... not actually sure if jQuery is the right tool to approach this.This whole thing really is part of a Wordpress situation but I wasn't able to add my original question that had a link to this one. (noob -> need to wait another 10 mins. or so)
Necati
+1  A: 

Basic JS approach:

<div id="x" class="widget-2 lang-日本語">foo</div>

function Element_getClassArgument(el, name) {
    var classes= el.className.split(' ');
    var prefix= name+'-';
    for (var i= classes.length; i-->0;)
        if (classes[i].substring(0, prefix.length)==prefix)
            return classes[i].substring(prefix.length);
    return null;
}

Element_getClassArgument(document.getElementById('x'), 'widget'); // 2

If you wanted to include whitespace characters, or a hyphen in a name, you'd have to introduce an encoding scheme of some sort, for example encodeURIComponent. But often you can get away without that.

Wrapping in something with $ in the name is left as an exercise for the reader. :-)

bobince
Hey, good ol' JS!
BalusC
I chose to go the jQuery way, but thanks for your input.
Necati