Search code examples
javascripthtmlmeteormeteor-blaze

Meteor - Passing data from templates to events, on button click


I have a scenario in which an admin is able to approve or reject a Users request to join a specific Module in my system. So I use a helper to find all the Modules for which the Admin manages in the Modules Collection and I list each request for each Module, with a button to Approve and a button Reject each request.

Module Collection

{
  "_id": "hcHJW2A8g8QoqvPmC",
  "year": "1",
  "courseId": "5aaeca852edb669c9e4b456a",
  "moduleName": "System Analysis",
  "logo": "https://ijnet.org/sites/default/files/images/migrate/2010-09-29/25647.jpg",
  "requested": [
    {
      "name": "aor88"
    },
    {
      "name": "Create"
    }
  ],
  "rejected": [],
  "approved": [],
  "admin_id": "Ad6emWNAqZY2oYneW"
}

templates > admin.html

<template name="admin">
<br><br>
{{#if modules}}
            {{ #each module in modules }}

             <div class="row">
                 <h4 id="modulename" >{{module.moduleName}}</h4>
                <div class="col-md-4 col-sm-6">

                    {{ #each request in module.requested }}
                    <div class="card-style">
                        <div class="media">
                            <div class="media-body">
                                <h4 id="username">{{request.name}}</h4>

                                <input type="submit" title="Reject" id="rejectScenarioButton"  value="Reject"/>

                                <input type="submit" title="Approve" id="approveScenarioButton"  value="Approve"/>


                            </div>
                        </div>
                    </div>
                    {{/each}}
                </div>
            </div> 

            {{/each}}
{{else}}
                <h1>There is currently no join requests</h1>
{{/if}}
</template>

helpers> admin.js

Template.admin.helpers({

    modules: function() {
        modules = Modules.find(
        {
            admin_id: Meteor.userId()
        },
        {
            requested:{
                $exists: true, 
                $not: {$size: 0} 
            }
        },
        {
            sort: {moduleName:-1}

        }
        );

      return modules

    }

})

Everything to this step is working as expected. My problem occurs when I try handle the data using click events. I am trying to extract the Module Name and User Name and then handle them in my click event. So In my example below I was expecting this.name to return the username, but it returns undefined.

events>admin.js

Template.admin.events({

    "click input[type=submit]": function(e, t) {
        if ($(e.target).prop("id") == "approveScenarioButton") {

            console.log(this.name);                   


                return false
        } else if ($(e.target).prop("id") == "rejectScenarioButton") {


        }

    }

})

Can anyone point me in the right direction?


Solution

  • In an event handler, the this keyword points to the template's datacontext (or window if there is none). The data context of the admin template is not a single request object. There's a few ways you could do this but it might be better in the long run to create a new Request Template and attach the handler there:

    {{#each request in module.requested}}
      {{> Request data=request}}                
    {{/each}}
    

    Request Template:

    <template name="Request">
      <div class="card-style">
        <div class="media">
          <div class="media-body">
            <h4 id="username">{{name}}</h4>
            <input type="submit" title="Reject" id="rejectScenarioButton"  value="Reject"/>
            <input type="submit" title="Approve" id="approveScenarioButton"  value="Approve"/>
          </div>
        </div>
      </div>
    </template>
    

    (I'd recommend replacing the ids on the submit inputs with classes - use those in your event key.)

    Request Template helpers/events:

    Template.Request.events({
      'click input[type=submit]'(e, t) {
        // `this` contains the data from the request object passed into the
        // template during each iteration
        console.log(this.name);
      }
    });