views:

349

answers:

10

From the following markup.

<div id="my-div">
    <a href="#" id="link-1">Somewhere</a>
    <a href="#" id="link-2">Somewhere else</a>
</div>

What are some options, using jQuery selectors and JavaScript for grabbing the integer in the ids?

For example.

$("#my-div a").click(function(){
    $(this).id // ... somehow grab n from "link-n"        
    alert(n);
});
+2  A: 

$(this).attr('id').replace('link-','')

Antony Hatchkins
He's asking how to parse the id once he get it
Cfreak
Doesn't this return "link-1"?
o.k.w
This will return the ID. Not **only** the numeric part of it as requested.
Kevin Peno
yep, thanks. corrected
Antony Hatchkins
+2  A: 

As long as the preceding text always remains the same you can just use the substring method to get the number.

$(this).attr('id').substring(5)
Damien
`.id` doesn't work, I don't think. You need the `attr('id')` form that you list first.
Brian Campbell
As gnarf pointed out, `$(this).id` doesn't work. If you use the jQuery object around `this`, you have to use `attr()`.
zombat
Also, I think you mean `substring(5)`, not `substring(6)`.
zombat
cheers. I saw others with .id and presumed it was something I missed from jQuery. Thanks Zombat, lol. Miscoutned
Damien
+1  A: 

Using a regex would be your best option, for instance:

// id contains '1' for id="link-1"
var id = parseInt(this.id.replace(/[^\d]/g, ''), 10);
brad
You should use `parseInt(...,10);` in the event that the ID starts with a 0 to stop octal parsing: `parseInt('010')` = 8... Also - in jQuery `$(this).id` will be undefined - try `$(this).attr('id')`
gnarf
Or, indeed, just `this.id`. No need to drag jQuery into everything.
bobince
@gnarf @bobince - Thanks for the comments, I've updated the answer to reflect them.
brad
A: 

If you know that all your ids are prefixed by "link-", you can simply get the substring of the id:

$("#my-div a").click(function(){
   alert(this.id.substr(5));
});
zombat
`$(this).attr('id')` instead of `$(this).id`
gnarf
Roger, thanks. A bit quick on the 'ol copy paste. I'd actually just go with `this.id` instead.
zombat
+1  A: 

I usually do something like this:

$("#my-div a").click(function(){
    var match;
    if (match = $(this).attr('id').match(/link-(\d+)/)) {
      var number = parseInt(match[1],10);
      alert(number);
    }
});
gnarf
+1 for using a regex '()' grouping. You don't need the 'link-', either, just .match(/(\d+)/) will do the trick. Who care's about the leading text?
Jarrett Meyer
@Jarrett - I'd rather ensure that it was a `link-?` instead of just saying "any old number will work"... This way, if you have an `<a id='rss-1'>` it will not use the `link-` specific code.
gnarf
A: 
var match = /link-(\d+)/.exec($(this).attr('id'));
var num = match[1];
Michael Morton
+1  A: 
var id = $(this).attr('id'),
    regex = /(\d+)/,
    matched = id.match( regex );

if ( matched ) {
    alert( matched[1] )
}
meder
gnarf
ah, right.. good catch
meder
+1  A: 
$(this).attr('id').split('-')[1];
Brian Schantz
Can't believe it took this long to get a split-based answer. +1
Triptych
+3  A: 

You could try:

var n = $(this).attr('id').match(/link-(\d+)/)[1];

This fetches the id attribute, matches against the pattern link-(\d+) (which means link- followed by one or more digits), and then extracts the first subexpression match (the part in the parentheses \d+), which should be the number you are looking for.

If you need to work with n as an integer instead of a string, you should should use parseInt, making sure to specify base 10:

var n = parseInt($(this).attr('id').match(/link-(\d+)/)[1], 10);

If your id attributes are not guaranteed to begin with link- followed by one or more digits, and you would like to catch this case instead of throwing an error, you should check the return value of match:

var match = $(this).attr('id').match(/link-(\d+)/);
if (match) {
    var n = parseInt(match[1], 10);
    alert(n);
} else {
    // do something else if they don't match
}
Brian Campbell
or use \d instead of [0-9]
Jarrett Meyer
Sure, fixed to be more succinct.
Brian Campbell
Why would you use this over the simpler `substr()`? If you assume that the first five characters are `link-`, you might as well assume the last portion of it will be the number you're looking for, n'est pas?
zombat
@zombat - true, but I would rather assert that I am indeed working with a 'link-(\d+)' before treating it like one.
gnarf
@zombat Because it makes your code more self-documenting. To someone who reads your code later, they might not know why you are doing a `substr` match, while the regular expression shows exactly what you are looking for. It also means that it will fail if you somehow match an element with an `id` in a different format; and usually, failing earlier and catching the bug at the source is better than working with broken data and failing later on after you've used that data for something else. (tl;dr what gnarf said)
Brian Campbell
@Brian - I disagree. If I use this line of code `var n = parseInt($(this).attr('id').match(/link-(\d+)/)[1], 10);` on an element that does not start with `link-`, it produces an error and ends processing of Javascript in that function. It would be much better to proceed with an empty match (such as a `substr()` on an unexpected id) and check that the match is indeed an int before you use it. `substr()` is also much less complicated than a regular expression, and improves code readability.
zombat
@zombat - the undefined error is why my answer checks the match before accessing it :)
gnarf
@zombat That's right. Throwing an error is intentional; if you reach an unexpected state, it is better to throw an error as soon as possible and abort, rather than continuing with bad data; that is the basic principle of adding assertions to your code. If you just use `substr` blindly (as in your answer), you could be continuing with bad data. I've edited my answer to include an option for handling an `id` that doesn't match more gracefully, if that's an expected condition; my original solution can still be used if you always expect a match, in order to throw an error if you don't.
Brian Campbell
Also, `substr` is not at all more readable; you have to count characters precisely (as demonstrated in Damien's answer, which got it wrong at first), and you still don't know when you see it *why* you're taking that substring; it's not self-documenting like the regular expression. It will also just blindly accept all characters at the end of the string, regardless of whether or not they are digits.
Brian Campbell
A: 

This should be the simplest way:

var id = this.id.replace(/[^\d]/g,'')*1;

It returns any digits from the ID attribute as a number (*1 does the conversion, similar to parseInt). In your example:

$("#my-div a").click(function(){
    var n = this.id.replace(/[^\d]/g,'')*1;
    alert(n);  // alerts any number in the ID attribute
    alert(typeof n) // alerts 'number' (not 'string')
});
David