1

I have the following code:

                <li class="shop-currencies">
                    <a href="#" id="EUR" data-currency="EUR">€</a>
                    <a href="#" id="GBP" data-currency="GBP">£</a>
                    <a href="#" id="USD" data-currency="USD">$</a>
                    <a href="#" id="ZAR" data-currency="ZAR" class="current">R</a>
                </li>

When an item is clicked I want to set the class to the clicked item and get the ID of the item clicked. This is what I have so far:

$('.shop-currencies').click(function() {

    var id = $(this).attr('id');

    alert(id);

    /**
     * Remove the classes from the currency elements
     */
    $('.shop-currencies').find('a').each(function(e) {
       $(this).removeClass();
    });

    /**
     * Set the class of the clicked element
     */
    $( '#' + id).addClass('current');



});

The ID is being returned as 'undefined' How do I get the ID of the clicked link?

Thanks

1
  • Please note that your bookmark anchors (href="#") will cause the page to spring to the top if it has scrolled at all, so also add e.preventDefault(); to any solution you choose :) Commented Jan 19, 2015 at 15:39

5 Answers 5

2

You need to attach click handler to child anchor element :

$('.shop-currencies a').click(function() {

var id = $(this).attr('id');

alert(id);

 /**
 * Remove the classes from the currency elements
 */
   $('.shop-currencies').find('a').not(this).removeClass('smclass')
 /**
 * Add class to current elements
 */
   $(this).addClass('smclass')
});
Sign up to request clarification or add additional context in comments.

2 Comments

I'd say it's better to use $('.shop-currencies').on('click', 'a' function() { ... }); With this modification your code will be more compatible with future versions of jQuery and will work with anchors created dynamically.
And why so. there is no need to delegate the event.
1

There are a couple of options, Milind Anantwar has one, the other is to use the originally clicked element, which is passed to the event as a target property on the event argument. You can also simplify your code a lot. Please note that your bookmark anchors will cause the page to spring to the top, so also add e.preventDefault(); to any solution you choose:

$('.shop-currencies').click(function(e) {
    e.preventDefault();
    $('a', this).removeClass('current');   // remove related anchor current class
    $(e.target).addClass('current');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/

The one downside to this is that clicking inside .shop-currencies, but not on a currency link, will clear the current selection. Because of this you are better off targetting the links instead:

$('.shop-currencies a').click(function(e) {
    e.preventDefault();
    $(this).siblings().removeClass('current');   // remove related anchor current class
    $(this).addClass('current');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/1/

Which can be reduced to one line:

$('.shop-currencies a').click(function(e) {
    e.preventDefault();
    $(this).addClass('current').siblings().removeClass('current');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/2/

Saving the best for last

And one last point... It is more efficient (but hardly noticeable) to add a single delegated event handler, instead of attaching 4 seperate handlers:

$('.shop-currencies').on('click', 'a', function(e) {
    e.preventDefault();
    $(this).addClass('current').siblings().removeClass('current');
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/3/

Final thoughts:

The IDs on the links are unnecessary if you have an appropriate this available. You can remove them from the HTML. You have the currency value you require in data-currency attributes, so you could use it like this:

$('.shop-currencies').on('click', 'a', function(e) {
    e.preventDefault();
    $(this).addClass('current').siblings().removeClass('current');
    alert($(this).data('currency'));
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/7/

1 Comment

A nice explanation, thank you for the tips and the effort. I am marking this as the answer as it is the most comprehensive.
0

your click, is attach to li instead of each a tag so do $('a').click();instead

Comments

0

Shortest and fastest answer

$('.shop-currencies > a').click(function(){
  $(this).siblings('a').removeClass('current');
  $(this).addClass('current');
});

The code pen link is here, you can play with the code your self

1 Comment

Never say shortest and fastest as a) it is not the shortest/fastest way to do this code and b) you are unlikely to care how fast this simple operation is as the speed differences are tiny :) (F.Y.I. a delegated event handler will be faster to connect and chaining your siblings after addClass will make it shorter :>)
0
$('.shop-currencies a').each(function() {
 $(this).on("click", function(event) {
  event.preventDefault();
  var id = $(this).attr('id');
  $('.shop-currencies a').removeClass("current");
  $(this).addClass('current');
  alert(id);
 });
});

http://jsfiddle.net/nj37g5rm/8/

16 Comments

Why introduce an each when jQuery does that automatically? Just realised this does not even target the anchors, so will not work at all. :(
he has an each on his code. Thanks for the down vote. This code I wrote works perfectly. if you want you can argue it but my answer is correct for his question no need for down votes.
ye typo, forgot the a tag, now updated. No need for big times.
The ID was only used to select the element the element was clicked :) That of course is a complete waste of time if you have an appropriate this. You need to figure out the intended aim and not copy the OPs mistakes :) ID's are not even needed for the desired result.
As the currency meta data value is in data-currency, I would drop the IDs (if only to avoid ID-clutter on the page) and use .data("currency"). I updated my own answer to include this suggestion.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.