From 958c487d7a2c7dcc1c2d6c039256cfa4da9a87b1 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Mon, 11 Dec 2017 20:19:33 -0800 Subject: [PATCH 01/13] Added quote view and quote list view, import links added in app.js --- src/app.js | 4 ++++ src/views/quote_list_view.js | 12 ++++++++++++ src/views/quote_view.js | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/views/quote_list_view.js create mode 100644 src/views/quote_view.js diff --git a/src/app.js b/src/app.js index 03ec910..7843129 100644 --- a/src/app.js +++ b/src/app.js @@ -2,9 +2,13 @@ import 'foundation-sites/dist/foundation.css'; import 'css/app.css'; import $ from 'jquery'; +import _ from 'underscore'; import Simulator from 'models/simulator'; +import Quote from 'models/quote'; import QuoteList from 'collections/quote_list'; +import QuoteView from 'views/quote_view'; +import QuoteListView from 'views/quote_list_view'; const quoteData = [ { diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js new file mode 100644 index 0000000..019e557 --- /dev/null +++ b/src/views/quote_list_view.js @@ -0,0 +1,12 @@ +import Backbone from 'backbone'; +import _ from 'underscore'; +import QuoteView from './quote_view'; +import Quote from '../models/quote'; + +const QuoteListView = Backbone.View.extend({ + initialize(params) { + + }, +}); + +export default QuoteListView; diff --git a/src/views/quote_view.js b/src/views/quote_view.js new file mode 100644 index 0000000..0544857 --- /dev/null +++ b/src/views/quote_view.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; + +const QuoteView = Backbone.View.extend({ + +}); + +export default QuoteView; From 8cad806f97f001c3eb454c71b5729f1759017630 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Mon, 11 Dec 2017 20:36:58 -0800 Subject: [PATCH 02/13] Quotes are displayed in the view, clicking buy/sell increase/decrease the value for each quote --- src/app.js | 10 ++++++++++ src/models/quote.js | 2 ++ src/views/quote_list_view.js | 15 ++++++++++++++- src/views/quote_view.js | 20 +++++++++++++++++++- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index 7843129..b403790 100644 --- a/src/app.js +++ b/src/app.js @@ -10,6 +10,8 @@ import QuoteList from 'collections/quote_list'; import QuoteView from 'views/quote_view'; import QuoteListView from 'views/quote_list_view'; +const quoteList = new QuoteList(); + const quoteData = [ { symbol: 'HUMOR', @@ -35,5 +37,13 @@ $(document).ready(function() { quotes: quotes, }); + const quoteListView = new QuoteListView({ + model: quotes, + template: _.template($('#quote-template').html()), + el: '#quotes-container', + }); + + quoteListView.render(); + simulator.start(); }); diff --git a/src/models/quote.js b/src/models/quote.js index 4fbf466..263bb81 100644 --- a/src/models/quote.js +++ b/src/models/quote.js @@ -8,10 +8,12 @@ const Quote = Backbone.Model.extend({ buy() { // Implement this function to increase the price by $1.00 + this.set('price', this.get('price') + 1.00); }, sell() { // Implement this function to decrease the price by $1.00 + this.set('price', this.get('price') - 1.00); }, }); diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js index 019e557..176e22b 100644 --- a/src/views/quote_list_view.js +++ b/src/views/quote_list_view.js @@ -5,7 +5,20 @@ import Quote from '../models/quote'; const QuoteListView = Backbone.View.extend({ initialize(params) { - + this.template = params.template; + this.listenTo(this.model, 'update', this.render); + }, + render() { + this.model.each( (quote) => { + const quoteView = new QuoteView({ + model: quote, + template: this.template, + tagName: 'li', + className: 'quote', + }); + this.$('#quotes').append(quoteView.render().$el); + }); + return this; }, }); diff --git a/src/views/quote_view.js b/src/views/quote_view.js index 0544857..57ddefd 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -2,7 +2,25 @@ import Backbone from 'backbone'; import Quote from '../models/quote'; const QuoteView = Backbone.View.extend({ - + initialize(params) { + this.template = params.template; + this.listenTo(this.model, 'change', this.render); + }, + render() { + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate); + return this; + }, + events: { + 'click button.btn-buy': 'buyQuote', + 'click button.btn-sell': 'sellQuote', + }, + buyQuote: function(event) { + this.model.buy(); + }, + sellQuote: function(event) { + this.model.sell(); + } }); export default QuoteView; From 884bb858153ee7666f742ecebc956943ce777693 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Tue, 12 Dec 2017 18:40:41 -0800 Subject: [PATCH 03/13] Trade history shows bought and sold quotes to the user --- src/app.js | 7 +++---- src/views/quote_list_view.js | 6 ++++++ src/views/quote_view.js | 4 ++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app.js b/src/app.js index b403790..a8c82ae 100644 --- a/src/app.js +++ b/src/app.js @@ -7,11 +7,10 @@ import _ from 'underscore'; import Simulator from 'models/simulator'; import Quote from 'models/quote'; import QuoteList from 'collections/quote_list'; + import QuoteView from 'views/quote_view'; import QuoteListView from 'views/quote_list_view'; -const quoteList = new QuoteList(); - const quoteData = [ { symbol: 'HUMOR', @@ -40,10 +39,10 @@ $(document).ready(function() { const quoteListView = new QuoteListView({ model: quotes, template: _.template($('#quote-template').html()), - el: '#quotes-container', + tradeTemplate: _.template($('#trade-template').html()), + el: 'main', }); quoteListView.render(); - simulator.start(); }); diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js index 176e22b..42c92be 100644 --- a/src/views/quote_list_view.js +++ b/src/views/quote_list_view.js @@ -6,6 +6,7 @@ import Quote from '../models/quote'; const QuoteListView = Backbone.View.extend({ initialize(params) { this.template = params.template; + this.tradeTemplate = params.tradeTemplate; this.listenTo(this.model, 'update', this.render); }, render() { @@ -16,10 +17,15 @@ const QuoteListView = Backbone.View.extend({ tagName: 'li', className: 'quote', }); + this.listenTo(quoteView, 'quoteAction', this.trade); this.$('#quotes').append(quoteView.render().$el); }); return this; }, + trade: function(quoteView) { + const compiledTradeTemplate = this.tradeTemplate(quoteView.model.toJSON()); + this.$('#trades').prepend(compiledTradeTemplate); + }, }); export default QuoteListView; diff --git a/src/views/quote_view.js b/src/views/quote_view.js index 57ddefd..c85817a 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -16,9 +16,13 @@ const QuoteView = Backbone.View.extend({ 'click button.btn-sell': 'sellQuote', }, buyQuote: function(event) { + this.model.set('buy', true); + this.trigger('quoteAction', this); this.model.buy(); }, sellQuote: function(event) { + this.model.set('buy', false); + this.trigger('quoteAction', this); this.model.sell(); } }); From cc4a9ac5987ee22f0a91f3b0c63126f22ca23cb4 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Wed, 13 Dec 2017 11:05:01 -0800 Subject: [PATCH 04/13] Added order, order list and matching views --- src/app.js | 22 +++++++++++++++++++++- src/collections/order_list.js | 8 ++++++++ src/models/order.js | 9 +++++++++ src/views/order_list_view.js | 10 ++++++++++ src/views/order_view.js | 8 ++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/collections/order_list.js create mode 100644 src/models/order.js create mode 100644 src/views/order_list_view.js create mode 100644 src/views/order_view.js diff --git a/src/app.js b/src/app.js index a8c82ae..37beca6 100644 --- a/src/app.js +++ b/src/app.js @@ -3,13 +3,22 @@ import 'css/app.css'; import $ from 'jquery'; import _ from 'underscore'; - +import Backbone from 'backbone'; import Simulator from 'models/simulator'; + +// Models & Collections import Quote from 'models/quote'; import QuoteList from 'collections/quote_list'; +import Order from 'models/order'; +import OrderList from 'collections/order_list'; +// Views import QuoteView from 'views/quote_view'; import QuoteListView from 'views/quote_list_view'; +import OrderView from 'views/order_view'; +import OrderListView from 'views/order_list_view'; + +// let quotes; const quoteData = [ { @@ -30,6 +39,16 @@ const quoteData = [ }, ]; +// quotes = new QuoteList(quoteData); +// +// const formSelect = function formSelect () { +// const $form_select = $('#order-form select[name="symbol"]'); +// quotes.each((quote) => { +// const symbol = quote.get('symbol'); +// $form_select.append(``); +// }); +// }; + $(document).ready(function() { const quotes = new QuoteList(quoteData); const simulator = new Simulator({ @@ -43,6 +62,7 @@ $(document).ready(function() { el: 'main', }); + // formSelect(); quoteListView.render(); simulator.start(); }); 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..5f25e7c --- /dev/null +++ b/src/models/order.js @@ -0,0 +1,9 @@ +import Backbone from 'backbone'; + +const Order = Backbone.Model.extend({ + defaults: { + symbol: 'UNDEF', + }, +}); + +export default Order; diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js new file mode 100644 index 0000000..5387d45 --- /dev/null +++ b/src/views/order_list_view.js @@ -0,0 +1,10 @@ +import Backbone from 'backbone'; +import _ from 'underscore'; +import OrderView from './order_view'; +import Order from '../models/order'; + +const OrderListView = Backbone.View.extend({ + +}); + +export default OrderListView; diff --git a/src/views/order_view.js b/src/views/order_view.js new file mode 100644 index 0000000..06f71fd --- /dev/null +++ b/src/views/order_view.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; +import Order from '../models/order'; + +const OrderView = Backbone.View.extend({ + +}); + +export default OrderView; From f57c4e6882a8ed542b0ad31ec509ff441145e5ed Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Fri, 15 Dec 2017 10:53:33 -0800 Subject: [PATCH 05/13] Refactored formSelect --- src/app.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/app.js b/src/app.js index 37beca6..a68abee 100644 --- a/src/app.js +++ b/src/app.js @@ -18,8 +18,6 @@ import QuoteListView from 'views/quote_list_view'; import OrderView from 'views/order_view'; import OrderListView from 'views/order_list_view'; -// let quotes; - const quoteData = [ { symbol: 'HUMOR', @@ -39,18 +37,9 @@ const quoteData = [ }, ]; -// quotes = new QuoteList(quoteData); -// -// const formSelect = function formSelect () { -// const $form_select = $('#order-form select[name="symbol"]'); -// quotes.each((quote) => { -// const symbol = quote.get('symbol'); -// $form_select.append(``); -// }); -// }; - $(document).ready(function() { const quotes = new QuoteList(quoteData); + const simulator = new Simulator({ quotes: quotes, }); @@ -62,7 +51,14 @@ $(document).ready(function() { el: 'main', }); - // formSelect(); + const formSelect = function formSelect () { + quotes.each((quote) => { + const symbol = quote.get('symbol'); + $('select[name="symbol"]').append(``); + }); + }; + + formSelect(); quoteListView.render(); simulator.start(); }); From 995801cd5ffbe37e33daafc8b34db173b402a72d Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Fri, 15 Dec 2017 20:07:14 -0800 Subject: [PATCH 06/13] A new order template object is made, form information currently undefined --- src/app.js | 20 +++++++++++--- src/collections/order_list.js | 2 +- src/views/order_list_view.js | 50 +++++++++++++++++++++++++++++++++++ src/views/order_view.js | 18 ++++++++++++- src/views/quote_list_view.js | 4 +-- src/views/quote_view.js | 11 +++++++- 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/src/app.js b/src/app.js index a68abee..9ca898a 100644 --- a/src/app.js +++ b/src/app.js @@ -18,6 +18,9 @@ import QuoteListView from 'views/quote_list_view'; import OrderView from 'views/order_view'; import OrderListView from 'views/order_list_view'; +let bus = {}; +bus = _.extend(bus, Backbone.Events); + const quoteData = [ { symbol: 'HUMOR', @@ -43,13 +46,16 @@ $(document).ready(function() { const simulator = new Simulator({ quotes: quotes, }); + simulator.start(); const quoteListView = new QuoteListView({ model: quotes, template: _.template($('#quote-template').html()), tradeTemplate: _.template($('#trade-template').html()), el: 'main', + bus: bus }); + quoteListView.render(); const formSelect = function formSelect () { quotes.each((quote) => { @@ -57,8 +63,16 @@ $(document).ready(function() { $('select[name="symbol"]').append(``); }); }; - formSelect(); - quoteListView.render(); - simulator.start(); + + const orders = new OrderList(); + + const orderListView = new OrderListView({ + model: orders, + symbols: quotes, + template: _.template($('#order-template').html()), + el: '#order-workspace', + bus: bus + }); + orderListView.render(); }); diff --git a/src/collections/order_list.js b/src/collections/order_list.js index 8d7cabd..6b77957 100644 --- a/src/collections/order_list.js +++ b/src/collections/order_list.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import Order from 'models/order'; +import Order from '../models/order'; const OrderList = Backbone.Collection.extend({ model: Order, diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index 5387d45..bfede6d 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -1,10 +1,60 @@ import Backbone from 'backbone'; import _ from 'underscore'; +import OrderList from '../collections/order_list'; import OrderView from './order_view'; import Order from '../models/order'; const OrderListView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.bus = params.bus; + this.quotes = params.quotes; + this.listenTo(this.model, 'update', this.render); + }, + render() { + this.$('#orders').empty(); + this.model.each((order) => { + const orderView = new OrderView({ + model: order, + bus: this.bus, + template: this.template, + tagName: 'li', + className: 'order', + }); + this.$('#orders').append(orderView.render().$el); + }); + return this; + }, + events: { + 'click .btn-buy': 'buyOrder', + 'click .btn-sell': 'sellOrder', + }, + createOrder(buy) { + const orderData = { + quotes: this.quotes, + bus: this.bus, + symbol: this.$('#symbol').val(), + targetPrice: parseFloat(this.$('#target-price').val()), + buy: buy.buy, + }; + return new Order(orderData); + }, + buyOrder: function(e) { + e.preventDefault(); + this.validate(this.createOrder({buy: true})); + }, + sellOrder: function(e) { + e.preventDefault(); + this.validate(this.createOrder({buy: false})); + }, + validate(order) { + this.model.add(order); + this.$el.find('form').trigger('reset'); + }, + addOrder(order) { + this.model.add(order); + }, }); export default OrderListView; diff --git a/src/views/order_view.js b/src/views/order_view.js index 06f71fd..c6639c2 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -2,7 +2,23 @@ import Backbone from 'backbone'; import Order from '../models/order'; const OrderView = Backbone.View.extend({ - + initialize(params) { + this.template = params.template; + this.bus = params.bus; + this.listenTo(this.model, 'change', this.render); + }, + render() { + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate); + return this; + }, + events: { + 'click .btn-cancel': 'removeOrder', + }, + removeOrder() { + this.model.destroy(); + this.remove(); + }, }); export default OrderView; diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js index 42c92be..8d74361 100644 --- a/src/views/quote_list_view.js +++ b/src/views/quote_list_view.js @@ -23,8 +23,8 @@ const QuoteListView = Backbone.View.extend({ return this; }, trade: function(quoteView) { - const compiledTradeTemplate = this.tradeTemplate(quoteView.model.toJSON()); - this.$('#trades').prepend(compiledTradeTemplate); + const tradeTemplate = this.tradeTemplate(quoteView.model.toJSON()); + this.$('#trades').prepend(tradeTemplate); }, }); diff --git a/src/views/quote_view.js b/src/views/quote_view.js index c85817a..94fcc0a 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -4,6 +4,7 @@ import Quote from '../models/quote'; const QuoteView = Backbone.View.extend({ initialize(params) { this.template = params.template; + this.bus = params.bus; this.listenTo(this.model, 'change', this.render); }, render() { @@ -24,7 +25,15 @@ const QuoteView = Backbone.View.extend({ this.model.set('buy', false); this.trigger('quoteAction', this); this.model.sell(); - } + }, + checkOrders() { + const symbol = this.model.get('symbol'); + this.bus.trigger(`check${symbol}`, this.model); + }, + // addTrade() { + // const tradeTemplate = this.tradeTemplate(this.model.toJSON()); + // $('#trades').prepend(tradeTemplate); + // }, }); export default QuoteView; From 127ccc0a9c9204cdc5a662a727a81ae2e194b55d Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Fri, 15 Dec 2017 20:09:32 -0800 Subject: [PATCH 07/13] Changes removeOrder to cancelOrder for clarity --- src/views/order_view.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/order_view.js b/src/views/order_view.js index c6639c2..7ec6ef3 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -13,9 +13,9 @@ const OrderView = Backbone.View.extend({ return this; }, events: { - 'click .btn-cancel': 'removeOrder', + 'click .btn-cancel': 'cancelOrder', }, - removeOrder() { + cancelOrder() { this.model.destroy(); this.remove(); }, From e205b699a24f34ee5569c707079db2e01ee936fd Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Fri, 15 Dec 2017 20:41:55 -0800 Subject: [PATCH 08/13] New order form correctly passes inputs to a new order --- src/views/order_list_view.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index bfede6d..4384c4d 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -17,10 +17,10 @@ const OrderListView = Backbone.View.extend({ this.model.each((order) => { const orderView = new OrderView({ model: order, - bus: this.bus, template: this.template, tagName: 'li', className: 'order', + bus: this.bus, }); this.$('#orders').append(orderView.render().$el); }); @@ -30,31 +30,32 @@ const OrderListView = Backbone.View.extend({ 'click .btn-buy': 'buyOrder', 'click .btn-sell': 'sellOrder', }, - createOrder(buy) { + createOrder(value) { const orderData = { - quotes: this.quotes, + // quotes: this.quotes, bus: this.bus, - symbol: this.$('#symbol').val(), - targetPrice: parseFloat(this.$('#target-price').val()), - buy: buy.buy, + // symbol: this.$('#symbol').val(), + // targetPrice: parseFloat(this.$('#target-price').val()), + buy: value.buy, }; + orderData['symbol'] = this.$(`[name=symbol]`).val(); + orderData['targetPrice'] = parseFloat(this.$(`[name=price-target]`).val()); return new Order(orderData); }, - buyOrder: function(e) { - e.preventDefault(); - this.validate(this.createOrder({buy: true})); + buyOrder: function(event) { + event.preventDefault(); + const order = this.createOrder({buy: true}); + this.validate(order); }, - sellOrder: function(e) { - e.preventDefault(); - this.validate(this.createOrder({buy: false})); + sellOrder: function(event) { + event.preventDefault(); + const order = this.createOrder({buy: false}); + this.validate(order); }, validate(order) { this.model.add(order); this.$el.find('form').trigger('reset'); }, - addOrder(order) { - this.model.add(order); - }, }); export default OrderListView; From f6c81e4bda847ed9165ff5e55b2d9caaa53a57c8 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Sun, 17 Dec 2017 14:35:32 -0800 Subject: [PATCH 09/13] Form recieves all information, bus added where necessary --- src/app.js | 30 +++++++++++++++--------------- src/models/order.js | 11 ++++++++--- src/views/order_list_view.js | 14 ++++++-------- src/views/order_view.js | 2 +- src/views/quote_list_view.js | 2 ++ src/views/quote_view.js | 10 +++------- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/app.js b/src/app.js index 9ca898a..a963cd0 100644 --- a/src/app.js +++ b/src/app.js @@ -18,9 +18,6 @@ import QuoteListView from 'views/quote_list_view'; import OrderView from 'views/order_view'; import OrderListView from 'views/order_list_view'; -let bus = {}; -bus = _.extend(bus, Backbone.Events); - const quoteData = [ { symbol: 'HUMOR', @@ -40,22 +37,24 @@ const quoteData = [ }, ]; -$(document).ready(function() { - const quotes = new QuoteList(quoteData); +const quotes = new QuoteList(quoteData); +const orders = new OrderList(); +let bus = {}; +bus = _.extend(bus, Backbone.Events); + +$(document).ready(function() { const simulator = new Simulator({ quotes: quotes, }); - simulator.start(); const quoteListView = new QuoteListView({ model: quotes, template: _.template($('#quote-template').html()), tradeTemplate: _.template($('#trade-template').html()), - el: 'main', - bus: bus + bus: bus, + el: 'main' }); - quoteListView.render(); const formSelect = function formSelect () { quotes.each((quote) => { @@ -63,16 +62,17 @@ $(document).ready(function() { $('select[name="symbol"]').append(``); }); }; - formSelect(); - - const orders = new OrderList(); const orderListView = new OrderListView({ model: orders, - symbols: quotes, + quotes: quotes, template: _.template($('#order-template').html()), - el: '#order-workspace', - bus: bus + bus: bus, + el: '#order-workspace' }); + + simulator.start(); + quoteListView.render(); + formSelect(); orderListView.render(); }); diff --git a/src/models/order.js b/src/models/order.js index 5f25e7c..44461eb 100644 --- a/src/models/order.js +++ b/src/models/order.js @@ -1,9 +1,14 @@ import Backbone from 'backbone'; const Order = Backbone.Model.extend({ - defaults: { - symbol: 'UNDEF', - }, + validate(attributes) { + const errors = {}; + + if(!attributes.price) { + errors['price'] = ['Price is required']; + } + + } }); export default Order; diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index 4384c4d..31116a4 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -1,6 +1,6 @@ import Backbone from 'backbone'; import _ from 'underscore'; -import OrderList from '../collections/order_list'; +// import OrderList from '../collections/order_list'; import OrderView from './order_view'; import Order from '../models/order'; @@ -18,9 +18,9 @@ const OrderListView = Backbone.View.extend({ const orderView = new OrderView({ model: order, template: this.template, + bus: this.bus, tagName: 'li', className: 'order', - bus: this.bus, }); this.$('#orders').append(orderView.render().$el); }); @@ -32,14 +32,12 @@ const OrderListView = Backbone.View.extend({ }, createOrder(value) { const orderData = { - // quotes: this.quotes, - bus: this.bus, - // symbol: this.$('#symbol').val(), - // targetPrice: parseFloat(this.$('#target-price').val()), buy: value.buy, + symbol: this.$('select[name=symbol]').val(), + quote: this.quotes.find({symbol: this.$('select[name=symbol]').val()}), + targetPrice: parseFloat(this.$('input[name=price-target]').val()), + bus: this.bus, }; - orderData['symbol'] = this.$(`[name=symbol]`).val(); - orderData['targetPrice'] = parseFloat(this.$(`[name=price-target]`).val()); return new Order(orderData); }, buyOrder: function(event) { diff --git a/src/views/order_view.js b/src/views/order_view.js index 7ec6ef3..e9242e1 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import Order from '../models/order'; +// import Order from '../models/order'; const OrderView = Backbone.View.extend({ initialize(params) { diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js index 8d74361..82d8cc8 100644 --- a/src/views/quote_list_view.js +++ b/src/views/quote_list_view.js @@ -7,6 +7,7 @@ const QuoteListView = Backbone.View.extend({ initialize(params) { this.template = params.template; this.tradeTemplate = params.tradeTemplate; + this.bus = params.bus; this.listenTo(this.model, 'update', this.render); }, render() { @@ -14,6 +15,7 @@ const QuoteListView = Backbone.View.extend({ const quoteView = new QuoteView({ model: quote, template: this.template, + bus: this.bus, tagName: 'li', className: 'quote', }); diff --git a/src/views/quote_view.js b/src/views/quote_view.js index 94fcc0a..b9e63af 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -26,13 +26,9 @@ const QuoteView = Backbone.View.extend({ this.trigger('quoteAction', this); this.model.sell(); }, - checkOrders() { - const symbol = this.model.get('symbol'); - this.bus.trigger(`check${symbol}`, this.model); - }, - // addTrade() { - // const tradeTemplate = this.tradeTemplate(this.model.toJSON()); - // $('#trades').prepend(tradeTemplate); + // checkOrders() { + // const symbol = this.model.get('symbol'); + // this.bus.trigger(`check${symbol}`, this.model); // }, }); From 8042de8242ddb5b45a485940239fc5417049f33c Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Sun, 17 Dec 2017 15:01:00 -0800 Subject: [PATCH 10/13] If quote reaches order value, order cancels --- src/views/order_list_view.js | 2 +- src/views/order_view.js | 12 ++++++++++++ src/views/quote_list_view.js | 5 +++-- src/views/quote_view.js | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index 31116a4..71e3e7b 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import _ from 'underscore'; +// import _ from 'underscore'; // import OrderList from '../collections/order_list'; import OrderView from './order_view'; import Order from '../models/order'; diff --git a/src/views/order_view.js b/src/views/order_view.js index e9242e1..cf85f8c 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -6,6 +6,7 @@ const OrderView = Backbone.View.extend({ this.template = params.template; this.bus = params.bus; this.listenTo(this.model, 'change', this.render); + this.listenTo(this.model.get('quote'), 'change', this.tradeOrder); }, render() { const compiledTemplate = this.template(this.model.toJSON()); @@ -19,6 +20,17 @@ const OrderView = Backbone.View.extend({ this.model.destroy(); this.remove(); }, + tradeOrder() { + if (this.model.get('buy')) { + if (this.model.get('quote').get('price') <= this.model.get('targetPrice')) { + this.cancelOrder(); + } + } else { + if (this.model.get('quote').get('price') >= this.model.get('targetPrice')) { + this.cancelOrder(); + } + } + }, }); export default OrderView; diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js index 82d8cc8..91b3b95 100644 --- a/src/views/quote_list_view.js +++ b/src/views/quote_list_view.js @@ -1,7 +1,8 @@ import Backbone from 'backbone'; -import _ from 'underscore'; +// import _ from 'underscore'; +// import Quote from '../models/quote'; import QuoteView from './quote_view'; -import Quote from '../models/quote'; + const QuoteListView = Backbone.View.extend({ initialize(params) { diff --git a/src/views/quote_view.js b/src/views/quote_view.js index b9e63af..59e7fc1 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import Quote from '../models/quote'; +// import Quote from '../models/quote'; const QuoteView = Backbone.View.extend({ initialize(params) { From 565c9586ed93fd4941629f1d3adda95478413b02 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Sun, 17 Dec 2017 15:51:53 -0800 Subject: [PATCH 11/13] An order buys/sells when a quote hits the right number(but buys all quotes) --- src/views/order_view.js | 2 ++ src/views/quote_view.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/views/order_view.js b/src/views/order_view.js index cf85f8c..7033bf5 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -23,6 +23,8 @@ const OrderView = Backbone.View.extend({ tradeOrder() { if (this.model.get('buy')) { if (this.model.get('quote').get('price') <= this.model.get('targetPrice')) { + console.log(this); + this.bus.trigger('buyOrder', this); this.cancelOrder(); } } else { diff --git a/src/views/quote_view.js b/src/views/quote_view.js index 59e7fc1..3817294 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -6,6 +6,8 @@ const QuoteView = Backbone.View.extend({ this.template = params.template; this.bus = params.bus; this.listenTo(this.model, 'change', this.render); + this.listenTo(this.bus, 'buyOrder', this.buyQuote); + this.listenTo(this.bus, 'sellOrder', this.sellQuote); }, render() { const compiledTemplate = this.template(this.model.toJSON()); From 038e1f6dbdb53b8e422f84aedb0dbcca78e1ec15 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Sun, 17 Dec 2017 18:06:42 -0800 Subject: [PATCH 12/13] Validations added for orders --- src/models/order.js | 17 +++++++++++++++-- src/views/order_list_view.js | 18 ++++++++++++++++-- src/views/order_view.js | 2 +- src/views/quote_view.js | 4 ---- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/models/order.js b/src/models/order.js index 44461eb..96ed9e9 100644 --- a/src/models/order.js +++ b/src/models/order.js @@ -4,10 +4,23 @@ const Order = Backbone.Model.extend({ validate(attributes) { const errors = {}; - if(!attributes.price) { - errors['price'] = ['Price is required']; + if(!attributes.targetPrice || attributes.targetPrice <= 0) { + errors['price'] = ['Invalid target price']; } + if (this.get('buy') && attributes.targetPrice >= this.get('quote').get('price')) { + errors['price'] = ['Price higher than market price!']; + } + + if (!this.get('buy') && attributes.targetPrice <= this.get('quote').get('price')) { + errors['price'] = ['Price lower than market price!']; + } + + if ( Object.keys(errors).length > 0 ) { + return errors; + } else { + return false; + } } }); diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index 71e3e7b..f76a66d 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -31,6 +31,8 @@ const OrderListView = Backbone.View.extend({ 'click .btn-sell': 'sellOrder', }, createOrder(value) { + this.$('.form-errors').empty(); + const orderData = { buy: value.buy, symbol: this.$('select[name=symbol]').val(), @@ -51,8 +53,20 @@ const OrderListView = Backbone.View.extend({ this.validate(order); }, validate(order) { - this.model.add(order); - this.$el.find('form').trigger('reset'); + if (order.isValid()) { + this.model.add(order); + this.$el.find('form').trigger('reset'); + } else { + const errors = order.validationError; + const errorSection = this.$('.form-errors'); + + Object.keys(errors).forEach((field) => { + errors[field].forEach((error) => { + const html = `

${error}

`; + errorSection.append(html); + }); + }); + } }, }); diff --git a/src/views/order_view.js b/src/views/order_view.js index 7033bf5..5aece39 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -23,12 +23,12 @@ const OrderView = Backbone.View.extend({ tradeOrder() { if (this.model.get('buy')) { if (this.model.get('quote').get('price') <= this.model.get('targetPrice')) { - console.log(this); this.bus.trigger('buyOrder', this); this.cancelOrder(); } } else { if (this.model.get('quote').get('price') >= this.model.get('targetPrice')) { + this.bus.trigger('sellOrder', this); this.cancelOrder(); } } diff --git a/src/views/quote_view.js b/src/views/quote_view.js index 3817294..c9e2fa4 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -28,10 +28,6 @@ const QuoteView = Backbone.View.extend({ this.trigger('quoteAction', this); this.model.sell(); }, - // checkOrders() { - // const symbol = this.model.get('symbol'); - // this.bus.trigger(`check${symbol}`, this.model); - // }, }); export default QuoteView; From 7cc2483eb115b90153ec75fe973f8fd214ebea18 Mon Sep 17 00:00:00 2001 From: Laura Robertson Date: Sun, 17 Dec 2017 22:36:19 -0800 Subject: [PATCH 13/13] Order only buy/sell correct quote --- src/app.js | 13 +++++++------ src/views/order_list_view.js | 6 ++++-- src/views/order_view.js | 1 - src/views/quote_view.js | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/app.js b/src/app.js index a963cd0..25f337f 100644 --- a/src/app.js +++ b/src/app.js @@ -37,13 +37,13 @@ const quoteData = [ }, ]; -const quotes = new QuoteList(quoteData); -const orders = new OrderList(); +$(document).ready(function() { + const quotes = new QuoteList(quoteData); + const orders = new OrderList(); -let bus = {}; -bus = _.extend(bus, Backbone.Events); + let bus = {}; + bus = _.extend(bus, Backbone.Events); -$(document).ready(function() { const simulator = new Simulator({ quotes: quotes, }); @@ -71,8 +71,9 @@ $(document).ready(function() { el: '#order-workspace' }); - simulator.start(); + quoteListView.render(); formSelect(); orderListView.render(); + simulator.start(); }); diff --git a/src/views/order_list_view.js b/src/views/order_list_view.js index f76a66d..65dab22 100644 --- a/src/views/order_list_view.js +++ b/src/views/order_list_view.js @@ -1,6 +1,7 @@ import Backbone from 'backbone'; // import _ from 'underscore'; // import OrderList from '../collections/order_list'; +import $ from 'jquery'; import OrderView from './order_view'; import Order from '../models/order'; @@ -20,6 +21,7 @@ const OrderListView = Backbone.View.extend({ template: this.template, bus: this.bus, tagName: 'li', + quotes: this.quotes, className: 'order', }); this.$('#orders').append(orderView.render().$el); @@ -32,13 +34,13 @@ const OrderListView = Backbone.View.extend({ }, createOrder(value) { this.$('.form-errors').empty(); - + const orderData = { buy: value.buy, symbol: this.$('select[name=symbol]').val(), quote: this.quotes.find({symbol: this.$('select[name=symbol]').val()}), targetPrice: parseFloat(this.$('input[name=price-target]').val()), - bus: this.bus, + bus: this.bus }; return new Order(orderData); }, diff --git a/src/views/order_view.js b/src/views/order_view.js index 5aece39..e40654f 100644 --- a/src/views/order_view.js +++ b/src/views/order_view.js @@ -1,5 +1,4 @@ import Backbone from 'backbone'; -// import Order from '../models/order'; const OrderView = Backbone.View.extend({ initialize(params) { diff --git a/src/views/quote_view.js b/src/views/quote_view.js index c9e2fa4..633a59f 100644 --- a/src/views/quote_view.js +++ b/src/views/quote_view.js @@ -1,13 +1,12 @@ import Backbone from 'backbone'; -// import Quote from '../models/quote'; const QuoteView = Backbone.View.extend({ initialize(params) { this.template = params.template; this.bus = params.bus; this.listenTo(this.model, 'change', this.render); - this.listenTo(this.bus, 'buyOrder', this.buyQuote); - this.listenTo(this.bus, 'sellOrder', this.sellQuote); + this.listenTo(this.bus, 'buyOrder', this.buyOrder); + this.listenTo(this.bus, 'sellOrder', this.sellOrder); }, render() { const compiledTemplate = this.template(this.model.toJSON()); @@ -28,6 +27,16 @@ const QuoteView = Backbone.View.extend({ this.trigger('quoteAction', this); this.model.sell(); }, + buyOrder: function(orderQuote) { + if(orderQuote.model.get('symbol') === this.model.get('symbol')){ + this.buyQuote(); + } + }, + sellOrder: function(orderQuote) { + if(orderQuote.model.get('symbol') === this.model.get('symbol')){ + this.sellQuote(); + } + } }); export default QuoteView;