diff --git a/dist/index.html b/dist/index.html index 559b18ecd..1f5e58cdb 100644 --- a/dist/index.html +++ b/dist/index.html @@ -6,10 +6,94 @@
- +
+
+

Find Movie

+
+ + + + + + +
+
+ +
+

Some Specific Moviez

+
+
    + +
+
+
+
+
+
+
+
    + +
+
+
+
+
+

Search Results

+
+
    + +
+
+
+ +
+ +
+
+
+ + + + diff --git a/spec/models/movie_spec.js b/spec/models/movie_spec.js new file mode 100644 index 000000000..a89d70a5a --- /dev/null +++ b/spec/models/movie_spec.js @@ -0,0 +1,35 @@ + +import Movie from 'models/movie'; + +describe('Movie spec', () => { + // let movie; + let validMovie; + beforeEach(() => { + validMovie = new Movie({ + title: 'valid title', + release_date: 'valid date', + }); + }); + + describe('Attribute Validations', () => { + it('is invalid without a title', () => { + expect(validMovie.isValid()).toEqual(true); + + validMovie.set('title', null); + + expect(validMovie.isValid()).toEqual(false); + + }); + + it('is invalid without a release_date', () => { + expect(validMovie.isValid()).toEqual(true); + + validMovie.set('release_date', null); + + expect(validMovie.isValid()).toEqual(false); + + }); + + }); + +}); diff --git a/spec/test_spec.js b/spec/test_spec.js index 9252883f2..eb4a547a5 100644 --- a/spec/test_spec.js +++ b/spec/test_spec.js @@ -1,13 +1,13 @@ - -describe('Sample spec', () => { - let a; - - it('and so is a spec', () => { - a = true; - - expect(a).toBe(true); - }); - xit('will not work', () => { - expect(false).toBe(true); - }); -}); +// +// describe('Sample spec', () => { +// let a; +// +// xit('and so is a spec', () => { +// a = true; +// +// expect(a).toBe(true); +// }); +// xit('will not work', () => { +// expect(false).toBe(true); +// }); +// }); diff --git a/src/app.js b/src/app.js index 30c00d594..c282790c1 100644 --- a/src/app.js +++ b/src/app.js @@ -1,14 +1,55 @@ +// Import jQuery & Underscore +import Backbone from 'backbone'; +import $ from 'jquery'; +import _ from 'underscore'; + import 'css/_settings.css'; import 'foundation-sites/dist/css/foundation.css'; import './css/styles.css'; -// Import jQuery & Underscore -import $ from 'jquery'; -import _ from 'underscore'; +//import models and collections +import MovieList from './collections/movie_list'; +import VendorList from './collections/vendor_list'; + +// import views +import MovieListView from './views/movie_list_view'; +import VendorListView from './views/vendor_list_view'; +import FormView from './views/form_view'; // ready to go $(document).ready(function() { + let bus = {}; + bus = _.extend(bus, Backbone.Events); + + const movieList = new MovieList({ bus: bus }); + const vendorList = new VendorList(); + // tripList.on('update', render, tripList); + movieList.fetch(); + + const movieListView = new MovieListView({ + model: movieList, + template: _.template($('#movie-template').html()), + detailsTemplate: _.template($('#movie-details-template').html()), + el: 'main', + bus: bus, + }); + + const formView = new FormView({ + model: movieList, + vendorModel: vendorList, + el: 'main', + bus: bus + }); + + const vendorListView = new VendorListView({ + model: vendorList, + inventory: movieList, + template: _.template($('#vendor-template').html()), + el: '#vendors-container', + bus: bus, + }); + + // movieListView.render(); - $('#main-content').append('

Hello World!

'); }); diff --git a/src/collections/movie_list.js b/src/collections/movie_list.js new file mode 100644 index 000000000..3b1ddc3c9 --- /dev/null +++ b/src/collections/movie_list.js @@ -0,0 +1,48 @@ +import Backbone from 'backbone'; + +import Movie from 'models/movie'; + +const MovieList = Backbone.Collection.extend({ + model: Movie, + url: 'http://localhost:3000/movies', + initialize(params) { + this.bus = params.bus; + + this.listenTo(this.bus, 'addToLibrary', this.addToLibrary); + }, + parse(response) { + return response; + }, + + addToLibrary(movie) { + if (!this.contains(movie)){ + const result = this.create(movie); + result.set('unique', true); + this.bus.trigger('updateStatus', result); + } else { + movie.set('unique', false); + this.bus.trigger('updateStatus', movie); + } + }, + + contains(movie) { + for (let i = 0; i < this.models.length; i += 1) { + const model = this.models[i]; + + if (model.get('title') === movie.get('title') && + model.get('release_date') === movie.get('release_date')) { + return true; + } + } + return false; + }, + + findWhereIgnoreCase(key, val) { + return this.filter(function(item) { + return item.get(key).toLowerCase() === val.toLowerCase(); + }); + }, + +}); + +export default MovieList; diff --git a/src/collections/vendor_list.js b/src/collections/vendor_list.js new file mode 100644 index 000000000..aea481100 --- /dev/null +++ b/src/collections/vendor_list.js @@ -0,0 +1,10 @@ +import Backbone from 'backbone'; + +import Movie from 'models/movie'; + +const VendorList = Backbone.Collection.extend({ + model: Movie, + url: 'http://localhost:3000/movies', +}); + +export default VendorList; diff --git a/src/models/movie.js b/src/models/movie.js new file mode 100644 index 000000000..14c5f54ed --- /dev/null +++ b/src/models/movie.js @@ -0,0 +1,29 @@ +import Backbone from 'backbone'; + +const Movie = Backbone.Model.extend({ + urlRoot: 'http://localhost:3000/movies', + defaults: { + inventory: 0, + }, + initialize(params) { + this.title = params.title; + // this.attributes.upperCaseTitle = this.title.toUpperCase(); + }, + validate(attributes) { + const errors = {}; + if(!attributes.title) { + errors['title'] = ["cannot be blank"]; + } + if(!attributes.release_date) { + errors['release_date'] = ["cannot be blank"] + } + + if (Object.keys(errors).length > 0) { + return errors; + } + return false; + }, + +}); + +export default Movie; diff --git a/src/views/form_view.js b/src/views/form_view.js new file mode 100644 index 000000000..046d23720 --- /dev/null +++ b/src/views/form_view.js @@ -0,0 +1,84 @@ +import Backbone from 'backbone'; +import _ from 'underscore'; +import $ from 'jquery'; + +import MovieView from '../views/movie_view'; +import VendorListView from '../views/vendor_list_view'; +import MovieList from '../collections/movie_list'; +import Movie from '../models/movie'; + +const FormView = Backbone.View.extend({ + initialize(params) { + this.bus = params.bus; + this.model = params.model; + this.vendorModel = params.vendorModel; + this.listenTo(this.bus, 'updateStatus', this.updateStatusMessageWith); + }, + events: { + 'click button.find-movie' : 'findMovie', + 'click button.show-all' : 'showAllMovies', + 'click button.vendor': 'searchTMDB', + }, + showAllMovies: function(e) { + e.preventDefault(); + + this.$('#movies-container').toggle(); + }, + findMovie: function(e) { + e.preventDefault(); + const title = this.$('input').val(); + let result; + + if (title && title !== '') result = (this.model.findWhereIgnoreCase('title', title))[0]; + if (result ) { + this.bus.trigger(`displayMyDetails${result.get('id')}`, result); + } else { + this.$('#status-message').append(`
  • "${title}" is not present in rental library.
  • `); + } + }, + searchModel: function(title) { + const movie = this.model.findWhereIgnoreCase({ title: title }); + return movie + }, + searchTMDB: function(event) { + event.preventDefault(); + const title = this.$('input').val(); + const that = this; + this.vendorModel.fetch({ + data: $.param({ query: title }), + success: function(vendorModel, response, options) { + that.updateStatusFrom(options); + } + }); + + }, + updateStatusMessageWith: function(movie) { + this.$('#status-message').empty(); + if (movie.isValid() && movie.get('unique')) { + this.$('#status-message').append(`
  • ${movie.get('title')} successfully added to rental library
  • `); + } else if (!movie.get('unique')) { + this.$('#status-message').append(`
  • ${movie.get('title')} is already in the rental library.
  • `); + } else { + this.$('#status-message').append(`
  • ${movie.get('title')} was not successfully added to rental library.
  • `); + const errors = movie.validationError; + Object.keys(errors).forEach((field) => { + errors[field].forEach((error) => { + this.$('#status-message').append(`
  • ${field}: ${error}
  • `); + }); + }); + } + + }, + updateStatusFrom: function(options) { + this.$('#status-message').empty(); + const query = options.data.slice(6) + if(options.xhr.responseJSON.length === 0){ + this.$('#status-message').append(`
  • No results for query: ${query}
  • `); + } else { + this.$('#status-message').append(`
  • Results for query: ${query}
  • `); + } + } + +}); + +export default FormView; diff --git a/src/views/movie_list_view.js b/src/views/movie_list_view.js new file mode 100644 index 000000000..12912c721 --- /dev/null +++ b/src/views/movie_list_view.js @@ -0,0 +1,33 @@ +import Backbone from 'backbone'; + +import MovieView from '../views/movie_view'; +import Movie from '../models/movie'; + +const MovieListView = Backbone.View.extend({ + initialize(params) { + this.bus = params.bus; + this.template = params.template; + this.detailsTemplate = params.detailsTemplate; + + this.listenTo(this.model, 'update', this.render); + this.listenTo(this.bus, 'addMovie', this.addMovie); + }, + render() { + this.$('#movies').empty(); + this.model.each((movie) => { + const movieView = new MovieView({ + model: movie, + template: this.template, + detailsTemplate: this.detailsTemplate, + bus: this.bus, + tagname: 'li', + className: 'movie', + }); + this.$('#movies').append(movieView.render().$el); + }); + }, + + +}); + +export default MovieListView; diff --git a/src/views/movie_view.js b/src/views/movie_view.js new file mode 100644 index 000000000..e330e37aa --- /dev/null +++ b/src/views/movie_view.js @@ -0,0 +1,40 @@ +import $ from 'jquery'; + +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const MovieView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.detailsTemplate = params.detailsTemplate; + this.bus = params.bus; + // this.listenTo(this.bus, `displayMyDetails${this.model.get('cid')}`, this.renderMovieDetails); + this.listenTo(this.bus, `displayMyDetails${this.model.get('id')}`, this.renderMovieDetails); + }, + render() { + const compiledTemplate = this.template(this.model.attributes); + this.$el.html(compiledTemplate); + return this; + }, + events: { + 'click this' : 'renderDetails', + }, + renderDetails: function(e) { + // debugger; + console.log('im trying to render a detail'); + e.preventDefault(); + this.renderMovieDetails(this.model); + }, + renderMovieDetails: function(movie, event) { + // debugger; + $('#movie-details').empty(); + const compiledTemplate = this.detailsTemplate(this.model.attributes); + this.$el.html(compiledTemplate); + $('#movie-details').append(this.$el); + // this.$('#movie-details').append(this.$el); + } + + +}); + +export default MovieView; diff --git a/src/views/vendor_list_view.js b/src/views/vendor_list_view.js new file mode 100644 index 000000000..19baf5be5 --- /dev/null +++ b/src/views/vendor_list_view.js @@ -0,0 +1,40 @@ +import Backbone from 'backbone'; +// import _ from 'underscore'; + +import VendorView from '../views/vendor_view'; +// import OrderView from '../views/order_view'; +// import Quote from '../models/quote'; +// import Movie from '../models/movie'; + +const VendorListView = Backbone.View.extend({ + initialize(params) { + this.bus = params.bus; + this.template = params.template; + this.detailsTemplate = params.detailsTemplate; + this.inventory = params.inventory; + this.vendorViews = [] + + this.listenTo(this.model, 'update', this.render); + }, + + render() { + this.$('#vendor-results').empty(); + this.vendorViews.forEach(view => view.remove()); + + this.model.each((movie) => { + const vendorView = new VendorView({ + model: movie, + template: this.template, + inventory: this.inventory, + detailsTemplate: this.detailsTemplate, + bus: this.bus, + tagName: 'li', + className: 'movie', + }); + this.vendorViews.push(vendorView); + this.$('#vendor-results').append(vendorView.render().$el); + }); + }, +}); + +export default VendorListView; diff --git a/src/views/vendor_view.js b/src/views/vendor_view.js new file mode 100644 index 000000000..12d721ed3 --- /dev/null +++ b/src/views/vendor_view.js @@ -0,0 +1,43 @@ +import $ from 'jquery'; + +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const VendorView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.detailsTemplate = params.detailsTemplate; + this.inventory = params.inventory; + this.bus = params.bus; + + this.listenTo(this.bus, `displayMyDetails${this.model.get('id')}`, this.renderMovieDetails); + }, + render() { + const compiledTemplate = this.template(this.model.attributes); + this.$el.html(compiledTemplate); + return this; + }, + events: { + 'click this' : 'renderDetails', + 'click button#add-movie': 'addMovie', + }, + renderDetails: function(e) { + e.preventDefault(); + this.renderMovieDetails(this.model); + }, + renderMovieDetails: function(movie, event) { + $('#movie-details').empty(); + const compiledTemplate = this.detailsTemplate(this.model.attributes); + this.$el.html(compiledTemplate); + $('#movie-details').append(this.$el); + }, + + addMovie(event) { + const title = this.model.get('title').toUpperCase(); + const date = this.model.get('release_date'); + this.bus.trigger('addToLibrary', this.model); + }, + +}); + +export default VendorView;