1

I am working on a site where a lot of content is generated dynamically using AngularJS. I need to get the attribute of an element that is dynamically generated using jQuery, but I am having trouble doing so. I have already figured out that I need to use the .on method to click rather than .click. My issue is finding the equivalent of $(this) within the .on method.

Here is my code:

$(document.body).on('click', 'a.card-topic-link' ,function(e) {
    e.preventDefault(); // Prevent default action - this works

    console.log('The click works!'); // This fires and works just fine

    var cardTopicLink = $(this).attr('data-topic-link'); // This is where the problem lies

    console.log(cardTopicLink); // This is undefined
}); // End on click

As I stated before, this does not work as the .click does not work for dynamic content:

$('a.card-topic-link').click(function(e) {
    e.preventDefault(); // Prevent default action

    var cardTopicLink = $(this).attr('data-topic-link');

    console.log(cardTopicLink);
});

I feel like there is a simple solution to this problem that I am having trouble finding. The key to this issue is that this is dealing with dynamic content.

Let me know if you have any ideas.

Sofia Braun
  • 194
  • 11
Marc
  • 4,661
  • 3
  • 40
  • 62
  • How are you setting the `data-topic-link` attribute of the element? – Frxstrem Oct 04 '16 at 22:48
  • It is set within HTML that is stored in the database and basically printed to the screen via AngularJS. It looks like this and is working properly `data-topic-link="text"`. – Marc Oct 04 '16 at 22:51
  • why aren't you using `ng-click` and passing in whatever data generates the attribute value in the first place? Need to provide a [mcve] – charlietfl Oct 04 '16 at 22:54
  • 1
    Suggested reading : [thinking-in-angularjs-if-i-have-a-jquery-background](http://stackoverflow.com/questions/14994391/thinking-in-angularjs-if-i-have-a-jquery-background) – charlietfl Oct 04 '16 at 22:56
  • Basically the data in question is a dump of HTML that was written at an earlier time and stored in the database. It contains some navigation links that have this attribute associated with it. There may be one link in the dataset or 1000. I can't pass the data into an `ng-click`. – Marc Oct 04 '16 at 23:00
  • If you're attaching a click handler to the body, then `this` is going to refer to the body. Your `$('a.card-topic-link').click` can work, but you will need to add the click handler **after** that link has been created by Angular. – Ashelyn Dawn Oct 04 '16 at 23:00
  • that is not correct @PawnStar. `this` is always the element the event occured on in a jQuery event handler – charlietfl Oct 04 '16 at 23:14
  • no reason the code shown shouldn't work if the attribute does exist. – charlietfl Oct 04 '16 at 23:16
  • @charlietfl You may be right. I hazarded a guess, and didn't feel it was solid enough to give a real answer. – Ashelyn Dawn Oct 04 '16 at 23:16
  • are you using `ngSanitize`? Have you confirmed the attributes exist in live html in dom using browser dev tools? Too many unknowns without more code context – charlietfl Oct 04 '16 at 23:20

2 Answers2

1

use e.currentTarget, instead of var cardTopicLink = $(this).attr('data-topic-link');, try var cardTopicLink = angular.element(e.currentTarget).attr('data-topic-link');

$(document).ready(function () {
  $(document.body).on('click', 'a.card-topic-link' ,function(e) {
    e.preventDefault(); // Prevent default action - this works
    console.log('The click works!'); // This fires and works just fine

    var cardTopicLink = $(e.currentTarget).attr('data-topic-link'); //   This is where the problem lies

    console.log(cardTopicLink);
  }); // End on click
});

plunker with similar code, firing on async loaded content - http://plnkr.co/edit/02rqCrbBVwXiIYff8ktC?p=preview

Andriy
  • 14,781
  • 4
  • 46
  • 50
0

It turns out that AngularJS was stripping out the attribute data-topic-link as it was parsed. This was happening because the HTML that contained the data-topic-link was passed as a part of the response that Angular was printing in an ng-repeat.

I updated the code so that the HTML with this attribute did not need to be served by AngularJS.

Marc
  • 4,661
  • 3
  • 40
  • 62