diff --git a/dist/index.html b/dist/index.html index 559b18ecd..ee7a02655 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,15 +1,88 @@ - - - Backbone Baseline - - -
- -
- - - - - + + + movies + + +
+
+
+
+ + + +
+
+

Results!

+
+ + + + + + + + + +
ImageTitleOverviewRelease Date +
+
+ + +
+
+

Movies!

+
+ + + + + + + +
TitleRelease Date
+
+
+
+ + + + + + + + diff --git a/src/app.js b/src/app.js index 30c00d594..fb1ef196b 100644 --- a/src/app.js +++ b/src/app.js @@ -5,10 +5,40 @@ import './css/styles.css'; // Import jQuery & Underscore import $ from 'jquery'; import _ from 'underscore'; +import Backbone from 'backbone'; + +// Import models and collections +import Movie from 'models/movie' +import MovieList from 'collections/movie_list' +import MovieListView from './views/movie_list_view' +import SearchListView from './views/search_list_view' // ready to go $(document).ready(function() { - $('#main-content').append('

Hello World!

'); + let bus = {}; + bus = _.extend(bus, Backbone.Events); + + const movieTemplate = _.template($('#all-movies-template').html()); + const searchTemplate = _.template($('#search-results').html()); + + const moviesList = new MovieList(); + + + const searchListView = new SearchListView({ + el: $('#search-view'), + template: searchTemplate, + bus: bus, + movies: moviesList, + }); + + const movieListView = new MovieListView({ + model: moviesList, + template: movieTemplate, + el: $('#list-movies'), + bus: bus, + }); + + moviesList.fetch(); }); diff --git a/src/collections/movie_list.js b/src/collections/movie_list.js new file mode 100644 index 000000000..480db962e --- /dev/null +++ b/src/collections/movie_list.js @@ -0,0 +1,9 @@ +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const MovieList = Backbone.Collection.extend({ + model: Movie, + url: 'http://localhost:3000/movies', +}) // MovieList + +export default MovieList diff --git a/src/css/styles.css b/src/css/styles.css index 68a79a569..535cde6a2 100644 --- a/src/css/styles.css +++ b/src/css/styles.css @@ -37,6 +37,10 @@ aside label { div { display: inline; } + +.hide { + display: none; +} /* * { border-style: solid; diff --git a/src/models/movie.js b/src/models/movie.js new file mode 100644 index 000000000..9675c4c29 --- /dev/null +++ b/src/models/movie.js @@ -0,0 +1,9 @@ +import Backbone from 'backbone'; + +const Movie = Backbone.Model.extend({ + // set the url so we can make a post request on a model + url: 'http://localhost:3000/movies', + +}); + +export default Movie diff --git a/src/views/movie_list_view.js b/src/views/movie_list_view.js new file mode 100644 index 000000000..81095d812 --- /dev/null +++ b/src/views/movie_list_view.js @@ -0,0 +1,42 @@ +import Backbone from 'backbone'; +import MovieView from './movie_view'; + +const MovieListView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.bus = params.bus; + + this.listenTo(this.model, 'update', this.render); + + // listen for event from the searchView to check if the movie already exists in the local collection + this.listenTo(this.bus, 'lookForMovie', this.checkCollectionForMovie); + }, + render() { + // console.log("inside render in movie list view"); + // console.log( this.model); + this.model.each((movie) => { + const movieView = new MovieView({ + model: movie, + template: this.template, + tagName: 'tr', + }); + this.$('#movies-list').append(movieView.render().$el); + }); + return this + }, // render + checkCollectionForMovie(movieData) { + let haveIt = false; + this.model.each((movie) => { + if (movie.get('title') === movieData.title && movie.get('release_date') === movieData.release_date ) { + haveIt = true; + console.log('we have the movie'); + } // if + this.bus.trigger(`${movieData.title}${movieData.release_date}`, haveIt) + }) // .each + + + }, // checkbox + +}); + +export default MovieListView; diff --git a/src/views/movie_view.js b/src/views/movie_view.js new file mode 100644 index 000000000..1dc2e4e84 --- /dev/null +++ b/src/views/movie_view.js @@ -0,0 +1,16 @@ +import Backbone from 'backbone'; +import Movie from '../models/movie'; + +const MovieView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + }, // initialize + render() { + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate) + + return this; + }, // render +}) // MovieView + +export default MovieView; diff --git a/src/views/search_list_view.js b/src/views/search_list_view.js new file mode 100644 index 000000000..81aa2e194 --- /dev/null +++ b/src/views/search_list_view.js @@ -0,0 +1,70 @@ +import Backbone from 'backbone'; +import $ from 'jquery'; +import SearchView from './search_view'; + + +const SearchListView = Backbone.View.extend({ + initialize(params) { + this.template = params.template; + this.movies = params.movies; + this.bus = params.bus; + this.listenTo(this.bus, 'errorSavingMovie', this.renderStatus); + }, // initialize + statusMessage(message) { + this.$('#status-messages').empty(); + this.$('#status-messages').append(`

${message}

`) + }, // statusMessage + events: { + 'click #search-button': 'searchForMovie', + 'click #clear-search': 'clearResults', + }, // events + searchForMovie(event) { + event.preventDefault(); + // this allows us to access the text input in the search form + const title = this.$('#search-input').val(); + + // create the url to make the api request + const url = 'http://localhost:3000/movies?query=' + title ; + const encoded_url = encodeURI(url); + + // make a call to the url using only jQuery + // this will make a call to the local API's movies index action, which will then make a call to the external API to get all the movies that match the search query + // const APIresponse = $.get(encoded_url) + + $.get(encoded_url).done( (data) => { + const APIresponse = data; + if (APIresponse.length < 1) { + console.log('no results'); + this.statusMessage(`No results found for ${title}`); + } + this.render(APIresponse) + + }) + }, // searchForMovie + render(results){ + // select element in html and toggle class + $('#results-table').toggleClass('hide') + // make a new search view for each result in the search response. + for (var result of results) { + const searchView = new SearchView({ + model: result, + template: this.template, + tagName: 'tr', + movies: this.movies, + bus: this.bus, + }); + this.$('#search-list').append(searchView.render().$el); + } + return this + },//close render + clearResults(){ + $('#results-table').toggleClass('hide'); + $('#search-list').empty(); + },//clearResults + renderStatus(errorMessage){ + this.$('#search-status').empty(); + this.$('#search-status').append(errorMessage) + } +}) //close view + +export default SearchListView diff --git a/src/views/search_view.js b/src/views/search_view.js new file mode 100644 index 000000000..fbb07da97 --- /dev/null +++ b/src/views/search_view.js @@ -0,0 +1,74 @@ +import Backbone from 'backbone'; +import $ from 'jquery'; +import Movie from '../models/movie'; +// import MovieList from '../collections/movie_list' +const SearchView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.bus = params.bus; + this.movies = params.movies; + this.listenTo(this.model, 'update', this.render); + this.listenTo(this.bus,`${this.model.title}${this.model.release_date}`, this.setHave ) + }, + events: { + // trigger when user wants to add a movie to the rails DB + 'click #add-movie' : 'makePost', + }, + render(){ + const movieData = { + title: this.model.title, + release_date: this.model.release_date} + this.doWeHaveMovie(movieData) + const compiledTemplate = this.template(this.model); //.toJSON()); + this.$el.html(compiledTemplate) + return this + }, // render + doWeHaveMovie(movieData) { + this.bus.trigger('lookForMovie', movieData); + }, // doWeHaveMovie + setHave(haveIt) { + if (haveIt) { + this.model['have'] = true; + } else { + this.model['have'] = false; + } // if + }, // setHave + makePost(){ + + // from notes: $.post(url, formData, success: callback) + + // set the url to make post request + const url = 'http://localhost:3000/movies'; + + // pull out the external_id from the views model to pass to the api + const ex_id = this.model['external_id']; + + // make a post request to the api, passing the external Id to the API + // this request goes to the create at the movies controller + $.post(url, {movie: {external_id: ex_id }}).done((data) => { + console.log('data'); + console.log(data); + if (data !== {}){ + // when the API was success create a new movie model with this data + console.log('in if for $.post'); + const newMovieDB = new Movie(data); + // add the new movie model to the movie list collection + this.movies.add(newMovieDB) + // change the add movie buttom to movie added + this.$('#have-movie').empty(); + this.$('#have-movie').append('Movie added') + } else { + const noResults = `

Can not add movie to the library

` + this.bus.trigger('errorSavingMovie', noResults); + } + + }).fail((data)=>{ + // if the API calls fails, shows error message + const error = '

Error adding movie to the library

' + this.bus.trigger('errorSavingMovie', error); + }) + }//makePost + + }); + + export default SearchView