Amir Rahbaran
Amir Rahbaran

Reputation: 2430

Meteor: how to retrieve "{{this}}-value" with a template event

Note: Whole code can be found here:

https://github.com/Julian-Th/crowducate-platform/tree/feature/courseEditRights

The issue: I can't retrieve the {{this}} value with an event. Console.log() is printing 0.

My HTML:

<!-- Modal to control who can collaborate on a course-->

<template name="modalAddCollaborators">
  <div id="modalAddCollaborators" class="modal fade" role="dialog">
    <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Manage Your Collaborators</h4>
      </div>
      <div class="modal-body">
        <form class="form" role="form">
          <ul class="list-group">
            {{#each  addedCollaborators}}
              {{#each canEditCourse}}
                 <li class="list-group-item js-listed-collaborator">{{this}}<a title="Remove Collaborator" id="remove-collaborator" class="btn btn-danger pull-right" href="#"><i class="fa fa-trash"></i></a></li>
             {{/each}}
            {{/each}}
          </ul>
          <div class="form-group">
            <input class="form-control typeahead" type="text" id="collaboratorName" placeholder="add a collaborator  ..." data-source="courses" autocomplete="off" spellcheck="off">
            <button type="button" id="js-addCollaborator" class="btn btn-success">Add</button>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>
</template>

My JS:

Template.modalAddCollaborators.rendered = function() {
    // initializes all typeahead instances
    Meteor.typeahead.inject();
};

Template.modalAddCollaborators.courses = function(){
    return Courses.find().fetch().map(function(it){ return it.author; });
 //return users.find().fetch().map(function(it){ return it.username; });
};

Template.modalAddCollaborators.helpers({
    'addedCollaborators': function () {
        return Courses.find().fetch();
    }
});

Template.modalAddCollaborators.events({
    'click #js-addCollaborator' : function (event) {
        var collaboratorName = $('#collaboratorName').val(); // 
        Courses.update(
           {_id: this._id},
           {$addToSet: {canEditCourse: collaboratorName}}
        );
        $('#collaboratorName').val("");
    },
    'click #remove-collaborator': function (event) {
        var listedCollaborator = $('.js-listed-collaborator').val();
        console.log(listedCollaborator);
        Courses.update(
            {_id: this._id }, 
            {$pull: {canEditCourse: listedCollaborator}}
        );
    }
});

My MongoDB JSON:

{
    "_id" : "j7A3tFdFBn5ECQGwe",
    "title" : "Beatles",
    "coverImageId" : "RERiadyMx8j8C9QQi",
    "author" : "John",
    "keywords" : [ 
        "Paul"
    ],
    "published" : "true",
    "about" : "Testing the Course",
    "canEditCourse" : [ 
        "uo8SMdNroPGnxMoRg", 
        "FLhFJEczF4ak7CxqN", 
        "lkahdakjshdal", 
        "asödjaöslkdjalsöSA"
    ],
    "createdById" : "uo8SMdNroPGnxMoRg",
    "dateCreated" : ISODate("2015-12-28T16:30:34.714Z")
}

As seen in the JS-File, my final goal is to delete the clicked user from an array.

Upvotes: 1

Views: 560

Answers (2)

chridam
chridam

Reputation: 103365

To get the text of the li item in the child link click event, combine the use of .parent() and .text() (since you can't use .val() on list items):

'click #remove-collaborator': function (event) {
    console.log(event.target);
    var listedCollaborator = $(event.currentTarget).parent().text();
    console.log(listedCollaborator);
    console.log(JSON.stringify(Template.parentData(0)));
    Courses.update(
        { 
            _id: Template.parentData(0)._id, /* or _id: Template.currentData()._id, */
            canEditCourse: listedCollaborator 
        }, 
        { $pull: { canEditCourse: listedCollaborator } }
    );
}

Notice you can use the current DOM element within the event bubbling phase through event.currentTarget to reference the element that kicked off the event. Since the element is the anchor tag, you get the li item as its .parent(), and subsequently get its value with .text().

As for the update, use Template.parentData() to get the parent _id. Specify a parameter of 0 in the method which denotes the current data context level to look.

For example, Template.parentData(0) is equivalent to Template.currentData(). Template.parentData(2) is equivalent to {{../..}} in a template.

Upvotes: 1

Michel Floyd
Michel Floyd

Reputation: 20226

Since you've attached your event handler to the modalAddCollaborators template this will be the data context of that template which is nothing.

Just setup a nested template at the level you want to catch the event.

Furthermore with this pattern you can identify the _id of the collaborator directly, it will be this. The course _id however comes from the context of the parent template. (I'm not sure whether the course level data context is 1 or 2 levels higher however).

html:

{{#each canEditCourse}}
  {{> nestedTemplate }}
{{/each}}

<template name="nestedTemplate">
  <li class="list-group-item js-listed-collaborator">
    {{this}}<a title="Remove Collaborator" id="remove-collaborator" class="btn btn-danger pull-right" href="#"><i class="fa fa-trash"></i></a>
  </li>
</template>

js:

Template.nestedTemplate.events({
  'click #remove-collaborator': function (event) {
    Courses.update({_id: Template.parentData()._id },{$pull: {canEditCourse: this}});
  }
});

Upvotes: 1

Related Questions