0

Creating a leaderboard in JavaScript that immediately updates to MongoDB. In order to increase the amount of points someone has on the leaderboard, you click on the respective <div> and it increases their score by 5 "points".

This is done by using this function

Template.leaderboard.events({
'click div.inc': function () {
  Players.update(Session.get("selected_player"), {$inc: {score: 5}});
}
});

I want the user to only update one player, but to allow changes. So for example, if the user selects "John Smith", "John Smith" should only be able to be increased 5 points. In addition to that, if the user decides he wants to give the points to "Janie Smith", "John Smith" should lose 5 points and "Janie Smith" should gain.

What's the best way to do this? Can I do this by figuring out the previous "selected_div"?

Stennie
  • 63,885
  • 14
  • 149
  • 175
user3822146
  • 114
  • 3
  • 10

2 Answers2

1

Replace Template.leaderboard.events with this:

Template.player.events({
  click: function() {
    // only continue if this was not the last player clicked
    if (!this.isLast) {

      // find the last player clicked
      var lastPlayerClicked = Players.findOne({isLast: true});

      // remove the isLast marker from the previously clicked player and
      // decrement her score
      if (lastPlayerClicked) {
        var modifier = {$inc: {score: -5}, $unset: {isLast: ''}}
        Players.update(lastPlayerClicked._id, modifier);
      }

      // update this player with a new score and mark her as last
      Players.update(this._id, {$inc: {score: 5}, $set: {isLast: true}});
    }
  }
});

It keeps track of the last clicked player by setting or removing isLast and then modifies the current and last player as appropriate. You may want to make sure you have a clean database by running meteor reset prior to adding this.

David Weldon
  • 63,632
  • 11
  • 148
  • 146
  • Looking back at this, I noticed there is only one vote given (ever). I want each different IP to have a chance to give points. How do I do this? – user3822146 Jul 29 '14 at 18:30
  • 1
    Move the logic to the server via a method call as seen in [this question](http://stackoverflow.com/questions/24816324/limit-meteor-vote-once-per-day). – David Weldon Jul 29 '14 at 18:44
  • Any chance you can update this answer with the combination of the two? I'm confused because there are time limits in that one -- I don't want those here. – user3822146 Jul 29 '14 at 22:39
  • 1
    I'd recommend asking another question saying specifically what you want and referencing those two answers. – David Weldon Jul 30 '14 at 00:08
0

I think you need to add the most recent player to the database:

Template.leaderboard.events({
    'click input.div': function () {
      var player = Session.get("selected_player");
      var currentPlayer = Players.find(player);
      var recentlyChanged = Players.find({changed: true});

      if(recentlyChanged === currentPlayer) {
          Players.update(player,  {$inc: {score: 5}});

      } else {
          Meteor.call('newScore', recentlyChanged, player);

      }
    }
  });

if (Meteor.isServer) {

 Meteor.methods({
        newScore: function(recentlyChanged, player) {
            if(recentlyChanged) {
                Players.update(recentlyChanged, {$inc: {score: -5}});
            }
            Players.update({}, {changed: false}, {multi: true});
            Players.update(player, {changed: true}, {$inc: {score: 5}});
        }
    });

}
Sean L
  • 827
  • 1
  • 11
  • 22