|
| 1 | +window.App = {}; |
| 2 | +window.sum = function (list) { return _.reduce(list, function (memo, num) { return memo + num; }, 0); }; |
| 3 | + |
| 4 | +App.thingstableTpl = _.template([ |
| 5 | + '<h3>Things</h3>', |
| 6 | + '<table class="table">', |
| 7 | + ' <thead>', |
| 8 | + ' <tr>', |
| 9 | + ' <th>Item</th>', |
| 10 | + ' <th>$</th>', |
| 11 | + ' <th></th>', |
| 12 | + ' </tr>', |
| 13 | + ' </thead>', |
| 14 | + ' <tbody>', |
| 15 | + ' </tbody>', |
| 16 | + ' <tfoot>', |
| 17 | + ' <tr>', |
| 18 | + ' <td><strong>Total</strong></td>', |
| 19 | + ' <td class="total">0</td>', |
| 20 | + ' <td></td>', |
| 21 | + ' </tr>', |
| 22 | + ' </tfoot>', |
| 23 | + '</table>', |
| 24 | + '<button class="btn btn-default btn-machi btn-sm pull-right"><span class="glyphicon glyphicon-plus"></span> Moar!</button>' |
| 25 | +].join()); |
| 26 | + |
| 27 | +App.ppltableTpl = _.template([ |
| 28 | + '<h3>People</h3>', |
| 29 | + '<table class="table">', |
| 30 | + ' <thead>', |
| 31 | + ' <tr>', |
| 32 | + ' <th>Nickname</th>', |
| 33 | + ' <% things.each(function (thing) { %> <th><%= thing.get(\'name\') %></th> <% }) %>', |
| 34 | + ' <th>To Pay</th>', |
| 35 | + ' <th>Paid</th>', |
| 36 | + ' <th>Balance</th>', |
| 37 | + ' <th></th>', |
| 38 | + ' </tr>', |
| 39 | + ' </thead>', |
| 40 | + ' <tbody> </tbody>', |
| 41 | + ' <tfoot>', |
| 42 | + ' <tr>', |
| 43 | + ' <td><strong class="tt" data-toggle="tooltip" data-placement="bottom" title="Pesos Por Pera">ppp</strong></td>', |
| 44 | + ' <% things.each(function (thing) { %> <td><%= ppp(thing) %></td> <% }) %>', |
| 45 | + ' <td></td>', |
| 46 | + ' <td></td>', |
| 47 | + ' <td></td>', |
| 48 | + ' <td></td>', |
| 49 | + ' </tr>', |
| 50 | + ' </tfoot>', |
| 51 | + '</table>', |
| 52 | + '<button class="btn btn-default btn-machi btn-sm pull-right"><span class="glyphicon glyphicon-plus"></span> 1</button>' |
| 53 | +].join()); |
| 54 | + |
| 55 | +App.pplTmpl = _.template([ |
| 56 | + '<td><input placeholder="Name" class="name" value="<%= name %>" /></td>', |
| 57 | + '<% things.each(function (thing) { %>', |
| 58 | + '<td><input type="checkbox" value="<%= thing.get(\'name\') %>" <% if (thing.containedIn(ownThings)) { %> checked <% } %> /></td>', |
| 59 | + '<% }) %>', |
| 60 | + '<td><%= toPay %></td>', |
| 61 | + '<td><input type="number" class="paid" value="<%= paid %>"></td>', |
| 62 | + '<td><%= balance %></td>', |
| 63 | + '<td><button type="button" class="close" aria-hidden="true">×</button></td>' |
| 64 | +].join()); |
| 65 | + |
| 66 | +App.thingTpl = _.template([ |
| 67 | + '<td><input placeholder="Something" class="name" value="<%= name %>" /></td>', |
| 68 | + '<td><input type="number" class="cost" value="<%= cost %>" /></td>', |
| 69 | + '<td><button type="button" class="close" aria-hidden="true">×</button></td>' |
| 70 | +].join()); |
| 71 | + |
| 72 | +$(function () { |
| 73 | + var $pplData = $('#ppl-data'), $thingsData = $('#things-data'), $version = $('#version'); |
| 74 | + |
| 75 | + App.Things = Backbone.Collection.extend({ |
| 76 | + model: Backbone.Model.extend({ |
| 77 | + defaults: { 'name': '', 'cost': 0, }, |
| 78 | + containedIn: function (list) { return _.contains(list, this.get('name')); } |
| 79 | + }), |
| 80 | + total: function () { return sum(this.pluck('cost')); }, |
| 81 | + }); |
| 82 | + |
| 83 | + App.People = Backbone.Collection.extend({ |
| 84 | + model: Backbone.Model.extend({ defaults: { 'name': '', 'paid': 0, ownThings: [] } }), |
| 85 | + }); |
| 86 | + |
| 87 | + App.ppl = new App.People(JSON.parse($pplData.val())); |
| 88 | + App.things = new App.Things(JSON.parse($thingsData.val())); |
| 89 | + |
| 90 | + App.toJSON = function ($storage, data) { $storage.val(JSON.stringify(data.toJSON())); } |
| 91 | + App.title = function () { }; |
| 92 | + App.dec = function (num) { return parseFloat(num.toFixed(2)) } |
| 93 | + App.base64 = function() { return 'data:text/html;base64,'+ window.btoa(document.documentElement.innerHTML) }; |
| 94 | + App.ppp = function (thing) { |
| 95 | + var n = 0; |
| 96 | + App.ppl.each(function (p) { if (thing.containedIn(p.get('ownThings'))) { n++; } }); |
| 97 | + return n ? App.dec(thing.get('cost') / n) : 0; |
| 98 | + }; |
| 99 | + |
| 100 | + App.toPay = function (p) { |
| 101 | + var total = 0; |
| 102 | + App.things.each(function (thing) { if (thing.containedIn(p.get('ownThings'))) { total += App.ppp(thing); } }); |
| 103 | + return total; |
| 104 | + }; |
| 105 | + |
| 106 | + App.ThingRowView = Backbone.Marionette.ItemView.extend({ |
| 107 | + collection: App.things, |
| 108 | + template: App.thingTpl, |
| 109 | + tagName: 'tr', |
| 110 | + events: {'click .close': 'rm', 'change input': 'update'}, |
| 111 | + rm: function () { return this.collection.remove(this.model); }, |
| 112 | + update: function () { this.model.set({'name': this.$('.name').val(), 'cost': parseFloat(this.$('.cost').val())}); } |
| 113 | + }); |
| 114 | + |
| 115 | + App.PplRowView = Backbone.Marionette.ItemView.extend({ |
| 116 | + collection: App.ppl, |
| 117 | + things: App.things, |
| 118 | + template: App.pplTmpl, |
| 119 | + tagName: 'tr', |
| 120 | + events: {'click .close': 'rm', 'change input': 'update'}, |
| 121 | + rm: function () { return this.collection.remove(this.model); }, |
| 122 | + update: function () { |
| 123 | + var ownThings = []; |
| 124 | + this.$('input[type="checkbox"]:checked').each(function () { ownThings.push(this.value); }); |
| 125 | + this.model.set({'name': this.$('.name').val(), 'paid': parseFloat(this.$('.paid').val()), 'ownThings': ownThings}); |
| 126 | + }, |
| 127 | + serializeData: function () { |
| 128 | + var toPay = App.toPay(this.model); |
| 129 | + var bal = App.dec(this.model.get('paid') - toPay); |
| 130 | + return _.extend({things: this.things, toPay: toPay, balance: bal}, this.model.toJSON()); |
| 131 | + }, |
| 132 | + }); |
| 133 | + |
| 134 | + App.ThingsView = Backbone.Marionette.CompositeView.extend({ |
| 135 | + collection: App.things, |
| 136 | + childView: App.ThingRowView, |
| 137 | + childViewContainer: 'tbody', |
| 138 | + el: '#thingstable', |
| 139 | + template: App.thingstableTpl, |
| 140 | + events: {'click .btn-machi': 'add'}, |
| 141 | + collectionEvents: {'change': 'setTotal', 'remove': 'render'}, |
| 142 | + setTotal: function () { this.$('.total').text(this.collection.total()); }, |
| 143 | + add: function () { this.collection.add({}); }, |
| 144 | + onRender: function () { this.setTotal(); } |
| 145 | + }); |
| 146 | + |
| 147 | + App.PeopleView = Backbone.Marionette.CompositeView.extend({ |
| 148 | + collection: App.ppl, |
| 149 | + childView: App.PplRowView, |
| 150 | + el: '#ppltable', |
| 151 | + childViewContainer: 'tbody', |
| 152 | + template: App.ppltableTpl, |
| 153 | + events: {'click .btn-machi': 'add'}, |
| 154 | + collectionEvents: {'remove change': 'render'}, |
| 155 | + initialize: function () { this.listenTo(App.things, 'add change remove', this.render); }, |
| 156 | + setTotal: function () { this.$('.total').text(this.collection.total()); }, |
| 157 | + add: function () { this.collection.add({}); }, |
| 158 | + serializeData: function () { return _.extend({ things: App.things }, this.collection.toJSON()); }, |
| 159 | + templateHelpers: { 'ppp': App.ppp }, |
| 160 | + onRender: function () { App.toJSON($pplData, App.ppl); App.toJSON($thingsData, App.things); } |
| 161 | + }); |
| 162 | + |
| 163 | + App.ShareBtn = Backbone.View.extend({ |
| 164 | + el: $('#share'), |
| 165 | + initialize: function () { |
| 166 | + this.listenTo(App.things, 'add change remove', this.render); |
| 167 | + this.listenTo(App.ppl, 'add change remove', this.render); |
| 168 | + }, |
| 169 | + render: function () { |
| 170 | + var url = 'http://v.gd/create.php?format=simple&url=' + App.base64();// + '&shorturl=' + App.title(); |
| 171 | + this.$el.attr('href', url); |
| 172 | + } |
| 173 | + }); |
| 174 | + |
| 175 | + //new README |
| 176 | + //release 2.0 |
| 177 | + $('#save').on('click', function () { window.location = App.base64(); }); |
| 178 | + |
| 179 | + App.thingsView = new App.ThingsView().render(); |
| 180 | + //App.peopleView = new App.PeopleView().render(); |
| 181 | + //App.shareBtn = new App.ShareBtn().render(); |
| 182 | + $('.tt').tooltip(); |
| 183 | +}); |
0 commit comments