Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
8af0d27
add underscore template
tanham Nov 28, 2017
dcaa748
add trip model
tanham Nov 28, 2017
83bf6d5
add trips api to collection
tanham Nov 28, 2017
9fd5d5b
set up app.js
tanham Nov 28, 2017
a162f82
add table =
tanham Nov 28, 2017
7bcc69e
add functionality to display trips
tanham Nov 29, 2017
a622920
add on click event
tanham Nov 29, 2017
51132eb
add template for indivdual trip view
tanham Dec 1, 2017
c5506bb
add urlRoot and toString override
tanham Dec 1, 2017
0c1e94b
update selector names
tanham Dec 1, 2017
3f828b4
whitespace
tanham Dec 1, 2017
8ad54c6
add renderTrip function
tanham Dec 1, 2017
ff5e9c5
fix typo
tanham Dec 1, 2017
f1de288
update toString override
tanham Dec 1, 2017
5071412
add trip event handler to renderTrips function
tanham Dec 1, 2017
3ae45d6
add about attribute to undersroce template
tanham Dec 1, 2017
3e12509
update urlRoot
tanham Dec 2, 2017
9fbade4
fetch trip details from within trips loop
tanham Dec 2, 2017
6564173
add form
tanham Dec 2, 2017
a058ee6
update form
tanham Dec 2, 2017
67c2362
add functions to read and save form data
tanham Dec 2, 2017
d7fe793
remove comments
tanham Dec 2, 2017
e2a350f
add functionality to remove trip from list if it does not save
tanham Dec 2, 2017
36a69f7
add reserve link trip-template
tanham Dec 2, 2017
f6a222e
add reserve form template
tanham Dec 2, 2017
a7aded4
compile underscore template
tanham Dec 2, 2017
bce8b3b
fix typo
tanham Dec 2, 2017
e9e9abc
add functionality to sort by trip fields
tanham Dec 4, 2017
4728d1d
add click handler to renderTrip function
tanham Dec 4, 2017
bd75324
add reservation model
tanham Dec 4, 2017
e73178a
add error handling
tanham Dec 4, 2017
f8085fc
add toggle
tanham Dec 4, 2017
0222761
remove unneeded class
tanham Dec 4, 2017
bd4186b
add comment
tanham Dec 4, 2017
d937594
update error handling
tanham Dec 4, 2017
27c6bd8
update styling
tanham Dec 4, 2017
d15006b
add comment
tanham Dec 4, 2017
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
104 changes: 104 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,118 @@
</head>
<body>
<header>
<h1>backTrek</h1>
<h3>~going the distance~</h3>

<div>
<button type="button" name="button" class="button" id="trips">see trips</button>
<button type="button" name="button" class="button" id="add-trip">add trip</button>
</div>
</header>

<section id="status-messages">
<ul></ul>
</section>

<main>

<aside class="float-center" id="trip"></aside>
<aside id="reserve-form"></aside>

<section class="add-trip-form columns large-4 small-12">
<h2>Add a Trip</h2>
<form id="add-trip-form">
<label for="name">Name</label>
<input type="text" name="name"></input>

<label for="continent">Continent</label>
<input type="text" name="continent"></input>

<label for="category">Category</label>
<input type="text" name="category"></input>

<label for="weeks">Weeks</label>
<input type="number" name="weeks"></input>

<label for="cost">Cost</label>
<input type="text" name="cost"></input>

<label for="about">About</label>
<input type="text" name="about"></input>

<input type="submit" value="Trip it!" class="button"></input>
</form>
</section>

<section>
<table class="columns large-4 small-12">
<thead>
<th class="name sort">name</th>
<th class="continent sort">continent</th>
<th class="category sort">category</th>
<th class="weeks sort">weeks</th>
<th class="cost sort">cost</th>
</thead>
<tbody id="trip-list">
</tbody>
</table>
</section>

</main>

<footer>

</footer>


<script type="text/template" id="trip-template">
<div id="ind-trip">
<h4><%- name %></h4>
<p><%- continent %></p>
<p><%- category %></p>
<p><%- weeks %></p>
<p><%- cost %></p>
<p><%- about %></p>

<button type="button" name="button" class="button" id="reserve">reserve trip</button>

</div>
</script>

<script type="text/template" id="reserve-template">
<div id="reserve-trip">
<form id="reserve-trip-form">
<label for="name">Name</label>
<input type="text" name="name"></input>

<label for="email">Email</label>
<input type="text" name="email"></input>

<input type="submit" value="Reserve!" class="button"></input>
</form>
</div>
</script>

<script type="text/template" id="list-template">
<tr class="trip">
<td id="trip-name">
<%- name %>
</td>
<td>
<%- continent %>
</td>
<td>
<%- category %>
</td>
<td>
<%- weeks %>
</td>
<td>
<%- cost %>
</td>
</tr>
</script>

<script src="app.bundle.js" type="text/javascript"></script>
</body>
</html>
165 changes: 161 additions & 4 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,165 @@ import _ from 'underscore';
import './css/foundation.css';
import './css/style.css';

console.log('it loaded!');
import TripList from 'app/collections/trip_list';
import Trip from 'app/models/trip';

$(document).ready( () => {
$('main').html('<h1>Hello World!</h1>');
});

const TRIP_FIELDS = ['name', 'continent', 'category', 'weeks', 'cost'];

// Clear status messages
const clearStatus = function clearStatus() {
$('#status-messages ul').html('');
$('#status-messages').hide();
};

// Add a new status message
const reportStatus = function reportStatus(status, message) {
console.log(`Reporting ${ status } status: ${ message }`);

// Should probably use an Underscore template here.
const statusHTML = `<li class="${ status }">${ message }</li>`;

// note the symetry with clearStatus()
$('#status-messages ul').append(statusHTML);
$('#status-messages').show();
};

const tripList = new TripList();
// initalize templates
let listTemplate;
let tripTemplate;
let reserveTemplate;

const renderTrips = function renderTrips(list) {
const tripTableElement = $('#trip-list');
tripTableElement.html('');
console.log(`tripList :${list}`);
list.forEach((trip) => {
const generatedHTML = $(listTemplate(trip.attributes));
// adding event handler here gives context as to which trip needs to be clicked
generatedHTML.on('click', (event) => {
const tripDetails = new Trip({id: trip.get('id')})
// grab backbone object and pass into function

tripDetails.fetch(
{
success: function(trip) {
console.log('worked');
renderTrip(trip);
},
error: function(message, b) {
console.log(message, b);
}
}); // end of fetch
})
tripTableElement.append(generatedHTML);
});
};

// BUG: renderReserve not firing on submit, console.logs not logging
const renderReserve = function renderReserve() {
const reserveForm = $('#reserve-form');
reserveForm.html('');
const generatedHTML = reserveTemplate();
console.log(generatedHTML);
reserveForm.append(generatedHTML);
}

const renderTrip = function renderTrip(trip) {
const tripElement = $('#trip');
// clears html in tripElement
tripElement.html('');
const generatedHTML = tripTemplate(trip.attributes);
tripElement.append(generatedHTML);

$('#reserve').on('click', (event) => {
renderReserve();
});
}

$('th.sort').removeClass('current-sort-field');
$(`th.sort.${tripList.comparator}`).addClass('current-sort-field');

const readFormData = function readFormData() {
const tripData = {};

TRIP_FIELDS.forEach((field) => {

const inputElement = $(`#add-trip-form input[name="${field}"]`);
const value = inputElement.val();

if (value != '') {
tripData[field] = value;
}
inputElement.val('');
});
console.log("reading trip data");
console.log(tripData);
return tripData;
};

const outputValidationFailures = function outputValidationFailures(errors) {
for (let field in errors) {
for (let problem of errors[field]) {
reportStatus('error', `${field}: ${problem}`);
}
}
};
const addTripHandler = function(event) {
event.preventDefault();

const trip = new Trip(readFormData());

if (!trip.isValid()) {
outputValidationFailures(trip.validationError);
return;
}
tripList.add(trip);

trip.save({}, {
success: (model, response) => {
console.log('successfully saved trip');
reportStatus('success', 'Successfully saved trip!');
},
error: (model, response) => {
console.log('failed to save trip');
console.log(response);
// removes from list if fails validations
tripList.remove(model);
outputValidationFailures(response.responseJSON["errors"]);
},
});
};

$(document).ready( () => {
// compile underscore templates
listTemplate = _.template($('#list-template').html());
tripTemplate = _.template($('#trip-template').html());
reserveTemplate = _.template($('#reserve-template').html());

tripList.on('sort', renderTrips);
tripList.fetch();

$('#add-trip-form').on('submit', addTripHandler);

$('#trips').on('click', () => {
$('#trip-list').toggle();
renderTrips(tripList);
});

$('#add-trip').on('click', () => {
console.log('clicked add trip');
$('.add-trip-form').toggle();
});

TRIP_FIELDS.forEach((field) => {
const headerElement = $(`th.sort.${field}`);
headerElement.on('click', (event) => {
console.log(`sorting table by ${field}`);
tripList.comparator = field;
tripList.sort();
});
});
$('#status-messages').on('click', clearStatus);
}); // end doc.ready
14 changes: 14 additions & 0 deletions src/app/collections/trip_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Backbone from 'backbone'
import Trip from '../models/trip';

const TripList = Backbone.Collection.extend({
model: Trip,
url: 'https://ada-backtrek-api.herokuapp.com/trips',
parse: function(response) {
return response;
},
comparator: 'name',
});


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

const Reservation = Backbone.Model.extend({
url: function () {
return `https://ada-backtrek-api.herokuapp.com/trips/${this.get('id')}/reservations`;
}
});

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

const Trip = Backbone.Model.extend({
urlRoot: 'https://ada-backtrek-api.herokuapp.com/trips',
// urlRoot() {
// return `https://ada-backtrek-api.herokuapp.com/trips/${ this.get('id') }`;
// },
toString() {
return `<Trip id:${this.get("id")},name:${this.get("name")},continent:${this.get("continent")}, weeks:${this.get("weeks")}, cost:${this.get("cost")}, about:${this.get("about")} >`;
},
validate(attributes) {
// Note the argument. We will read attribute values from
// here instead of calling this.get()

// Format of errors: same as Rails!
// {
// title: ['cannot be blank', 'already taken'],
// author: ['cannot be blank']
// }

const errors = {};
if (!attributes.name) {
errors.name = ['cannot be blank'];
}

if (!attributes.continent) {
errors.continent = ['cannot be blank'];
}

if (!attributes.category) {
errors.category = ['cannot be blank'];
}

if (!attributes.weeks) {
errors.weeks = ['cannot be blank'];
}

if (!attributes.cost) {
errors.cost = ['cannot be blank'];
}


if (Object.keys(errors).length < 1) {
return false;
}
return errors;
},

});

export default Trip;
11 changes: 11 additions & 0 deletions src/css/style.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@

/* Your styles go here! */

body {
/*background-image: url(https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?auto=format&fit=crop&w=1440&q=80&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D);*/

}
header {
color: white;
background-color: #ca412b;
height: 200px;
text-align: center;
}