diff --git a/dist/index.html b/dist/index.html index 8a046fa..9600aaa 100644 --- a/dist/index.html +++ b/dist/index.html @@ -55,15 +55,15 @@

Open Orders

-
+

Order Entry Form

- + - - + + diff --git a/src/app.js b/src/app.js index 03ec910..d1c5a05 100644 --- a/src/app.js +++ b/src/app.js @@ -2,9 +2,22 @@ import 'foundation-sites/dist/foundation.css'; import 'css/app.css'; import $ from 'jquery'; +import _ from 'underscore'; import Simulator from 'models/simulator'; + import QuoteList from 'collections/quote_list'; +import Quote from 'models/quote'; +import QuoteView from './views/quote_view'; +import QuoteListView from './views/quote_list_view'; + +import TradeHistoryView from './views/trade_history_view'; + +import OrderListView from './views/order_list_view'; +import OrderFormView from './views/order_form_view'; +import OrderView from './views/order_view'; +import Order from 'models/order'; +import OrderList from 'collections/order_list'; const quoteData = [ { @@ -25,11 +38,72 @@ const quoteData = [ }, ]; +// const quoteList = new QuoteList(); +let quoteTemplate; + + $(document).ready(function() { + let bus = {}; + + bus = _.extend(bus, Backbone.Events); + const quotes = new QuoteList(quoteData); const simulator = new Simulator({ quotes: quotes, }); + // const $quoteList = $('#quotes'); + // + // const quoteView = new QuoteView({ + // model: quotes.at(0), + // template: _.template($('#quote-template').html()), + // tagName: 'li', + // className: 'quote', + // }); + // THESE ARE THE THINGS THAT BACKBONE EXPECTS except for template, which is why we initialized template. + + // $quoteList.append(quoteView.render().$el); + simulator.start(); + + + quoteTemplate = _.template($('#quote-template').html()); + + const quoteListView = new QuoteListView({ + //this is what params becomes + el: '#quotes', + model: quotes, //need explanation + template: quoteTemplate, + tradeTemplate: _.template($('#trade-template').html()), + bus: bus, + }); + + const order = new Order; + const orders = new OrderList(); + + const orderListView = new OrderListView({ + el: '#orders', + model: orders, + template: _.template($('#order-template').html()), + }); + + + + const orderFormView = new OrderFormView({ + el: '#order-entry-form', + orderList: orders, + quoteList: quotes + }); + + quoteListView.render(); + orderListView.render(); + orderFormView.render(); + + // const quoteView = new QuoteView({ + // el: 'ul', + // model: quote, + // template: quoteTemplate, + // }); + // + // quoteView.render(); }); diff --git a/src/collections/order_list.js b/src/collections/order_list.js new file mode 100644 index 0000000..8d7cabd --- /dev/null +++ b/src/collections/order_list.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; +import Order from 'models/order'; + +const OrderList = Backbone.Collection.extend({ + model: Order, +}); + +export default OrderList; diff --git a/src/models/order.js b/src/models/order.js new file mode 100644 index 0000000..675707e --- /dev/null +++ b/src/models/order.js @@ -0,0 +1,31 @@ +import Backbone from 'backbone'; +import Quote from 'models/quote'; + +const Order = Backbone.Model.extend({ + defaults: { + symbol: 'UNDEF', + targetPrice: 0.00, + buy: true, + // quote: null + }, + + validate() { + const targetPrice = this.get('targetPrice'); + const symbol = this.get('symbol'); + + if (!targetPrice) { + console.log("Order cannot be created without a price") + return "Order cannot be created without a price"; + } + + // if (typeof targetPrice != 'float') { + // return "Order price must be a number"; + // } + + if (!symbol) { + return "Please select a symbol"; + } + } +}); + +export default Order; diff --git a/src/models/quote.js b/src/models/quote.js index 4fbf466..c1bb91e 100644 --- a/src/models/quote.js +++ b/src/models/quote.js @@ -6,11 +6,14 @@ const Quote = Backbone.Model.extend({ price: 0.00 }, + buy() { + this.set('price', this.get('price') + 1.00); // Implement this function to increase the price by $1.00 }, sell() { + this.set('price', this.get('price') - 1.00); // Implement this function to decrease the price by $1.00 }, }); diff --git a/src/views/order_form_view.js b/src/views/order_form_view.js new file mode 100644 index 0000000..eccd687 --- /dev/null +++ b/src/views/order_form_view.js @@ -0,0 +1,80 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; +// import QuoteView from '../views/quote_view'; +import Order from '../models/order'; +import OrderList from '../collections/order_list'; +import $ from 'jquery'; + + +const OrderFormView = Backbone.View.extend({ + initialize(params) { + //maybe move the stuff in orderlistview to here?? + this.orderList = params.orderList; + this.quoteList = params.quoteList; + }, + + render() { + this.quoteList.each((quote)=> { + this.$('#symbol').append($(``)); + }); + return this; + }, + + events: { + 'click button.btn-buy': 'buy', + 'click button.btn-sell': 'sell', + // 'click button.btn-buy': 'addNewOrder', + // 'click button.btn-sell': 'addNewOrder', + }, + buy(event) { + // event.preventDefault(); + console.log(event); + event.isBuy = true; + this.addNewOrder(event); + }, + sell(event) { + // event.preventDefault(); + console.log(event); + event.isBuy = false; //I added this to be able to send this info to addneworder, you can add any text you want after event. + this.addNewOrder(event); + }, + + addNewOrder(event) { + console.log(event); + event.preventDefault(); + const orderData = {}; + orderData['symbol'] = $('select[name=symbol]').val(); + orderData['targetPrice'] = parseFloat($('input[name=targetPrice]').val()); + orderData['quote'] = this.quoteList.findWhere({symbol: orderData['symbol']}); + // console.log(orderData['quote'].get('symbol')); + // if (val != '') { + // orderData[field] = val; + // } + + orderData['buy'] = event.isBuy; + + const newOrder = new Order(orderData); + //console.log(newOrder); + // console.log(orderData); + + if (newOrder.isValid()) { + this.orderList.add(newOrder); + // console.log("you added a new order") + // console.log(this.orderList.at(0)); + } + else { + console.log("Not a valid order: " + newOrder.validationError); + } + // updateStatusMessageWith(`New order added: ${newTask.get('task_name')}`); + // } else { + // updateStatusMessageFrom(newTask.validationError); + // } + + //Emptying out the form after + this.$('select[name=symbol]').val(''); + this.$('input[name=targetPrice]').val(''); + }, + +}); + +export default OrderFormView; diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js new file mode 100644 index 0000000..ba8b0b8 --- /dev/null +++ b/src/views/order_list_view.js @@ -0,0 +1,33 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; +// import QuoteView from '../views/quote_view'; +import Order from '../models/order'; +import OrderView from '../views/order_view' +import QuoteList from '../collections/quote_list'; +import $ from 'jquery'; + + + +const OrderListView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.model = params.model; + this.listenTo(this.model, 'update', this.render); + }, + + render() { + this.$el.empty(); + this.model.each((order) => { + const orderView = new OrderView({ + model: order, + template: this.template, + tagname: 'li', + className: 'orders' + }); + this.$el.append(orderView.render().$el); + }); + return this; + }, +}); + +export default OrderListView; diff --git a/src/views/order_view.js b/src/views/order_view.js new file mode 100644 index 0000000..d4a458c --- /dev/null +++ b/src/views/order_view.js @@ -0,0 +1,55 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; +// import QuoteView from '../views/quote_view'; +import Order from '../models/order'; +import OrderList from '../collections/order_list'; +import $ from 'jquery'; + + +const OrderView = Backbone.View.extend({ + initialize(params) { //where do the params come from? app.js + this.template = params.template; + this.model = params.model; + this.listenTo(this.model, 'change', this.render); + //anytime the model changes, it will redraw it + this.listenTo(this.model.get('quote'), 'change', this.executeOrder); + + }, + + executeOrder() { + console.log('execute order is being called'); + let quote = this.model.get('quote'); + + if (this.model.get('buy')) { + if (this.model.get('targetPrice') >= quote.get('price')) { + quote.buy(); + this.model.destroy(); + this.remove(); + } + } else { + if (this.model.get('targetPrice') <= quote.get('price')) { + quote.sell(); + this.model.destroy(); + this.remove(); + } + } + }, + + render() { + const compiledTemplate = this.template(this.model.toJSON()); //go that template, send the data from the model as JSON which is like a hash + + this.$el.html(compiledTemplate); //this replaces the html in that element with the complied string from above compiledTemplate + + return this; + }, + events: { + 'click button.btn-cancel': 'cancel', + }, + cancel(event) { + console.log(event); + this.model.destroy(); + }, + +}); + +export default OrderView; diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js new file mode 100644 index 0000000..9427279 --- /dev/null +++ b/src/views/quote_list_view.js @@ -0,0 +1,42 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; +import QuoteView from '../views/quote_view'; +import TradeHistoryView from '../views/trade_history_view'; + +const QuoteListView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.bus = params.bus; + this.tradeTemplate = params.tradeTemplate; + console.log(params); + + this.listenTo(this.model, 'update', this.render) + }, + + render() { + const tradeHistoryView = new TradeHistoryView( { + bus: this.bus, + el: '#trades', + template: this.tradeTemplate, + }); + this.$el.empty(); + console.log(this); + this.model.each((quote)=> { + const quoteView = new QuoteView({ + model: quote, + template: this.template, + tagName: 'li', + className: 'quotes', + bus: this.bus, + }); + + this.$el.append(quoteView.render().$el); + }); + console.log('render tradeHistoryView') + + return this; + //always return this + }, +}); + +export default QuoteListView; diff --git a/src/views/quote_view.js b/src/views/quote_view.js new file mode 100644 index 0000000..da8ec88 --- /dev/null +++ b/src/views/quote_view.js @@ -0,0 +1,47 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; + +const QuoteView = Backbone.View.extend({ + initialize(params) { //where do the params come from? + this.template = params.template; //I find this strange as well + + this.bus = params.bus; + this.listenTo(this.model, 'change', this.render) + //anytime the model changes, it will redraw it + }, + + render() { + const compiledTemplate = this.template(this.model.toJSON()); //Don't understand exactly how this works + + this.$el.html(compiledTemplate); + + return this; + }, + events: { + 'click button.btn-buy': 'buy', + 'click button.btn-sell': 'sell', + }, + buy(event) { + console.log(event); + this.bus.trigger('trade', { + //this is what trade is + buy: true, + price: this.model.get('price'), + symbol: this.model.get('symbol'), + }); + this.model.buy(); + }, + sell(event) { + console.log(event); + this.bus.trigger('trade', { + buy: false, + price: this.model.get('price'), + symbol: this.model.get('symbol'), + }); + this.model.sell(); + }, + + +}); + +export default QuoteView; diff --git a/src/views/trade_history_view.js b/src/views/trade_history_view.js new file mode 100644 index 0000000..92d8f57 --- /dev/null +++ b/src/views/trade_history_view.js @@ -0,0 +1,47 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; + + +const TradeHistoryView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + console.log(params); + this.bus = params.bus; + this.listenTo(this.bus, 'trade', this.renderTrade); + }, + + // el: '#current-trade', //not sure about this + renderTrade(trade) { + this.trade = trade; + this.render(); + }, + render() { + // if (this.model) { //if I have a model + console.log('rendering current Trade'); + console.log(this.trade); + const compiledTemplate = this.template(this.trade); + + this.$el.prepend(compiledTemplate); + + console.log(this); + // // this.model.each((quote)=> { + // const tradeHistoryView = new TradeHistoryView({ + // model: quote, + // template: this.template, + // tagName: 'span', + // className: 'trade', + // this.$('#trades').append(quoteView.render().$el); + return this; + }, + // events: { + // 'click button.btn-buy': 'trade', + // 'click button.btn-sell': 'trade', + // }, + // trade(event){ + // console.log("you traded something"); + // console.log(event); + // this.$('#trades').append(TradeHistoryView.render().$el); + // }, +}); + +export default TradeHistoryView;