How can I render two different views in a one page app without changing URLs. I'm using meteor with the default blaze as well as the flow:router package. Right now I have it set up like this: routes.js..
FlowRouter.route("/", {
name: "App.home",
action() {
BlazeLayout.render("App_body", {
main: "App_home",
mainContent: "calendar"
});
}
});
FlowRouter.route("/list", {
name: "App.list",
action() {
BlazeLayout.render("App_body", { main: "App_home", mainContent: "list" });
}
});
but this way I'm using the url /list and i dont want that. I would like to simply render an alternate component template in the same url. I'm very new to coding so forgive me if this is obvious. Essentially I just want two different view styles: a list and a calendar. So I would like a way to set it up so that a spacebars template can be rendered if a certain button is clicked, and a different one can be rendered instead if another button is clicked.
Thanks so much for any help, i've been at this for a couple of days :)
You can handle this within a single template like so:
FlowRouter.route('/', {
name: 'App.home',
action() {
BlazeLayout.render('App_body', { main: 'App_home', mainContent: 'ListOrCalendar' });
}
And then the ListOrCalendar
template would look like this:
{{#if displayList}}
{{> List}}
{{else}}
{{> Calendar}}
{{/if}}
<button>Switch</button>
You would set up a ReactiveVar
in the ListOrCalendar
template:
Template.ListOrCalendar.onCreated(function() {
const instance = this;
instance.displayList = new ReactiveVar(true);
});
See ReactiveVar
explanation here (ignore Session)
Then you would have a helper which returns the value of your ReactiveVar:
Template.ListOrCalendar.helpers({
displayList() {
const instance = Template.instance();
return instance.displayList.get();
}
});
Finally, you would hook up an event to change the value of displayList
to switch between templates:
Template.ListOrCalendar.events({
"click button"(event, instance) {
const displayListCurrent = instance.displayList.get();
const displayListNew = !displayListCurrent;
instance.displayList.set(displayListNew);
// or, more concisely, instance.displayList.set(!instance.displayList.get());
}
});
So, in summary:
ReactiveVar
is true
displayList
returns true
#if displayList
condition in the template is satisfiedList
template is displayedReactiveVar
is set to falsedisplayList
helper returns false
#if displayList
condition in the template is not satisfied and it goes to the else
statementCalendar
template is displayedReactiveVar
is toggled back to true
, and on we go as aboveThis might seem daunting or over-complicated, but there's nothing fancy going on here at all. You'll get used to it pretty quickly