Use ajax to improve some functionalities

master
Guillaume Dott 2015-10-22 12:58:43 +02:00
parent 7925becdfb
commit 1bdd77ea23
9 changed files with 147 additions and 49 deletions

View File

@ -17,8 +17,19 @@ module Librarix
end
get '/search' do
movies = params.key?('search') ? Tmdb::Movie.find(params['search']) : Tmdb::Movie.popular.map { |m| Tmdb::Movie.new(m) }
slim :search, locals: {movies: movies, conf: Tmdb::Configuration.new}
movies = if params['search'].nil?
Tmdb::Movie.popular.map { |m| Tmdb::Movie.new(m) }
elsif params['search'] == ''
[]
else
Tmdb::Movie.find(params['search'])
end
if request.xhr?
slim :list, layout: false, locals: {movies: movies}
else
slim :search, locals: {movies: movies}
end
end
post '/add' do
@ -36,7 +47,11 @@ module Librarix
post '/remove' do
Librarix::Redis::Movie.new(params[:id]).remove
redirect to('/')
if request.xhr?
""
else
redirect to('/')
end
end
end
end

View File

@ -1,35 +1,56 @@
body {
margin: 0;
margin: 10px;
}
h2 {
margin-top: 0;
}
#search {
display: flex;
input {
border-radius: 0.4em;
border: solid 3px #f4f4f4;
}
input[type="submit"] {
background-color: #f4f4f4;
}
input[type="text"] {
flex-grow: 1;
font-size: 1.4em;
padding: 5px;
}
}
ul {
list-style-type: none;
margin: 0;
padding: 0;
li {
padding: 10px;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
.poster {
margin-right: 10px;
}
.informations {
align-self: flex-start;
flex: 1 1 300px;
}
padding: 10px 0;
}
li:nth-child(even) {
background-color: #f4f4f4;
}
}
.movie {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
.poster {
margin-right: 10px;
}
.informations {
align-self: flex-start;
flex: 1 1 300px;
}
}

View File

@ -1 +1 @@
body{margin:0}h2{margin-top:0}ul{list-style-type:none;margin:0;padding:0}ul li{padding:10px;display:flex;flex-flow:row wrap;align-items:center;justify-content:center}ul li .poster{margin-right:10px}ul li .informations{align-self:flex-start;flex:1 1 300px}ul li:nth-child(even){background-color:#f4f4f4}
body{margin:10px}h2{margin-top:0}#search{display:flex}#search input{border-radius:0.4em;border:solid 3px #f4f4f4}#search input[type="submit"]{background-color:#f4f4f4}#search input[type="text"]{flex-grow:1;font-size:1.4em;padding:5px}ul{list-style-type:none;margin:0;padding:0}ul li{padding:10px 0}ul li:nth-child(even){background-color:#f4f4f4}.movie{display:flex;flex-flow:row wrap;align-items:center;justify-content:center}.movie .poster{margin-right:10px}.movie .informations{align-self:flex-start;flex:1 1 300px}

View File

@ -1,2 +1,65 @@
function initButtons() {
var buttons = document.querySelectorAll('button[data-action=remove-movie]');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function(event) {
event.preventDefault();
removeMovie(this.previousElementSibling.value)
});
}
}
function initSearch() {
var typing_timer;
var typing_interval = 300;
document.querySelector('#search > input[type="text"]').addEventListener('input', function(event) {
var value = this.value;
clearTimeout(typing_timer);
typing_timer = setTimeout(function() { search(value); }, typing_interval);
});
document.querySelector('#search > input[type="submit"]').style.display = 'none';
window.addEventListener('popstate', function(event) {
document.querySelector('#search > input[type="text"]').value = event.state.value;
search(event.state.value);
});
}
function search(value) {
var url = '/search?search=' + encodeURIComponent(value)
window.history.pushState({value: value}, "", url);
var req = new XMLHttpRequest();
req.open('GET', url);
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.addEventListener('load', function(e) {
document.getElementById('movies').parentNode.innerHTML = this.responseText;
});
req.send()
}
function removeMovie(id) {
var data = new FormData();
data.append('id', id);
var req = new XMLHttpRequest();
req.open('POST', '/remove');
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.addEventListener('load', function(e) {
document.querySelector('.movie[data-id="' + id + '"]').parentNode.remove();
});
req.send(data)
}
document.addEventListener('DOMContentLoaded', function(event) {
initButtons();
if(document.querySelector('#search') != null) {
initSearch();
}
});

View File

@ -1,6 +1,3 @@
- content_for(:title) { 'Index' }
ul
- movies.each do |movie|
li
== slim :movie, locals: {movie: movie}
== slim :list, locals: {movies: movies}

View File

@ -7,5 +7,4 @@ html
link rel="stylesheet" media="all" href="/application.css"
script type="text/javascript" src="/application.js"
body
div#main
== yield
== yield

View File

@ -0,0 +1,4 @@
ul#movies
- movies.each do |movie|
li
== slim :movie, locals: {movie: movie}

View File

@ -1,16 +1,17 @@
.poster
- if movie.poster_path
img src="#{poster_url(movie.poster_path, 'w154')}"
.informations
h2
a href="https://www.themoviedb.org/movie/#{movie.id}" #{movie.original_title} (#{movie.release_year})
p = movie.overview
.actions
- if movie.added?
form method="post" action="/remove"
input type="hidden" name="id" value="#{movie.id}"
button type="submit" Remove
- else
form method="post" action="/add"
input type="hidden" name="id" value="#{movie.id}"
button type="submit" Add
.movie data-id="#{movie.id}"
.poster
- if movie.poster_path
img src="#{poster_url(movie.poster_path, 'w154')}"
.informations
h2
a href="https://www.themoviedb.org/movie/#{movie.id}" #{movie.original_title} (#{movie.release_year})
p = movie.overview
.actions
- if movie.added?
form method="post" action="/remove"
input type="hidden" name="id" value="#{movie.id}"
button type="submit" data-action="remove-movie" Remove
- else
form method="post" action="/add"
input type="hidden" name="id" value="#{movie.id}"
button type="submit" data-action="add-movie" Add

View File

@ -1,10 +1,8 @@
- content_for(:title) { 'Search' }
form method="get" action="/search"
input type="text" name="search" value="#{params['search']}"
input type="submit"
form method="get" action="/search" id="search"
input type="text" name="search" value="#{params['search']}" autocomplete="off" autofocus="on"
input type="submit" value="Search"
ul
- movies.each do |movie|
li
== slim :movie, locals: {movie: movie}
div
== slim :list, locals: {movies: movies}