Access html data attribute from helper? :: $(this).data("id") not this.data

633 views
Skip to first unread message

Chad Kruse

unread,
May 5, 2014, 1:22:27 PM5/5/14
to meteo...@googlegroups.com
I know I can access the current template data context in a helper via this.data, but how do I access an html data attribute? In jquery you'd just use $(this).data('id'), but I keep getting undefined. Syntax problem? 

If the data-id of an element appears in an array within a collection, I add a class to that element. Here's my setup (thanks in advance for the help!):

HTML
<a class="js-indicator {{followsIndicator}}" data-id="{{key}}">{{name}}</a>

Helper
UI.registerHelper('followsIndicator', function () {
  var $key = [what goes here?]; //I want to reference the data-id attribute
  var $arr = Follows.findOne({ visitorId: 'some_id'}).following;
  return $.inArray($key, $arr) !== -1 ? 'indicator' : 'indicator-placeholder';
});

I've tried all sorts of permutations and no luck.

Much appreciated,
ck


Jay Greenspan

unread,
May 5, 2014, 4:06:56 PM5/5/14
to meteo...@googlegroups.com
Chad, 

If I understand correctly, you're not doing this the "Meteor Way."

I think you want to do this test as you loop through your data context... so in the template:

{{#each mydataContext}}
  <p> <a class="js-indicator {{followsIndicator}}" data-id="{{key}}">{{name}}</a> </p>
{{/each}}

Then in the helpers:
Template.mytemplate.helpers({
    mydataContext: function(){
        return myCollection.find();
    },
    followsIndicator: function(){
        var keyToTest = this.key;
        var valToTest = this.value
        //run query with values here.
      
    }   
        
})


Chad Kruse

unread,
May 5, 2014, 4:58:22 PM5/5/14
to meteo...@googlegroups.com
Thanks Jay. Thanks for pushing me to do it the right way :) I think my problem is I'm trying to leverage some old queries based on a data model that no longer really fits and it's time to step back and do it the right way. Was hoping I could just tap into the existing data-id="key" via jQuery and call it a day. Alas. #lazy

For posterity sake, I'd still be interested to know if accessing a data attribute is possible and what the syntax would be, hacky as it may be.

And in case anyone happens upon this in the future, here's my temp fix:
UI.registerHelper('followsIndicator', function (key) {
  var $key = this.key;
  var $arr = Follows.findOne({ visitorId: 'some_id'}).following;
  if (key !== undefined) {
    return $.inArray(key, $arr) !== -1 ? 'indicator' : 'indicator-placeholder';
  } else {
  return $.inArray($key, $arr) !== -1 ? 'indicator' : 'indicator-placeholder';
  }
});

The if statement works for html structured like the original:
<a class="js-indicator {{followsIndicator}}" data-id="{{key}}">{{name}}</a>

The else statement allows me to leverage the existing queries I have, some of which pull down nested "keys" (e.g. this.foo.[0].key). The html for that is therefore:
<a class="js-indicator {{followsIndicator this.foo.[0].key}}" data-id="{{key}}">{{name}}</a>

Thanks again Jay.

Jay Greenspan

unread,
May 5, 2014, 7:15:29 PM5/5/14
to meteo...@googlegroups.com
For posterity sake, I'd still be interested to know if accessing a data attribute is possible and what the syntax would be, hacky as it may be.


I'm pretty new to this, so I could very well be off....

What's the situation where,, in the course of writing to your template, you'd need to access HTML attributes? If the attributes are dynamic, they're written from your helpers, and thus are available in said helpers. 

On the other side, all of the HTML data, as well other data from the original data source, are available through events. 

  Template.hello.events({
    'click .mylink': function(e){
      console.log(this);
      console.log(e);
    }

I haven't yet run into a case where one of these two wouldn't be sufficient. 

Am  I missing the point?

Chad Kruse

unread,
May 6, 2014, 11:02:37 AM5/6/14
to meteo...@googlegroups.com
You're not off at all...it's a function of me trying to use a short cut instead of doing it the right way. I'm trying to think of a time you'd need to access the html data attributes and am coming up empty too. So, it's a pretty unlikely edge case at best and definitely not the right way in any scenario.

tl;dr

In my case, the css classes came from client activity, not the server-side collection, and were largely an after thought when creating my original data model (it's for a quick prototype) . So instead of reworking the data model (I'm a relative newbie and slow), I created a local collection for the event activity and was looking for the jQuery short cut to get the css class to persist across iron-router routes. In hindsight, it would have been much faster to take a step back, insert the follows activity in the existing server side collection (that's the beauty of NoSQL right?) and be done with it. And next time, thanks to this discussion, that's certainly what I'll be doing :)


--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/2QOyw5KkQrQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages