T...">

Meteor: event detection in nested template

New Meteor Question ...

I have code vaguely similar to this:

<template name="fancy-button">
    <p>This is a fancy button that I use in several places!</p>
    <input type="button" class="very-fancy" value="Click Me!" />
</template>

<template name="homepage">
    {{> fancy-button}}
    // here, I want the button to bring up my "stats" page (go, iron-router, go)
</template>

<template name="stats-page">
    {{> fancy-button}}
    // here, I want the button to show an alert
</template>

      

Question: on the homepage and stats-page, is there a way to know if the user has clicked the fancy-button?

(Or is this the wrong way to implement things in meteor?)

+3


source to share


2 answers


Note. The answer below will give you a working toggle button and one general toggle status. If you need a button to do different things or change different boolean buttons depending on the context, then there is more work to do. Perhaps it is possible.

The nesting used in the display does not affect the internal presentation of the templates. All templates in Meteor are defined in the Template object as Template.someTemplateName

. Each template is a JS object containing data fields, functions, and event handlers.

For this reason, dashes in template names are not allowed .

Since meteorite uses the template name in the Javascript object as the property name, so the template names must follow the Javascript naming conventions / restrictions. In particular, the dash looks like a minus in the resulting code:

Template.fancy-button.events

and won't work. Javascript reads that as a Template.fancy

minus button.events

, not as an event handler for the fancy button template.

As for Javascript compatible names, http://javascript.crockford.com/code.html suggests:

Names must be formed from 26 upper and lower case letters (A .. Z, a .. z), 10 numbers (0 .. 9) and _ (lower drum) ...



Another Javascript convention is camelCase, where each word in the name after the first word is capitalized. I suggest that instead of a dash, change the code like this:

<template name="fancyButton">
    <p>This is a fancy button that I use in several places!</p>
    <input type="button" class="veryFancy" value="Click Me!" />
</template>

<template name="homePage">
    {{> fancyButton}}
    // here, I want the button to bring up my "stats" page (go, iron-router, go)
    {{ #if veryFancyStatus }}
    {{ > statsPage }}
    {{ /if }} 
</template>

<template name="statsPage">
    {{> fancyButton}}
    // here, I want the button to show an alert page
    {{ #if veryFancyStatus }}
    {{ > alertPage }}
    {{ /if }}
</template>

      

The Meteor method for setting the click handler should use event maps

Also, you probably want to use a helper to make it easier to use session variables in your template

Here's how to implement a switch:

client.js (untested)

// initialize veryFancyStatus to 0
Session.set("veryFancyStatus",0)
// register veryFancyStatus so we can read it in every template
Handlebars.registerHelper('veryFancyStatus',function(input){
  return Session.get("veryFancyStatus");
});
// set up an event handler so that any time a .veryFancy class element is clicked
// a function is called to toggle the session variable veryFancyStatus
// this should also trigger redraws in templates that are conditional on veryFancyStatus
Template.fancyButton.events({
  'click .veryFancy': function () {
    Session.set("veryFancyStatus", +(!(Session.get("veryFancyStatus")));
  }
});

      

+1


source


Thanks a lot @paul! I went with something like this:

<template name="fancyButton">
    <p>This is a fancy button that I use in several places!</p>
    <input type="button" class="veryFancy" value="Click Me!" />
</template>

<template name="homePage">
    {{> fancyButton}}
    {{respondToFancyButton}}
    <!-- here, I want the button to bring up my "stats" page (go, iron-router, go) -->
</template>

<template name="statsPage">
    {{> fancyButton}}
    {{respondToFancyButton}}
    <!-- here, I want the button to show an alert -->
</template>

      



Then, in my JavaScript client code:

Session.set("fancyButtonMonitor", 0);

Template.fancyButton.events({
    'click .veryFancy': function(theEvent, theTemplate) {
        Session.set("fancyButtonMonitor", 1);
    }
});

Template.homepage.respondToFancyButton = function () {
    if (Session.get("fancyButtonMonitor") == 1) {
        Session.set("fancyButtonMonitor", 0);
        Router.go('stats');
    }
    return null;
};

Template.statsPage.respondToFancyButton = function () {
    if (Session.get("fancyButtonMonitor") == 1) {
        Session.set("fancyButtonMonitor", 0);
        Router.go('alert');
    }
    return null;
};

      

+2


source







All Articles