I am new to meteor and js and trying to build some app using meteor.
I want to get the _id for further use. Before I just use this._id to get the object id but this time I cannot.
Here is the html:
{{#each player in getPlayers}}
<div class="card test">
<div class="content">
<a class="header">{{player.name}}</a>
</div>
</div>
{{/each}}
Here is the js:
Template.playerList.helpers({
'getPlayers'(){
var player = PlayerLists.find().fetch();
return player;
}
});
and the function I try to catch the _id:
'click .test': function() {
event.preventDefault();
var currentId = this._id;
currentPlayer = PlayerLists.findOne({_id:currentId});
console.log(currentId);
}
PlayerLists is a collection and play is document. I try to just the selected player's _id but currentId shows undefined whenever I click the player.
Could anyone help me with it? Thanks a lot!
I use a simple solution:
{{#each player in getPlayers}}
<div class="card test">
<div class="content">
<a class="header useThisEvent" data-id="{{_id}}>{{player.name}}</a>
</div>
</div>
{{/each}}
'click .useThisEvent': function() {
event.preventDefault();
//there you have id of selected item. Its imporatant to use event.currentTarget
var id = $(event.currentTarget).data('id')
}
//Try to simple you code:
Template.playerList.helpers({
'getPlayers'(){
return PlayerLists.find().fetch();
}
});
{{#each player in getPlayers}} i suggest to change for {{#each getPlayers}}
btw in 'this' probably you have window object, not _id from PlayerList collection. Try to use Template.instance() or Template.currentData() but this methods sometimes can return something else.
Related
I am only posting the necessary code and solving this much will clear rest of my doubts. I am new to angularjs, so kindly forgive if I am asking something stupid.
I am using ng-repeat to generate a list which uses an array defined in the controller scope. When I click on 'Add Another' button, a new element is created. I want to get access of this element to add a class to it. But when I use 'getElementById' function in the same function 'addNewForm' I get 'null'.
However, when I call function 'fn' by hitting 'Find Untitled' button, I get the correct element. Could anybody explain and solve this? Any help is appreciated. Thanks in advance!
I am posting the code below:
HTML:
<div ng-controller="myctrl3">
<ul id ="menu_Ul">
<li ng-repeat="x in list">
<button id="{{ 'navAppsButtonID-' + $index }}">{{x}}</button>
<br>
</li>
<li>
<button ng-click="addNewForm()">Add another</button>
</li>
</ul>
<button ng-click="fn()">Find Untitled</button>
</div>
JS:
.controller("myctrl3", function($scope) {
var list = ['abcd', 'efgh', 'ijkl', 'mnop'];
$scope.list = list;
$scope.abc = function () {
var listPush = function () {
$scope.list.push("Untitled Menu");
for(var i = 0;i<$scope.list.length-1;i++) {
var element = document.getElementById('navAppsButtonID-'+i);
element.classList.remove('current');
}
};
var listLen = $scope.list.length;
if($scope.list[listLen-1] === undefined) {
listPush();
}
else if ($scope.list[listLen-1] == "Untitled Menu") {
alert("Cannot open more than one Untitled Menu at the same time.");
}
else {
listPush();
}
};
$scope.addNewForm = function() {
$scope.abc();
console.log("Element is: ", document.getElementById('navAppsButtonID-'+($scope.list.length-1)));
};
$scope.fn = function () {
console.log("Element is: ", document.getElementById('navAppsButtonID-'+($scope.list.length-1)));
};
})
You're thinking too much jQuery and too little angular. If the goal is to add a class to the last element of ng-repeat, this is how you do that:
<li ng-repeat="x in list">
<button ng-class="{ current: $last }">{{ x }}</button>
</li>
$last is a variable available inside ng-repeat, and if it's true, ng-class will set the class current on the element.
You don't assign unique ids to elements to getElementById from somewhere else when working in angular.
I've set a value when the user click vote choice. Its working.
.then(function(response) {
localStorage.setItem('isClicked', 'Yes');
var i = +localStorage.key("nid");
var nidId = 'nid' + localStorage.length;
localStorage.setItem(nidId, vm.nid);
vm.clickedBefore = true;
})
This is my HTML scope:
<div class="card myfunc" ng-repeat="myfunc in myfuncPage.myfuncs" id="{{myfunc.nid}}" >
<div class="item item-text-wrap">
<h2 class="item-icon-left"><i class="icon ion-ios-analytics"></i>
{{myfunc.title}}</h2>
</div>
<div class="item item-text-wrap" ng-show="localstorage">
<img ng-src="{{myfunc.field_image.und[0].imgPath}}"/>
<p class="custom-class" ng-bind-html='myfunc.body.und[0].value'>
</p>
<ul ng-repeat="vote in myfunc.advmyfunc_choice">
<li ng-repeat="voteselect in vote">
<div class="row">
<button class="col button button-outline button-dark" ng-click="myfuncPage.sendNid(myfunc);myfuncPage.sendVote(voteselect);showVoted = ! showVoted" >{{voteselect.choice}}</button>
<div class="voted-screen" ng-show="showVoted">
<h3>Thanks.</h3>
</div>
</div>
</li>
</ul>
</div>
</div>
In basically, I need remember the div via localStorage and when the page refresh, hide choice divs.
ng-show="showVoted" working on click but I need on refresh.
What is the best way to do it? Thanks.
I am not sure what local storage module you are using, so I can't be specific, but I would write factory that handles the retrieval and storage of the values you need
(function () {
var voteFactory = function (localStorage) {
return {
getVote: function (key) {
var isVoted = false;
// get local storage item, set voted etc
var voted = localStorage.getItem(key);
if(voted) {
isVoted = voted;
}
return isVoted;
},
setVote: function(key, value) {
localStorage.setItem(key,value);
}
};
};
app.factory('voteFactory', ['localStorage', voteFactory]);
})();
Then within the scope controller/directive you are using to show or hide you would have a function:
$scope.showVoted = function(key) {
return voteFactory.getVote(key);
}
then ng-show="showVoted(theidentifieryouwantouse)"
It is also worthwhile to mention I would use ng-if instead of ng-show. To be more efficient you could store your votes as an array instead of individual values and do a check to see if you have retrieved all values, get from local storage if not. Then your functions would interrogate retrieved array instead of repeated calls to local storage. I would also advice maybe using a promise in the factory because retrieval from local storage could be delayed causing some ui oddities.
Hopefully this is along the lines of what you are looking for. I can elaborate if needed.
I am trying to remove a single document from the collection in over server side with Meteor.methods by passing _id of object ,but it is not removing object , also tried other fields in that document but no go.
I have also tried FoodCategory.remove(removeID) ; that is also not working.
File 1 - displayCategorySection.html
<template name="categoryDisplaySection">
<div class="row categoryDisplay">
<div class="col-md-10 col-lg-10 ">
{{Category}}
</div>
<div class="col-md-2 col-lg-2 pull-right">
<i class="fa fa-minus-square"></i>
</div>
</div>
<div class="row ">
<div class="col-md-12 col-lg-12 identity">
{{_id}}
</div>
</div>
</template>
In the .JS file I am passing this _id to Meteor method deleteFoodCategory
File 2 - categoryDisplaySection.js
Template.categoryDisplaySection.events({
'click .fa-minus-square':function(evt,tmpl)
{
var remove_id = tmpl.$(".identity").text();
alert(remove_id);
/*****Server side call for document remove *****/
Meteor.call("deleteFoodCategory",remove_id,
function(error,result)
{ alert(result); });
}
});
Server Side File 3 - FoodCategorySection.js contain deleteFoodCategory method
Meteor.methods({
deleteFoodCategory: function(removeID)
{
return FoodCategory.remove({
'_id' : removeID
},
function(error,id)
{
if(id) { return id;} else { return error; }
});
}
});
Code is working correctly if I put _id like "RAEnLfomeqctuonnE" in place of variable removeID. I tried various options like '_id' or just _id without quotes , unable to figure out problem.Please take a look
Fetching the document _id from a div text is overkill, you could use the current data context instead :
Template.categoryDisplaySection.events({
"click .fa-minus-square": function(evt,tmpl){
var removeId = this._id;
alert(removeId);
Meteor.call("deleteFoodCategory", removeId);
});
In your Meteor method, you can simply pass the _id to Collection.remove :
Meteor.methods({
deleteFoodCategory: function(removeId){
return FoodCategory.remove(removeId);
}
});
Answer provided by saimeunt is also working correctly as far as original problem is concern , there is need to use .trim function with remove_id variable
File 2 - categoryDisplaySection.js
Template.categoryDisplaySection.events({
"click .fa-minus-square": function(evt,tmpl){
var remove_id = tmpl.$(".identity").text();
/**This line needed to be added**/
removeId = remove_id.trim();
alert(removeId);
/*****Server side call for data insert *****/
Meteor.call("deleteFoodCategory",removeId);
})
but as #saimeunt has said fetching the document _id from a div text is overkill,so using this_id from now on
I am trying to filter my collection based on the selection of value from select dropdown list. I have tried with the solutions here and here and its not working enough for me. Below is the template where i want to filter.the select dropdown is in another template categoryFilter which iam calling here using {{> categoryFilter}} to filter the list of collections under {{#each car}} block. The field i am using in schema is ccategory which i want to filter
<template name="carsList">
<div class="col s12 filter-holder">
<div class="col m4 s4 filter-box">
{{> categoryFilter}}
</div>
</div>
<div class="col s12">
<ul class="collection" id="listings">
{{#each cars}}
<li>
{{> carItem}}
</li>
{{/each}}
</ul>
</div>
</template>
this is my existing helper for calling all cars
Template.carsList.helpers ({
'allCars': function() {
return Cars.find();
},
});
this is how my event look like for this. var pageSession=ReactiveDict();
Template.carsList.events({
"click .categoryselection": function(e, t){
var text = $(e.target).text();
pageSession.set("selectedCategory",text);
}
});
I am using ReactiveDict() package for this filtering.Am i doing it right till now? How can i filter the values and call them on the <ul> list and filter <li> values.Please help me
Since you are only storing one value at a time (the selected category), there is no real need to use a ReactiveDict for this case, is there? If so, you could do it with a ReactiveVar instead:
Template.carsList.onCreated(function () {
this.selectedCategory = new ReactiveVar();
});
Template.carsList.helpers ({
'allJobs': function() {
var category = Template.instance().selectedCategory.get();
return Cars.find(category ? {ccategory: category} : {});
},
});
Template.carsList.events({
"click .categoryselection": function(e, t){
var text = $(e.target).text();
t.selectedCategory.set(text);
}
});
If you still want to use a ReactiveDict for multiple filter values such as ccategory and city, you could go with:
Template.carsList.helpers ({
'allJobs': function() {
var filter = {};
var category = pageSession.get("selectedCategory");
var city = pageSession.get("selectedCity");
if (city)
filter.city = city;
if (category)
filter.ccategory = category;
return Cars.find(filter);
},
});
Template.carsList.events({
"click .categoryselection": function(e, t){
var text = $(e.target).text();
pageSession.set("selectedCategory",text);
},
"click .cityselection": function(e, t){
var text = $(e.target).text();
pageSession.set("selectedCity",text);
}
});
I have the following event in my client file:
Template.categories.events({
...
'keyup #add-category': function (e,t){
if (e.which === 13)
{
var catVal = String(e.target.value || "");
if (catVal)
{
lists.insert({Category:catVal,owner:this.userId});
Session.set('adding_category', false);
}
}
},
...
});
And this is the relevant template part:
<template name="categories">
<div id="categories" class="btn-group">
{{#if new_cat}}
<div class="category">
<input type="text" id="add-category" value="" />
</div>
{{else}}
<div class="category btn btn-inverse" id="btnNewCat">+</div>
{{/if}}
{{#each lists}}
<div class="category btn {{list_status}}" id="{{_id}}">
{{Category}}
</div>
{{/each}}
</div>
</template>
So when a new Category is inserted, the owner should be set.. But it doesn't.
Here's the entry in MongoDB:
> db.lists.find()
{ "Category" : "test-admin", "_id" : "EsybjC3SLnNzCBx2t" }
Any idea what I'm doing wrong? (actually I'm following the "Getting Started with Meteor" book lending library example
EDIT it seems that:
console.log(this.userId);
undefined
Swap this line:
lists.insert({Category:catVal,owner:this.userId});
to this one:
lists.insert({Category:catVal,owner:Meteor.userId()});
this is probably not what you expect it to be inside that event. You should debug to confirm that that is the case. You are probably just getting undefined for this.userId. I would recommend assigning this to a variable (call it "self" or "that") outside of this event handler function but inside the scope where this will be what you actually want it to be. You can then reference that variable inside the event handler.
It should look like this:
function thatRegistersEvents() {
var self = this;
// ...
registerSomeEvent(function () {
return self.someThisProperty;
});
}
This is the correct behavior. If you read the official Meteor documentation for references to this.UserId, it is only available in Meteor.publish() and Meteor.methods(). this.UserId is not available in Meteor.template(), which you have done in the code sample above, so one must use Meteor.userId() in templates.