Backbone JS with Rivets JS example

by imehesz

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="https://raw.github.com/mikeric/rivets/master/lib/rivets.js"></script>
For Sale
<div id='auction'>
  <h2 data-text='auction.title'></h2>
  <img data-src='auction.image_url'>
  <div><label>Time left: </label><span data-text='auction.timeRemaining'></span></div>

  <div class='alert-box' data-show='auction.endingSoon'>
    <p>Hurry up! Win this item NOW!</p>
  </div>

    <div><label>Highest Bid: </label> $<span data-text='auction.bid'></span> <button id="addbid" data-hide="auction.ended">Bid +$50!</button></div>
    <div><label>Current Bidder: </label> <span data-text='auction.bidder'></span></div>     

</div>

<div class="poweredby">
    powered by <a href="http://backbonejs.org/" target="_blank">BackboneJS</a> and <a href="http://rivetsjs.com/" target="_blank">RivetsJS</a>
</div>

CSS

.alert-box{
    color: #f00;
    border: 1px solid #f00;
    text-align:center;
    font-weight: bolder;
    margin: 5px 0px;
}

#auction{
    border: 1px solid #aaa;
    padding: 10px;
    width: 250px;   
}

label{
    font-weight: bolder;
}

img{
    width: 100px;
}

.poweredby{
    margin-top: 5px;
    font-size: 11px;
    color: #aaa;
}

.poweredby a{
    color: #777;
}

JavaScript

rivets.configure({
  adapter: {
    subscribe: function(obj, keypath, callback) {
      callback.wrapped = function(m, v) { callback(v) };
      obj.on('change:' + keypath, callback.wrapped);
    },
    unsubscribe: function(obj, keypath, callback) {
      obj.off('change:' + keypath, callback.wrapped);
    },
    read: function(obj, keypath) {
      return obj.get(keypath);
    },
    publish: function(obj, keypath, value) {
      obj.set(keypath, value);
    },
      time: function(obj, keypath){
          obj.set( keypath, value );
      }
  }
});

Auction = {};

Auction.Item = Backbone.Model.extend({});

Auction.AuctionView = Backbone.View.extend({
    el: "#auction",
    
    events:{
        'click #addbid': function(){
            var item = this.model;
            item.set({bid:(item.get('bid')+50), bidder: 'You'});
        }
    },
    
    initialize: function(){
        rivets.bind($('#auction'), {auction: this.model});
         _.bindAll(this, 'updateTimer');
        this.updateTimer();
    },
    
    runTimer: function(){
        var item = this.model;
        if( item.get('timeRemaining') > 0 )
        {
            _.delay(_.bind(this.updateTimer, this), 1000);
        }
    },
    
    updateTimer: function(){
        var item = this.model,
            timeleft = item.get( 'timeRemaining' )-1;
        item.set({timeRemaining: timeleft});
        
        if( timeleft < 15 )
        {
            item.set({endingSoon: true});
        }        

        if( timeleft > 0 )
        {
            this.runTimer();
        }
        else
        {
            item.set({timeRemaining:"-", endingSoon: false, ended: true});
        }
    }    
});

Auction.App = function(){
    this.item = null;
    
    this.start = function(){
        var item = new Auction.Item();

        item.set({
            title: '3" Floppy Drive',
            image_url: "http://gh33da.com/3DIcons/Floppy_Drive_35/Floppy_Drive_35.png",
            timeRemaining: 25,
           ...