Ember JS Enable dropdown only on element which was clicked - javascript

I am an Ember newbie and can't get my head around how to run events on specific elements populated via records on my ember model.
Here is my Template
{{#each user in model }}
{{#each activecredit in user.activecredits}}
<div class="col-lg-2 hive-credit-box active-credit">
<div class="credit-brandname">
{{activecredit.Brandname}}
</div>
<div class="credit-brand-image-container">
<img src="http://localhost:3000/{{activecredit.Imglocation}}" class="credit-image"/>
</div>
<div class="hive-credit-percent"><img class="hive-filled-container" src="imgs/hivefilled9.png"/></div>
<div class="hive-credit-dollars">$xx.xx</div>
<div {{bind-attr class=activecredit.Brandname}} {{action 'enableTrade'}}><img src="imgs/trade_button.png" class="credit-trade-button" /></div>
<div class="credit-brand-amount">
xx%
</div>
<!-- Trade button click dropdown -->
{{#if isSelected}}
<div class="hivetrade">
<div class="arrow_box">
Hi there
</div>
<div class=""></div>
</div>
{{/if}}
</div>
{{/each}}
{{/each}}
Now I want to show a drop down on each element on click of a button .
When I set the enableTrade action , all dropdowns of all the divs show up.
actions:{
enableTrade:function(){
this.set('isSelected',true);
}
}
How do I enable only the dropdown in the particular div that was created.
I suppose I need to bind certain attributes to each div,but how do I access which div was clicked in my controller?
Any help would be appreciated .
Thanks

You can pass params through the action helper, and use them to set isSelected on the appropriate item.
{{#each model as |user| }}
{{#each user.activeCredits as |activeCredit|}}
<button {{action 'enableTrade' activeCredit}}>Enable Trade</button>
{{#if activeCredit.isSelected}}
<div class="hivetrade">Hello World</div>
{{/if}}
{{/each}}
{{/each}}
To handle it:
actions:{
enableTrade:function(credit) {
credit.set('isSelected',true);
}
}
If you need to allow only one credit to be selected at a time, your controller and action could be modified like this:
selectedCredit: null,
actions:{
enableTrade:function(credit) {
// unselect the previously selected credit
if (this.get('selectedCredit')) {
this.set('selectedCredit.isSelected', false);
}
// select, and cache the selection choice
credit.set('isSelected',true);
this.set('selectedCredit', credit);
}
}

Related

How to set default session and dropdown values in meteor?

I have a collection which store default values according to the logged in user. I have a setting menu where default can be set for the application by the user. How can we set the dropdown of that setting menu to the default value set previously by user every time and how can we set the default session value. I'm using semantic UI and isron router, I'm trying to get the default values from the collection in .onRendered(), but the output will be Values:
Template.header.onRendered (function(){
var defaultSettingValues=defaultSetting.find().fetch()
console.log ("Values: "+defaultSettingValues);
});
The dropdown in settng menu:
<div class="ui selection dropdown button" id="defaultDrop" tabindex="0">
<input type="hidden" name="filter">
<div class="default text">Select from here</div>
<i class="right floated dropdown icon"></i>
<div class="menu" tabindex="-1">
<div class="item" data-value="objId1">abc</div>
<div class="item" data-value="objId2">def</div>
<div class="item" data-value="objId3">hij</div>
</div>
</div>
I'm trying to get the default setting values from collections and then set the session and set the default dropdown.
How can i solve this? or is there any alternate way in which i can achieve this?
Ok so you can set default value of your dropdown with the following code :
Template.header.onRendered (function(){
// Care because it returns an array, and you just need the default value
var defaultSettingValues=defaultSetting.find().fetch();
// Supposing the defaultSettingValues is equals to 'objId1'
$('#defaultDrop').dropdown('set selected', defaultSettingValues);
});
You need to find a way to get your value from what's returning your collection.
I think you should be using helpers in order to achieve this in a good way.
In the Html template
<template name="The_template">
<div class="ui selection dropdown button" id="defaultDrop" tabindex="0">
<input type="hidden" name="filter">
<div class="default text">Select from here</div>
<i class="right floated dropdown icon"></i>
<div class="menu" tabindex="-1">
{{#each option in options}}
<div class="item" data-value="objId1">{{option.someData}}</div>
{{/each}}
</div>
</div>
</template>
Then in the javascript template
Template.The_template.helpers({
options() {
return Collection.find();
}
})

How do I can get a clicked item to show/hide its hidden elements?

I am having some trouble displaying a clicked items hidden elements.
Find below my clicked events code.
'click .stylishTiles'(event, instance) {
event.preventDefault();
var selectedTile = this._id;
Session.set("selectedTile_id2", selectedTile);
$("#hidden").show(300);
$(".selected").addClass('show');
},
'click .show'(event, instance) {
event.preventDefault();
$("#hidden").hide(300);
$(".stylishTiles").removeClass('show');
}
The Session.set("selectedTile_id2", selectedTile) in the clicked event is passed on to the helper via Session.get('selectedTile_id2').
Find below the aimed helper code:
'selectedTile': function () {
var selectedTileId = this._id;
var selectedTile_id2 = Session.get('selectedTile_id2');
if(selectedTileId == selectedTile_id2){
return "selected"
}
}
And find below the code for the targeted template:
<template name="invoicesV2C">
{{#each pendingInvoicesV2C}}
<div class="well well-sm stylishTiles {{selectedTile}}">
<div id ="invoiceAmount"> KES: {{formatCurrency recipientAmount}} </div>
<div id="hidden"> tel: {{recipientNumber}} <br> purpose: {{invoicePurpose}} </div>
</div>
{{/each}}
</template>
The {{#each pendingInvoicesV2C}} in the template correctly generates several items, while correctly hiding their hidden elements by default due to the CSS code
#hidden{
display: none;
}
The much desired effect is that I when I click on any item, its hidden elements, being: <div id="hidden"> tel: {{recipientNumber}} <br> purpose: {{invoicePurpose}} </div> should show, hence
$("#hidden").show(300);
$(".selected").addClass('show');
And in reverse, whenever I click on an item already showing its elements,again being: <div id="hidden"> tel: {{recipientNumber}} <br> purpose: {{invoicePurpose}} </div> it should be hidden.
Currently, regardless of the item I click on, only the first element in the list of items will show/hide its elements.
Kindly help me understand how I can get a clicked element to show its hidden details?
You have numerous errors along with really twisted logic.
Let me help you to simplify that:
CSS:
We're using class instead of id
.hidden {
display: none;
}
Template:
<template name="invoicesV2C">
{{#each pendingInvoicesV2C}}
<div class="well well-sm stylishTiles">
<div class="invoiceAmount">
KES: {{formatCurrency recipientAmount}}
</div>
<div class="toggled hidden">
tel: {{recipientNumber}}
<br>
purpose: {{invoicePurpose}}
</div>
</div>
{{/each}}
</template>
Template Code:
Template.invoicesV2C.events({
'click .stylishTiles'(event) {
event.preventDefault();
const $e = $(event.target).closest('.stylishTiles');
$e.find('.toggled').toggle(300);
}
});
That's all. You don't even need helper and using Session at all.
Here is tiny fiddle, representing how it works: https://jsfiddle.net/iStyx/ff6hvorz/

I cant seem to find the error in Meteor

I am new at meteor and I am having some issues. I am creating a social network app and what it basically does is signs up user and the user can post and follow others. Thats the basic functionality it does right now. I want to add something that when a user clicks on other users profile it shows that users post. But the code isnt working and doesnt show any error at all
Template
<template name="profileArea">
{{#if currentUser}}
<div id="side-profile" class="side-box">
<a class="filter-user">{{currentUser.username}}</a>
</div>
{{/if}}
<div id="side-all" class="side-box">
<a class="community">Community</a>
</div>
{{#if currentUser}}
<div id="side-like" class="side-box">
<h3>Following</h3>
<div class="boxcontent">
{{#each username in following}}
<div>
<a class="filter-user">{{username}}</a>
</div>
{{/each}}
</div>
</div>
<div id="side-likeyou" class="side-box">
<h3>Follows You</h3>
<div class="boxcontent">
{{# each followers}}
<div>
<a class="filter-user">{{username}}</a>
</div>
{{/each}}
</div>
</div>
{{/if}}
</template>
Code:
Template.profileArea.events({
'click .filter-user': function(event){
event.preventDefault();
var selectedUser = event.target.text;
Session.set('username', selectedUser);
},
'click .community': function(event){
event.preventDefault();
Session.set('username', null);
}
});
Template.postsList.helpers({
posts: function() {
//Stuff should happen here but its not -_-
var result;
if(Session.get('username')){
result = Post.find({username: Session.get('username')}, {sort:{created: -1}});
}
else{
result = Post.find({}, {sort:{created: -1}});
}
return result;
}
});
The problem in this case is that you have never actually rendered your postsList template (you have only just defined it).
If you want to actually see postsList you need to call {{> postsList }} from somewhere in your profileArea's HTML. This will render that template and then your postsList.posts helper will execute (and change reactively when Session.get('username')) changes.
Maybe add this after the 'Follows You' section of the profile.
<div id="side-posts" class="side-box">
<h3>Posts</h3>
<div class="boxcontent"> {{> postsList }} <div>
</div>

Deeply nested dynamic templates loses scope of parents

I'm attempting to use a dynamic template to create a virtual number pad; this works by passing rows of buttons to another template that renders them. The issue I'm having is the template cannot use Templates.parentData() to access the context as it becomes undefined. Moving up in the inheritance by using Templates.parentData(2) or (3) does not function either.
Template.bs_num_pad.helpers({
'number_rows' : function(){
var result = [];
console.log(this);
console.log(Template.currentData());
// true
console.log(Template.parentData(1));
// Template viewName="Template.bs_num_pad"
console.log(Template.parentData(-2));
// true
console.log(Template.parentData(-3));
// true
}
});
<!-- begin snippet: js hide: false -->
<template name="bs_num_pad">
<div class="container bsNumPadNumber">
<span style="display:block;text-align:center;">{{getBsNumPadNumber}}</span>
{{#each number_rows}}
<div class="col-3">
{{>bs_buttonset}}
</div>
{{/each}}
</div>
</template>
The number pad template that references another template to generate the bootstrap buttonset.
<template name="bs_buttonset">
{{!Template.dynamic template="bs_buttonset" data=difficultyOptions }}
<div class="btn-group btn-group-md" style="text-align:center;display:inline-block;" role="group">
{{#each this}}
<button id="{{btnId}}" value={{value}} class="btn {{btnClass}}" type="button">
{{#if btnIcon}}<i class="glyphicon {{btnIcon}}"></i>{{/if}}{{#if btnText}}{{btnText}}{{/if}}
</button>
{{/each}}
</div>
</template>
Template.parentData(-2) should return the contents of optionsModal; instead it returns 'true'.

Create an ember component for input validation

I have a form in an Ember app which is starting to get a bit ugly after adding in server side validation feedback and I have tried to convert it into a component using This link as a base
My current input box looks like this:
<div class="form-group">
<label class="group-label">Message:</label>
{{textarea value=model.message classNames="group-control" placeholder="Message"}}
</div>
<div {{bind-attr class=":form-group model.errors.message:has-error"}}>
<label class="group-label">Message:</label>
{{input value=model.message classNames="group-control" placeholder="Message"}}
</div>
{{#if model.errors.message}}
<div class="group-errors">
{{#each error in model.errors.message}}
<div class="error">
{{error.message}}
</div>
{{/each}}
</div>
{{/if}}
I would like to convert that into a component, this is what I currently have:
form-input.hbs
<div {{bind-attr class=":form-group hasError:has-error"}}>
<label class="group-label" {{bind-attr for=label}}>{{label}}</label>
{{yield}}
</div>
{{#if errors.length}}
<p>Errors</p>
<span class="help-block">
{{errors}}
</span>
{{/if}}
form-input_component.coffee
App.FormInputComponent = Ember.Component.extend
label: Em.computed 'for', ->
#get('for').underscore().replace(/_/g, " ").capitalize()
hasError: (->
#get('object.errors')?.has #get('for')
).property 'object.errors.[]'
errors: (->
return Ember.A() unless #get('object.errors')
#get('object.errors').errorsFor(#get('for')).mapBy('message').join(', ')
).property 'object.errors.[]'
This displays the input field correctly but the errors do not display, I am missing something but I am not sure what it is.

Categories