Meteor session not getting set in Template events - meteor

I want to show a button in my template which is shown or not dependent on a session value being true or false. However when I want to set the session to false in events it does not happen:
<template name="Home">
{{#if reload}}
<a class="btn btn-primary fontScale reloadBtn" href="#" id="reload"><i class="fa fa-refresh fa-lg"></i> Reload</a>
{{/if}
</template>
Template.Home.helpers({
reload: function(){
.........
(imgCount1 > imgCount) ? Session.set('more',true):Session.set('more', false);
return Session.get('more');
}
});
Template.Home.events({
......
"click #reload": function(){
Session.set('more', false);
}
});
How can I set the session variable back to false after the button had been clicked?

I guess your helper is keeping the session variable to true. When you click the button, you are setting the session variable, but not the image count.
If that's the case, just put some logging in both the click event and on the helper, and you might see one overwriting the value from the other.

Related

Bootstrap Dropdown with MVC - Keep last selected value displayed

I have the following Bootstrap dropdown in my Coverage MVC View. It defaults to "Active" status. When another status is selected, the associated items are shown on the page, for instance, "Past Coverage".
<div class="dropdown">
<button id="statusButton" class="btn dropdown-toggle ddlDisplay" type="button" data-toggle="dropdown">
Active
<span class="caret"></span>
</button>
<ul id="statusDropdown" class="dropdown-menu">
<li>Active</li>
<li>Past Coverage</li>
<li>Researching Now</li>
</ul>
</div>
I have the following javascript to change the html of the dropdown, so in this case it would say "Past Coverage".
$(".dropdown-menu li a").click(function () {
var selText = $(this).text();
$("#statusButton").html(selText + '<span class="caret"></span>');
This works fine, but you can only see, in this case, "Past Coverage", for a second, because then the href link is fired, the MVC Url.Action is called, the page reloads and Active is once again shown in the dropdown. How do I keep the most recent selected status in the dropdown?
You can use localStorage for storing. If you want to store in a per page session basis, then you can use sessionStorage.
Something like this should do.. Don't forget to clear the localStorage by calling localStorage.clear(); when needed.
$(".dropdown-menu li a").click(function () {
var selText = $(this).text();
$("#statusButton").html(selText + '<span class="caret"></span>');
localStorage['selText'] = selText; // store in storage
|);
$(document).ready(function() {
var selText = localStorage['selText'] || 'defaultValue';
if(selText != 'defaultValue') {
$("#statusButton").html(selText + '<span class="caret"></span>'); // Load previously selected item
}
});
I haven't really done something like this in particular so there must be a better way other than this. But this should work.

Meteor delete list item with selected class

I am trying to add a delete function that if i click on a list item(template) it adds a selected class to the li. I then want be able to click a button that finds the li with a class of selected and passes the data to a meteor method that removes the data from a collection. How do i access this data.
I have tried a few ways but this is what i have so far.
sidebar.js
Template.Sidebar.events({
'click .button-collapse': function() {
console.log("here")
$(".button-collapse").sideNav();
},
'click #delete i': function() {
Meteor.call('deleteListItem', $( "li.selected" )._id);
}
})
sidebar.html
<template name="Sidebar">
<ul id="slide-out" class="side-nav fixed grey darken-3">
<li class="action-bar">
<span id="add-new" data-target="modal-add" class="modal-trigger"><i class="small material-icons">add</i></span>
<span id="save"><i class="small material-icons">note_add</i></span>
<span id="rename"><i class="small material-icons">mode_edit</i></span>
<span id="delete"><i class="small material-icons">delete</i></span>
<span data-activates="slide-out" id="close" class="button-collapse close "><i class="small material-icons right">reorder</i></span>
</li>
<!-- Load save items-->
{{#if Template.subscriptionsReady}}
{{#each userSaves}}
{{>ListItem}}
{{/each}}
{{else}}
<p>Loading</p>
{{/if}}
</ul>
<i class="material-icons">menu</i>
<!-- Modal form to add new simulator file -->
<!-- Modal Structure -->
<div id="modal-add" class="modal">
<div class="modal-content">
<h4>New Simulator</h4>
{{> quickForm collection=saves id="newSimulator" type="insert" buttonClasses="modal-action modal-close btn waves-effect waves-light" buttonContent="Add"}}
</div>
</div>
</template>
list class
Meteor.methods({
deleteListItem: function(id) {
Saves.remove(id);
}
});
You can not retrieve the ID of an object like that. Either your button has to be inside the document you're gonna remove or you have to include the _id in your HTML attributes and get that value.
So simply add data-value="{{_id}}" to your <li> in your loop and get the selected like this:
//this will retrieve the id of one selected element only
//you need to use each/forEach if you want to remove multiple
$('li.selected').attr('data-value')
EDIT:
Another solution would be using Session. Since you click on an item to select it, you can set a Session in that event
//in the click event where you select a list item
Session.set('itemId', this._id);
//in Sidebar events
'click #delete i': function() {
const itemId = Session.get('itemId');
Meteor.call('deleteListItem', itemId);
}
EDIT 2:
If you use Session solution, don't forget to remove the Session when the template is destroyed. Otherwise (for your use case) when you go to another route and come back without deleting a selected item and click the delete button, it will delete the document even though it doesn't appear to be selected.
Template.templateName.onDestroyed(function(){
Session.set('sessionName', undefined);
});

How to call something after DOM changed in meteor?

Template.onRendered :
Callbacks added with this method are called once when an instance of Template.myTemplate is rendered into DOM nodes and put into the document for the first time.
Is there any way to call something after the DOM changed?
For example, a navbar(header) with login/logout button is rendered after user open the homepage, and the navbar is changed after the user logged in(logout button).
I need to do something after the navbar has been changed.
You can refactor your code by creating new templates to introduce finer grained lifecycle events on child templates.
HTML
<template name="navbar">
<div class="navbar">
{{#if currentUser}}
{{> logoutButton}}
{{else}}
{{> loginButton}}
{{/if}}
</div>
</template>
<template name="loginButton">
<button class="login">Login</button>
</template>
<template name="logoutButton">
<button class="logout">Logout</button>
</template>
JS
Template.loginButton.onRendered(function(){
// will print Login after user logged out
console.log(this.$("button").text());
});
Template.logoutButton.onRendered(function(){
// will print Logout after user logged in
console.log(this.$("button").text());
});
Alternatively, you can use an autorun inside Template.navbar.onRendered to listen to user login/logout and perform actions after DOM has been modified using Tracker.afterFlush.
HTML
<template name="navbar">
<div class="navbar">
{{#if currentUser}}
<button class="logout">Logout</button>
{{else}}
<button class="login">Login</button>
{{/if}}
</div>
</template>
JS
Template.navbar.onRendered(function(){
// declare a new reactive computation
// (rerun when the reactive data source is modified)
this.autorun(function(){
// listen to the same reactive data source as in the template helper
// => currentUser
var user=Meteor.user();
// this code will run after every other reactive computations depending
// on the same data source being modified
Tracker.afterFlush(function(){
// will print Logout after user logged in
// will print Login after user logged out
console.log(this.$("button").text());
}.bind(this));
}.bind(this));
});

How to get part of html content inserted in a Meteor template if the content is not in the page already

I am using Meteor 0.7.0.1 with Spark and I have the following template that used to popover content, and the template is inserted at each post items.
<template name="postLinks">
<a href="#" id="ui-popover-container-{{id}}" class="popover-list-trigger dropdown-toggle" data-toggle="dropdown">
<i class="icon-calendar"></i>
</a>
{{#if poppedUp}}
<div id="link-popover-wrapper" style="display:none">
<ul class="link-popover">
{{#each linkOptions}}
<li><a tabindex="-1" class="link-action" id="link-{{value}}" href="#">{{label}}</a>
</li>
{{/each}}
</ul>
</div>
{{/if}}
</template>
I want to print the div "link-popover-wrapper" only once the first time the template loaded. Subsequent template inserts in post items the div won't inserted so only one hidden div is in the page. I handled it using a template variable in following way.
var _poppeUp = true;
Template.postLiks.helpers({
poppeUp : function () {
if (_poppeUp) {
_poppeUp = false;
return true;
}
return false;
}
});
It is working for the first time the page is loaded and only one instance of the div "link-popover-wrapper" is in the page. The problem is when a post is updated and page is re-rendered the template variable still set to false and the div is not printed in the page. I wanted to reset that template variable when a page is re-rendered.
Is there a way to overcome this issue in Meteor ?
Just add code that does the opposite on page render:
Template.postLinks.rendered = function() {
if (!_poppedUp)
_poppedUp = true;
You didn't ask, but this strikes me as an odd way to implement this. Rather than {{#if poppeUp}}, why not {{#with getFirstLinkPopoverWrapper}} and then define a getFirstLinkPopoverWrapper helper that returns just the one link-popover-wrapper div that you want shown? Then you never need to worry about re-renders or tracking some variable.
EDIT: Alternate implementation:
You could simply use jQuery to tell you whether or not an element of id link-popover-wrapper already exists on the page:
Template.postLinks.helpers({
poppedUp: function() {
return $("#link-popover-wrapper").length !== 0;
}
}
That's it. If no such element exists, the length of the jQuery object is zero and the statement evaluates as false and false is returned. Otherwise true is returned and your template adds the element.

show dialogbox is not working in `meteorJs`?

I need help for i had develop the modal dialogbox using meteorJs it is not working when ever click the add client button open a dialog box but it is not working please check where i did a mistake, here is my code below.
template:
<template name="shedule">
<button class="btn btn-success addClients">Add Client</button>
</template>
Js code:
Session.setDefault('showclientDialog', false);
template.shedule.events({
'button #addClient':function(e,t){
console.log("You pressed Add Client button");
e.preventDefault();
Session.set('showclientDialog' , true);
}
});
template.shedule.showclientDialog = function(){
return Session.get('showclientDialog');
}
I believe this should work for you:
template:
added an if block to check the session variable
<template name="shedule">
<button class="btn btn-success addClients">Add Client</button>
{{#if showclientDialog}}
<div class="clientDialogue">Client Dialoge</div>
{{/if}}
</template>
Js code:
fixed the event map to check for correct selector
Session.setDefault('showclientDialog', false);
Template.shedule.events({
'click .addClients':function(e,t){
console.log("You pressed Add Client button");
e.preventDefault();
Session.set('showclientDialog' , true);
}
});
Template.shedule.showclientDialog = function(){
return Session.get('showclientDialog');
}

Resources