I'm trying to open or close a modal on the click of a button.
My current template looks like this:
<template name="Nav">
{{#if currentUser}}
<button class="settings_toggle">
{{email}}
</button>
{{#if settingsMode}}
<div class="settings_modal">
Your Menus
Sign Out
</div>
{{/if}}
{{else}}
<button class="log_in_toggle">
Sign In
</button>
{{#if loginMode}}
<div class="loginModal">
{{> atForm}}
</div>
{{/if}}
{{/if}}
</template>
And in a corresponding .js file I've set up the necessary helpers and events:
Template.Nav.onRendered(function(){
Session.set('settingsMode',true);
Session.set('loginMode',true);
});
Template.Nav.helpers({
loginMode(){
return Session.get('loginMode');
},
settingsMode(){
return Session.get('settingsMode');
}
});
Template.Nav.events({
'click .settings_toggle'(event){
Session.set('!settingsMode');
},
'click .log_in_toggle'(event){
Session.set(!'loginMode');
}
});
Template.Nav.events({
'click .settings_toggle'(event){
Session.set('!settingsMode');
},
'click .log_in_toggle'(event){
Session.set(!'loginMode');
}
});
Now, I assume this is because of my limited knowledge of javascript, but how would I properly get it to work so that when .log_in_toggle is clicked, it sets loginMode to false if true and vice versa.
Since you have jQuery, you can easily show/hide elements on click events. I don't see a reason to have sessions here.
Events:
'click .settings_toggle': function(){
//Shows a hidden element
$('.elementClass').show()
}
'click .close_modal': function(){
//Hides element
$('.elementClass').hide()
}
In your CSS, have both of the modals have display: none; as the jQuery .show() will make them visible.
In your helpers, and .onRendered(), just erase the sessions because you already display the right elements by checking {{#if currentUser}} and your modals will be initially hidden with CSS and you'll show them with click event.
EDIT
Additionally, you have two Template.Nav.events({}). You can't do that.
Related
Hi Guys i have a small problem,
i have a click event on a settings icon but the settings icon is inside a link so when i click the icon the click event is called but i cant see anything because i getting redirected to the next page so i need a way to click the icon without firing the link
<template name="startseite">
<div id="viewport">
{{#each gebiet}}
<div id="viewmode">
this is the link--> <a id="link" href="/straßen/{{this._id}}">
<div id="gebietsCard">
<ul id="gebieteListe">
and here the icon --> <li id="settings"><i id="setting" class="material-icons md-24 md-light">settings</i></li>
<li id="überschrift">{{Gebietsname}}</li>
<li>{{Gebietsnummer}}</li>
<li>{{Ort}}</li>
</ul>
</div>
</a>
</div>
<div id="editmode">
<div id="gebietsCardEdit">
test
</div>
</div>
{{/each}}
</div>
</template>
my js:
Template.startseite.events({
'click #settings': function(){
console.log("geklickt")
$("#editmode").css('display', 'inline');
$("#viewmode").css('display', 'none');
}
});
I hope you can help me thanks Guys ;)
This could be done easily with:
Template.startseite.events({
'click #settings': function(e){
e.stopPropagation();
e.preventDefault(); // I am not sure if this is needed, try it yourself and remove if it is no use
$("#editmode").css('display', 'inline');
$("#viewmode").css('display', 'none');
}
}
You can find more information regarding these two functions here:
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
In meteor, I have created a cards dynamically after submitting the form. and the dynamic card contains the show and hide buttons. When I click on show option button the hidden part is showing for all the cards instead of that particular card. the problem is the card is creating dynamically so I thought that is problem .. how to make the functionality to work separately to the each card.
Here I am attaching the code:
<div id="newActionCard">
{{#each newaction}}
<div class="workflowcard">
<div class="module-card">
<div class="res-border"></div>
<div class="card-img"></div>
<div class="res-content">
<div class=" assigned-team">{{team}}</div>
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="description">{{description}}</div>
<div class=" due-on">Due on:{{d_date}}</div><hr>
<div class="subcontent">
{{> actioncardsubcontent}}
</div>
<div class="reqext">
{{> requestextensioncard}}
</div>
</div>
<div class="due">
Due on:
<div>
<span class="day-stamp">THU</span><br>
<div class="date-stamp">26</div>
<div class="month-stamp">AUG
</div>
</div>
</div>
</div>
<div class="btn-box newaction">
<button type="button" class="cancelsub" >New Action</button>
<button type="submit" class="createbtnsub" >Show Options</button>
</div>
<div class="btn-box showoption">
<button type="button" class="hideoption" style="display:none">Hide Options</button>
</div>
{{/each}}
</div>
In JS I have written the hide and show functionalities in the events..now how to stop functionality to all cards at a time.
Here is my JS:
Template.workflow.events({
"click .createbtnsub" : function() {
$( ".subcontent" ).show();
$('.createbtnsub').hide();
$('.cancelsub').hide();
$('.hideoption').show();
$('.requestextension').show();
},
"click .hideoption": function(){
$('.subcontent').hide();
},
"click .hideoption": function(){
$(".subcontent").hide();
$('.cancelsub').show();
$('.createbtnsub').show();
$('.requestextension').hide();
$('.hideoption').hide();
$('.reqext').hide();
},
"click #createActionBtn": function(){
$('#createAction').hide();
$('.editw').show();
$('.hidew').show();
},
});
Template.actioncardsubcontent.rendered = function(){
this.$(".subcontent").hide();
};
Template.requestextensioncard.rendered = function(){
this.$(".reqext").hide();
};
Template.workflow.helpers({
getWorkflow: function(){
return Workflow.find();
},
user: function(){
return Meteor.users.find({});
},
getNewaction: function(){
return Newaction.find();
},
});
Please see the following and adjust the selectors as needed:
"click .showoption": function(event){
$(event.currentTarget).next('button').show();
}
This will work for selecting sibling elements, however as a tip I would recommend rewriting your template.helper that returns the cards data from the database into something more specific.
Something like dynamic classes based on index or id so your class/id names would return as follows .showoption-12kjddfse4 . Then you can just get the attribute of the current target and apply it to your js selector.
Also as kind of an explination to why all buttons were showing, is you were using the class selector, which is meant for grabbing groups of elements/nodes. This is also another reason to created more specific classnames/ids to your use case.
So in your class name you could do something like
<button class="showoption" id="{{_id}}">button</button>
<button id="hiddenoption-{{_id}}" class="hiddenoption">button</button>
Then selecting your elements would be easier as follows:
'click .showoption'(event) => {
let id = event.currentTarget.getAttribute(id);
document.getElementById('hiddenoption-'+id).style.display = 'block';
}
I have a standard way in my ember app to display alert messages. I just pass it a string.
But now I want to include an ember link inside my message.
This is not working:
afterModel: function(model) {
if (model.length) {
this.send("addAlert", "Click {{#link-to 'reviews.show' 1}}here{{/link-to}} to see the review");
}
}
This is how the html is rendered:
{{#each alerts as |alert|}}
<div data-alert class="alert-box {{alert.state}} radius">
{{{alert.message}}}
<a class="close" {{action 'removeAlert' alert}}>x </a>
</div>
{{/each}}
With a handlebars tripple-thing {{{}}}
Any ideas on how to make this work?
I know you can add bubbles=false to actions to stop propagation to parent elements, but how do you stop an action from getting called on it's child elements?
I'm trying to create an overlay to my site, which has a transparent background overlay-bg, a close button and some overlay-content. Each of these elements should be clickable to hide the overlay. But whenever I click the popup (which is restricted to a width of 400px inside the overlay-content) or the form elements inside the popup, etc... the hide method is still being called. The other actions on my form, etc are also being called at the same time.
My initial thought, a way I've done this with jQuery, is to use the event to determine if the clicked element has a class on it like canClose, so that if a child element is clicked the function would return before completion... but I can seem to figure out how to access an event object from the action. I tried returning this as a parameter of the action, but that just returns the ember component itself and not the element that was clicked.
Component:
App.OverlayComponent = Ember.Component.extend({
elementId: 'login-overlay',
// ...
actions: {
// ...
hide: function () {
var view = this;
view.set('showing', false);
view.$().one(Ember.$.support.transition.end, function () {
view.destroy();
});
}
},
});
Template:
<div class="overlay-bg" {{action 'hide'}}></div>
<a href="#" class="close" {{action 'hide'}}>×</a>
<div class="overlay-content" {{action 'hide' this}}>
<div class="popup">
<h1>Login</h1>
<form {{action 'login' on='submit'}}>
<label for="username">Username</label>
{{input value=username id="username" placeholder="Your email address" classNameBindings='usernameError:error'}}
<label for="password">Password</label>
{{input type="password" value=password id="password" placeholder="Password" classNameBindings='passwordError:error'}}
<button class="btn btn-primary" {{action 'login'}}>Login</button>
<p class="text-center forgot"><a href="#" {{action 'forgot'}}>Forgot Password?</a></p>
</form>
<hr>
<p class="mb0 text-center"></i> Login with Facebook</p>
</div>
<p class="text-center signup">Don't have an account? <a href="#" {{action 'signup'}}>Signup</a></p>
</div>
UPDATE:
Forgot to mention, I also tried adding e to my hide function and inside the handlebars helper in the template (hide: function (e) {} and {{action 'hide' event}}) but when I log e it's undefined.
Also, I'm using Ember 1.0.0... do I need to update to a newer version to get access to events in my actions?
I had this exact problem. I kept the action on the bg layer and removed it from the parent element, i.e.
<div class="overlay-bg" {{ action 'hide' }}></div>
<div class="overlay-content">...</div>
If you had the action on .overlay-content because it covers .overlay-bg, you may need
.overlay-content {
pointer-events: none;
}
.overlay-content > * {
pointer-events: all;
}
So, Basically i'm new to meteor(0.8.2) and trying to create a basic app having two templates(addnewPlace and Map) and a single button. What i need to get is that, when i click on "Add new Place" button, template "addNewPlace" should be loaded in body or else template "Map" should be loaded. Help will be appreciated :)
My html code:
<body>
{{> menu}}
{{> body}}
</body>
<template name="body">
{{#if isTrue}}
{{> addnewPlace}}// tested this template individually, it works.
{{else}}
{{> maps}} // tested this template individually, it works too.
{{/if}}
</template>
<template name="menu">
<h1>Bank Innovation Map</h1>
<input type="button" value="Add new Place">
</template>
My js code:
Template.body.isTrue = true;
Template.menu.events({
'click input': function(){
//load a new template
console.log("You pressed the addNewplace button");//this fn is called properly
Template.body.isTrue = true;
}
});
Well first of all you obviously aren't changing anything in the click event (true before, true after). But also if you did, I think you might be better off using a session variable for this, to maintain reactivity.
Session.setDefault('showAddNewPlace', false)
Template.body.isTrue = function() { Session.get('showAddNewPlace'); }
Template.menu.events({
'click input': function(){
//load a new template
console.log("You pressed the addNewplace button");//this fn is called properly
Session.set('showAddNewPlace', true)
}
});
Meteor 0.8.2 comes in with the dynamic template include feature. Just set a session variable value on click event and you would like to use the template name on the event.
Session.setDefault('myTemplate', 'DefaultTemplateName');
"click input": function (event) {
Session.set("myTemplate", 'template_name');
}
You can now write this:
<body>
{{> menu}}
{{> body}}
</body>
<template name="body">
{{> UI.dynamic template=myTemplate}}
</template>
<template name="menu">
<h1>Bank Innovation Map</h1>
<input type="button" value="Add new Place">
</template>
You may like to take a look at this article for the reference:
https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/