Reputation: 6756
It's list sorted by likes.
Meteor template and reactivity system automatically rerender html template whenever data defined by cursor(barvy.find({}, {sort:{likes: -1}})
) changes. So now on screen list is always sorted by 'likes'. If first item has 50 likes, second item 50 likes and i add one like to second item, then it moves to first position on the screen, because cursor returns it like first item.
My question is: how i can show arrow up on items that moves up in ordered list and arrow down on items that moves down? Because creating of DOM element is handled by Meteor, i don't know how to get info about what elements changes their positions.
Template.poradi.barvy = function () {
return barvy.find({}, {sort:{likes: -1}});
};
Html template:
<body>
{{> poradi}}
</body>
<template name="poradi">
<h2>Poradi</h2>
<ul>
{{#each barvy}}
<li>{{barva}}, {{likes}} <input type="button" id="button_{{barva}}" value="like" /></li>
{{/each}}
</ul>
</template>
Upvotes: 1
Views: 542
Reputation: 64342
If I understand the question correctly, you want to know how each click corresponds to a rendered item. There are a couple of ways to do this, but the easiest is just to render each list item in a separate template. Here is a complete working example:
likes.html
<body>
<h1>Items to like</h1>
{{> itemsList}}
</body>
<template name="itemsList">
<ul>
{{#each items}}
{{> item}}
{{/each}}
</ul>
</template>
<template name="item">
<li>
{{text}} ({{likes}})
<button class='up'>Up</button>
<button class='down'>Down</button>
</li>
</template>
likes.js
if (Meteor.isClient) {
Items = new Meteor.Collection(null);
Meteor.startup(function () {
Items.insert({text: 'apples', likes: 10});
Items.insert({text: 'grapes', likes: 8});
Items.insert({text: 'pears', likes: 6});
Items.insert({text: 'oranges', likes: 4});
});
Template.itemsList.items = function () {
return Items.find({}, {sort: {likes: -1}});
};
Template.item.events({
'click .up' : function () {
Items.update(this._id, {$inc: {likes: 1}});
return false;
},
'click .down' : function () {
Items.update(this._id, {$inc: {likes: -1}});
return false;
}
});
}
I've used a collection local to the client for easy initialization, and so it will reset every time you refresh the page. The key insight is that if you render each item in its own template, the click
events refer only to that item, so you have access to this._id
.
Upvotes: 0
Reputation: 1962
I would like to try something to store the old position with an unique id and compare it against the new position. You could write a extra function by extending your template e.g. (not tested code, but logic should work):
Template.HelloWorld.getArrow = function(uniqueId, currentPosition) {
if(typeof array[uniqueId] == 'undefined') { // If there is no old data
array[uniqueId] = currentPosition;
return "same.png";
}
oldPosition = array[uniqueId];
if(oldPosition < currentPosition) {
arrow = "up.png";
}
else if(oldPosition > currentPosition) {
arrow = "down.png";
}
else {
arrow = "same.png";
}
array[uniqueId] = currentPosition;
return arrow;
};
And thats how to call it in your template "HelloWorld":
<img src="{{getArrow "itemId" "positionNumber"}}">
Every time the data in your collection is changing, the template is redrawn and so the function getArrow would be recalled for every item.
Upvotes: 1