Ranker_v3

HTML

<div class="ranker-template">
  <div class="item">
      <button class="up">Up <span>0</span></button> 
      <button class="down">Down <span>0</span></button>
      <p class="approval">Approval: <span>0</span>%</p>
      <p class="unique-id"></p>
      <p class="name">test</p>
  </div>
</div> 

<div class="ranker-container"></div>

CSS

body {
  font-family: sans-serif;
}

.ranker-template {
  display: none;
}

.item { 
  border-radius: 5px; 
  padding: 0.5em; 
  border: 1px solid #eee; 
  float: left; 
  clear: both; 
  margin: 0 0 0.5em;
}

.item p {
  display: inline;
}

.item .unique-id {
  font-weight: bold;
}

.item button {
  padding: 0.5em;
}

.item button span {
  padding: 0.3em 0.5em;
  border-radius: 2000px;
  background: #fff;

JavaScript

// object to hold all our code
var dataArray = ["Tom", "Bob", "Fred"];
var ranker = {};

// init function
ranker.init = function() {
  // declare selector, grab collection
  ranker.itemSelector = '.item';
  ranker.items = $(ranker.itemSelector);
  ranker.setupData();
  ranker.bindEvents();
}

// function to set up data
ranker.setupData = function() {
  ranker.items.each(function() {
    var this$ = $(this);
    this$.data({
      'upvotes':   0,
      'downvotes': 0,
      'total':     0,
      'approval':  0,
    });
  })
}
                    
// function that binds the click events to items
ranker.bindEvents = function() {
  // for each item in our collection
  ranker.items.each(function() {
    var this$ = $(this);
    // unbind clicks to prevent multiple bindings
    // when calling ranker.bindEvents() after init
    this$.off('click');
    // vote up click bind
    this$.on('click', '.up', function() {
      ranker.upvote(this$);
    });
    // vote down click bind
    this$.on('click', '.down', function() {
      ranker.downvote(this$);
    });
  })
};

// function invoked by voting UP
ranker.upvote = function(item) {
  var data = item.data();
  // increment upvotes, total
  data.upvotes++;
  data.total++;
  // parseInt() is needed since toFixed() turns our number into a string!
  // not cool! we want to do mathy stuff with it later
  data.approval = parseInt((data.upvotes/data.total*100).toFixed(0), 10);
  // update the UI
  ranker.updateItemUI(item, '.up span', data.upvotes, data.approval);
};

// function invoked by voting DOWN
ranker.downvote = function(item) {
  var data = item.data();
  // increment downvotes, total
  data.downvotes++;   
  data.total++;
  // parseInt() is needed since toFixed() turns our number into a string!
  // not cool! we want to do mathy stuff with it later
  data.approval = parseInt((data.upvotes/data.total*100).toFixed(0), 10);
  // update the UI
  ranker.updateItemUI(item, '.down span', data.downvotes,...