Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
125 changes: 122 additions & 3 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,136 @@
<meta charset="utf-8">
<title>My JavaScript App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="app.bundle.js" type="text/javascript"></script>
</head>
<body>
<header>

<h1>Wanderlust Expeditions:</h1>
<h2>Choose Your Own Adventure</h2>
<nav>
<button class="button" id="load-trips">See All of Our Trips</button>
<button class="button" id="create-trip">Create Your Own Trip</button>
</nav>
</header>
<main>
<main class="clearfix">

<section id="status-messages">
<button class="clear float-right">Close</button>
<ul>
</ul>
</section>


<section class="row-column">
<div id="individual-trip" class="small-12 medium-6 large 3">
<!-- Where the template stuff goes! -->
<p id="trip-details">
</p>
</div>
</section>

<section id="reserve-trip">
<aside class="columns large-4 small-12">
<h2>Take a Trip</h2>
<form id="reservation-form" data-id="12">
<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="Book Trip" class="button"></input>
</form>
</aside>
</section>


<section id="add-trip">
<aside class="columns large-4 small-12">
<h2>Create your own Adventure!</h2>
<form id="add-trip-form" method="post">
<label for="name">Name of Trip</label>
<input type="text" id="name" name="name"></input>

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

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

<label for="weeks">Number of Weeks</label>
<input type="integer" id="weeks" name="weeks"></input>

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

<input type="submit" value="Add a Trip" class="button"></input>
</form>
</aside>
</section>

<section class="row">
<section id="all-trips" class="small-12 medium-6 large-6">
<table>
<thead>
<th class="sort name">Name</th>
<th class="sort continent">Continent</th>
<th class="sort category">Category</th>
<th class="sort weeks">Weeks</th>
<th class="sort price">Price</th>
</thead>

<!-- Where the template stuff goes! -->
<tbody id="trips-list">
</tbody>
</table>
</section>
</section>



</main>
<footer>


</footer>
<script src="app.bundle.js" type="text/javascript"></script>

<script id="all-trips-template" type="text/template">

<tr class="trips" >
<td id="trip-selector" data-id="<%- id %>" >
<%- name %>
</td>
<td>
<%- continent %>
</td>
<td>
<%- category %>
</td>
<td>
<%- weeks %>
</td>
<td>
<%- cost %>
</td>
</tr>
</script>

<script id="show-details-template" type="text/template" >
<h2> <%- name %> </h2>
<p id="weeks">
<%- weeks %> in <%- continent %> for $<%- cost %>
</p>
<p>
<%- about %>
</p>
<h4 class="reservation button" data-id="<%- id %>"> Make a Reservation!</h4>
</script>

<script id="status-message-template" type="text/template" >
<li class="<%- status %>">
<%- message %>
</li>
</script>


</body>
</html>
191 changes: 188 additions & 3 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,193 @@ import _ from 'underscore';
import './css/foundation.css';
import './css/style.css';

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


const TRIP_FIELDS = ['name', 'continent', 'category', 'weeks', 'price'];
const RES_FIELDS = ['name', 'email'];

let allTripsTemplate;
let showDetailsTemplate;
let statusMessageTemplate;

// Render Methods

const renderAll = function renderAll(tripList) {
const tripListElement = $('#trips-list');
tripListElement.empty();
$('th.sort').removeClass('current-sort-field');
$(`th.sort.${ tripList.comparator }` ).addClass('current-sort-field');

tripList.on('update', renderAll);

Choose a reason for hiding this comment

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

These should be in $(document(.ready this will eventually cause lots of rendering when a new model is added or if it's been sorted multiple times.

Only add the listener once, not every time it renders.

tripList.on('sort', renderAll);

tripList.forEach((trip) => {
let tripsHTML = allTripsTemplate(trip.attributes);
if (trip.id < 34) {
tripListElement.append( $(tripsHTML) );
}
}); // for each
}; // renderAll function

// error messages

const reportStatus = function(status, message) {
console.log(`Reporting ${ status } message: ${ message } `);
const generatedHTML = statusMessageTemplate({
status: status,
message: message,
});

$('#status-messsages ul').append(generatedHTML);
$('status-messages').show()
}

const tripsApiErrorHandler = function(model, response) {
model.destroy();

if (response.responseJSON['errors']) {
const errors = response.responseJSON['errors'];
for (const field in errors) {
for (const problem of errors[field]) {
reportStatus('error', ` ${ field }: ${ problem }`);
} // for problem
} // error

} else {
reportStatus('error', 'Could not save trip');
console.log('Error response from server:')
console.log(response);
} // end else
} //handler

const renderDetails = function renderDetails(id) {
const tripDetails = $('#trip-details');
tripDetails.empty();
const oneTrip = new Trip({id: id});
oneTrip.fetch({}).done(() => {
tripDetails.append(showDetailsTemplate(oneTrip.attributes));
});
}; // renderDetails

const makeReservation = function makeReservation(bookTripID, reservationFormData) {
let reserveURL = 'https://trektravel.herokuapp.com/trips/' + bookTripID + '/reservations';
$.post(reserveURL, reservationFormData);
}

const readAddTripForm = function readAddTripForm() {
const addTripData = {};
TRIP_FIELDS.forEach( (field) => {
const inputElement = $(`add-trip-form input[name="${ field }"]`);
addTripData[field] = inputElement.val();
});
return addTripData;
}; // read form function


const clearForm = function clearForm() {
$('#add-trip-form input[name]').val('');
};


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


allTripsTemplate = _.template($('#all-trips-template').html() );
showDetailsTemplate = _.template($('#show-details-template').html() );
statusMessageTemplate = _.template($('#status-message-template').html() );

$('#individual-trip').hide();
$('#all-trips').hide();
$('#reserve-trip').hide();
$('#add-trip').hide();
$('#status-messages').hide();

const tripList = new TripList();

tripList.on('sort', renderAll);

//Events

// show add trip form

$('#create-trip').on('click', function() {
console.log("You clicked to see the add trip form");
$('#add-trip').show();
});

// add a new trip

$('#add-trip-form').on('submit', (event) => {
event.preventDefault();

$('#individual-trip').hide();
const newTrip = new Trip(readAddTripForm);
tripList.add(newTrip);

Choose a reason for hiding this comment

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

no checking for validations?

Also the trip doesn't have an ID yet (gets the from the API), so you should wait until the save is successful and then execute tripList.fetch() to pull down the updated Trip from the API (with an ID).

newTrip.save({}, {
success: clearForm,
error: tripsApiErrorHandler
});
$('#status-messages').show
});

// make reservations

$('#reservation-form').on('submit', (event) => {
event.preventDefault();
const bookTripID = $(event.target).attr('data-id');
let reservationFormData =
$('#reservation-form').serialize();
makeReservation(reservationFormData);

Choose a reason for hiding this comment

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

Here you're calling makeReservation with the wrong paramater. The 1st parameter should be the tripID

}) //end book trip

// show trip reservation form
$('#trip-details').on('click', 'h4', function() {
console.log("You clicked to see the res form");
console.log(this);
const bookTripID = $(this).attr('data-id');
$('#reservation-form').attr("data-id", bookTripID);
$('#reserve-trip').show();
})


// show trip details
$('#trips-list').on('click', '.trips', (event) => {
const tripID = $(event.target).attr('data-id');
$('#individual-trip').show();
renderDetails(tripID);
window.scrollTo(0, 0);
});

// show all the trips

const allTrips = $('#load-trips');
allTrips.on('click', () => {

tripList.fetch();
$('#all-trips').show();
})

// Clear error messages
$('#status-messages button.clear').on('click', (event) => {
$('#status-messages ul').html('');
$('#status-messages').hide
})

// Sort Fields
TRIP_FIELDS.forEach((field) => {
const headerElement = $(`.sort.${ field }`);

headerElement.on('click', () => {
console.log(`Sorting by ${ field }`);
tripList.comparator = field;
tripList.sort();

}); // click event handler
}); // fields for each

}); // end document ready
9 changes: 9 additions & 0 deletions src/app/collections/trip_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Backbone from 'backbone';
import Trip from '../models/trip';

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

export default TripList;
15 changes: 15 additions & 0 deletions src/app/models/reservation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Defining the Model

// import Backbone from 'backbone';
//
// const Reservation = Backbone.Model.extend({

Choose a reason for hiding this comment

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

Looks like you were on a good track!

//
// url: function() {
// console.log(this);
// return 'https://ada-backtrek-api.herokuapp.com/trips/' + this.get("id") + '/reservations';
// }
// }); //end const Rervation
//
// export default Reservation;

// https://ada-backtrek-api.herokuapp.com/trips/1/reservations
Loading