Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Roboto+Condensed|Rubik+Mono+One">
</head>
<body>
<main id="application" class="content">
Expand Down Expand Up @@ -44,7 +43,7 @@ <h2>Trade History</h2>

<div id="order-workspace" class="order-workspace row">

<div class="columns large-8 small-12">
<div id="orders-container" class="columns large-8 small-12">
<div class="orders-container columns large-10 large-offset-1">
<h2>Open Orders</h2>
<div class="orders-list-container">
Expand All @@ -57,13 +56,13 @@ <h2>Open Orders</h2>
<div class="columns large-4 small-12 trade-column">
<div class="order-entry-form columns small-10 small-offset-1">
<h3>Order Entry Form</h3>
<form>
<form id="order-form">
<label for="symbol">Symbol</label>
<select name="symbol">
<select id="dropdown" name="symbol">
<!-- Option entries should be added here using JavaScript -->
</select>
<label for="price-target">Price</label>
<input type="number" name="price-target" step="0.10" min="0.00" placeholder="100.00" />
<input type="number" name="price-target" step="0.10" min="0.00" value="88.5" placeholder="100.00" />
<label>Action</label>
<button class="btn-buy alert button">Buy</button>
<button class="btn-sell success button">Sell</button>
Expand All @@ -85,22 +84,22 @@ <h3>Order Entry Form</h3>
<script type="text/template" id="quote-template">
<!-- The provided styles assume that you will insert this template
within an element with the class "quote" applied -->
<!-- <li class="quote"> -->
<li class="quote">
<div class="row small-12 columns">
<h3 class="symbol"><%- symbol %></h3>
<h3 class="price">$<%- price.toFixed(2) %></h3>
<h3 class="price"><%- price.toFixed(2) %></h3>
<div class="quote-actions">
<button class="btn-buy alert button">Buy</button>
<button class="btn-sell success button">Sell</button>
</div>
</div>
<!-- </li> -->
</li>
</script>

<script type="text/template" id="trade-template">
<li class="trade">
<span>
You <%- buy ? 'bought' : 'sold' %> <%- symbol %> at $<%- price.toFixed(2) %>
You <%- buy ? 'bought' : 'sold' %> <%- symbol %> at <%- price.toFixed(2) %>
</span>
</li>
</script>
Expand All @@ -110,7 +109,7 @@ <h3 class="symbol"><%- symbol %></h3>
<div class="detail">
<span class="action"><%- buy ? 'buy' : 'sell' %></span>
at
<span class="price">$<%- targetPrice.toFixed(2) %></span>
<span class="price"><%- targetPrice %></span>
</div>
<button class="btn-cancel button secondary">Cancel</button>
</script>
Expand Down
48 changes: 48 additions & 0 deletions spec/models/order_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Quote from 'models/quote';
import Order from 'models/order';

describe('Order spec', () => {
let quote;
let order;
beforeEach(() => {
quote = new Quote({
symbol: 'CLOTH',
price: 100.00,
});
order = new Order({
symbol: 'CLOTH',
quote: quote,
buy: true,
targetPrice: 100,
})
});

describe('Create a new Order', () => {
it('creates a valid instance of an Order', () => {
order.set('targetPrice', 80.00);
order.set('buy', true);

expect(order.isValid()).toEqual(true);
})

it('invalid order if price is not a number', () => {
order.set('targetPrice', 'hello');

expect(order.isValid()).toEqual(false);
})

it('invalid buy order if price is higher than market', () => {
order.set('targetPrice', 180);
order.set('buy', true);

expect(order.isValid()).toEqual(false);
})

it('invalid sell order if price is lower than market', () => {
order.set('targetPrice', 8);
order.set('buy', false);

expect(order.isValid()).toEqual(false);
})
});
});
69 changes: 65 additions & 4 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@ 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 Simulator from './models/simulator';
import QuoteList from './collections/quote_list';
import Order from './models/order'
import OrderList from './collections/order_list'

import QuoteListView from './views/quote_list_view';
import TradeListView from './views/trade_list_view';
import OrderFormView from './views/order_form_view';
import OrderListView from './views/order_list_view';

const quoteData = [
{
symbol: 'HUMOR',
symbol: '유머',
price: 88.50,
},
{
symbol: 'CLOTH',
symbol: '피복',
price: 81.70,
},
{
Expand All @@ -25,11 +33,64 @@ const quoteData = [
},
];

quoteData.forEach(function(quote) {
$('#dropdown').append(`<option>${quote.symbol}</option>`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code should really be within the $(document).ready(...) callback function.

The reason for that is because we're using jQuery to find the select tag on the page with ID dropdown, and then manipulating it by appending option tags inside of it. Both of these things are only guaranteed to work properly if we wait until the entire page has been loaded -- which is what the $(document).ready(...) is for.

We can see the problem manifest if we change index.html to have the script tag for app.bundle.js inside of the head tag after the meta tags, instead of at the bottom of the body tag. By moving the JS code to the top of our HTML file, the browser will load it and run the JS code in app.js first, before, loading the actual HTML content of the page.

In that case the drop down selection does not have any options added to it, because when this line of code runs jQuery cannot find the select tag with ID dropdown (because it hasn't been loaded yet from the HTML file).

})



$(document).ready(function() {


let bus = {};
bus = _.extend(bus, Backbone.Events);

let template = _.template($('#quote-template').html());
let tradeTemplate = _.template($('#trade-template').html());
let orderTemplate = _.template($('#order-template').html());

const quotes = new QuoteList(quoteData);
const simulator = new Simulator({
quotes: quotes,
});
const orders = new OrderList();

const quoteListView = new QuoteListView({
el: '#quotes-container',
model: quotes,
template: template,
bus: bus,
});

const tradeListView = new TradeListView({
el: '#trades-container',
template: tradeTemplate,
bus: bus,
})
const orderFormView = new OrderFormView({
// quoteData: quoteData,
el: '.order-entry-form',
bus: bus,
orderList: orders,
quoteList: quotes,
});

const order = new Order({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like this instance of Order is being used anywhere, so we could probably remove it?

bus: bus,
})

const orderListView = new OrderListView({
el: '.orders-list-container',
model: orders,
template: orderTemplate,
bus: bus,
});


orderListView.render();
quoteListView.render();

simulator.start();


});
8 changes: 8 additions & 0 deletions src/collections/order_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Backbone from 'backbone';
import Order from '../models/order'

const OrderList = Backbone.Collection.extend({
model: Order,
})

export default OrderList
28 changes: 28 additions & 0 deletions src/models/order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Backbone from 'backbone';

const Order = Backbone.Model.extend({
defaults: {
symbol: 'UNDEF',
targetPrice: 9.00,
buy: true,
},
validate: function(attributes) {
let error = '';

if (attributes.buy && (attributes.targetPrice >= attributes.quote.get('price'))) {
error = 'Price higher than market price!';
} else if (!attributes.buy && (attributes.targetPrice <= attributes.quote.get('price'))) {
error = 'Price lower than market price!';
} else if (isNaN(attributes.targetPrice)) {
error = 'Invalid Target Price';
}

if (error != '') {
return error
} else {
return false
}
},
})

export default Order
9 changes: 6 additions & 3 deletions src/models/quote.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ const Quote = Backbone.Model.extend({
},

buy() {
// Implement this function to increase the price by $1.00
},
console.log('click into buy()');
this.set('price', this.get('price') + 1)
console.log(this.get('price'));
},

sell() {
// Implement this function to decrease the price by $1.00
console.log('click into sell()');
this.set('price', this.get('price') - 1)
},
});

Expand Down
2 changes: 1 addition & 1 deletion src/models/simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const Simulator = Backbone.Model.extend({

this.quotes.forEach((quote) => {
// Calculate a random price movement
const maxChange = 1.00;
const maxChange = 0.10;
const minChange = 0.00;
let change = _.random(minChange * 10, maxChange * 10) / 10;

Expand Down
61 changes: 61 additions & 0 deletions src/views/order_form_view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Backbone from 'backbone';

import Quote from '../models/quote';
import Order from '../models/order';
import OrderList from '../collections/order_list';
import QuoteList from '../collections/quote_list';


const OrderFormView = Backbone.View.extend({
initialize(params){
this.bus = params.bus;
this.quoteList = params.quoteList
},
// quoteData.each((quote) => {
// $('#dropdown').append(`<option>${quote.symbol}</option>`);
// }),

readOrderFormData(type) {
const orderData = {};

const $inputSymbolValue = this.$(`select[name="symbol"]`).val();
const $inputPriceTargert = this.$(`input[name="price-target"]`)


const priceValue = parseFloat($inputPriceTargert.val()).toFixed(2);
// console.log(`priceValue = ${priceValue}`);

// Don't take empty strings, so that Backbone can
// fill in default values
orderData['symbol'] = $inputSymbolValue;
if (priceValue != '') {
orderData['targetPrice'] = priceValue;
}
orderData['buy'] = type
console.log(this.quoteList);
console.log(orderData['symbol'])
orderData['quote'] = this.quoteList.find({symbol: orderData['symbol']});
$inputPriceTargert.val('');
return orderData;
},
events: {
'click button.btn-buy': 'buyOrder',
'click button.btn-sell': 'orderSell',
},
buyOrder(event) {
event.preventDefault();
console.log('test click order');
let orderObject = this.readOrderFormData(true)

this.bus.trigger('newOrder', orderObject)
},

orderSell(event) {
event.preventDefault();
console.log('test click orderSell');
let orderObject = this.readOrderFormData(false);
this.bus.trigger('newOrder', orderObject)
}

});
export default OrderFormView;
Loading