Risorse
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="bower_components/bootstrap-4.1.1-dist/css/bootstrap.css">
<link rel="stylesheet" href="css/loader.css">
<link rel="stylesheet" href="bower_components/fancybox/dist/jquery.fancybox.min.css">
</head>
<body>
<div class="jumbotron jumbotron-fluid bg-dark text-light py-4">
<div class="container">
<h1 class="display-4">Cerca su Youtube</h1>
</div>
</div>
<div class="container py-4">
<div class="row">
<div class="col-md">
<input type="search" id="query" class="form-control form-control-lg mb-3" placeholder="frase o id canale" />
</div>
<div class="col-md-auto">
<select id="query-type" class="form-control form-control-lg">
<option value="1">query</option>
<option value="2">id canale</option>
</select>
</div>
<div class="col-md-auto">
<button id="search-btn" class="btn btn-danger btn-lg">Cerca</button>
</div>
</div>
<h1 class="text-center my-4">Risultati</h1>
<div class="row" id="results"></div>
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a id="prev" class="page-link" href="#" tabindex="-1">« prev</a>
</li>
<li class="page-item disabled">
<a id="next" class="page-link" href="#">succ »</a>
</li>
</ul>
</nav>
</div>
<script src="bower_components/jquery-3.3.1.min/index.js"></script>
<script src="bower_components/fancybox/dist/jquery.fancybox.min.js"></script>
<script src="bower_components/bootstrap-4.1.1-dist/js/bootstrap.bundle.min.js"></script>
<script src="js/YoutubeSearch.js"></script>
<script src="js/main.js"></script>
</body>
</html>
css/loader.css
#results {
min-height: 200px;
}
.loader {
color: rgba(0,0,0,0.6);
font-size: 20px;
margin: 100px auto;
width: 1em;
height: 1em;
border-radius: 50%;
position: relative;
text-indent: -9999em;
-webkit-animation: load4 1.3s infinite linear;
animation: load4 1.3s infinite linear;
-webkit-transform: translateZ(0);
transform: translateZ(0);
margin: auto;
}
@-webkit-keyframes load4 {
0%,
100% {
-webkit-box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
-webkit-box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
-webkit-box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
-webkit-box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
-2em -2em 0 0;
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
-2em -2em 0 0;
}
87.5% {
-webkit-box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
@keyframes load4 {
0%,
100% {
-webkit-box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
}
12.5% {
-webkit-box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
25% {
-webkit-box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
}
37.5% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
50% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
}
62.5% {
-webkit-box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
}
75% {
-webkit-box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
-2em -2em 0 0;
box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em,
2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em,
-2em -2em 0 0;
}
87.5% {
-webkit-box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
}
}
js/YoutubeSearch.js
var YoutubeSearch = function (options) {
var opt = {};
$.extend(opt, this.defaults, options);
for (var prop in opt) {
this[prop] = opt[prop];
}
}
YoutubeSearch.prototype = {
defaults : {
service: "https://www.googleapis.com/youtube/v3/search",
query: "",
queryType: "video",
maxResults: 12,
apikey: "",
fail: null,
done: null,
always: null,
order: 'date'
},
nextPageToken: '',
prevPageToken: '',
pageToken:'',
getParam: function() {
var data = {
key: this.apikey,
part: 'snippet,id',
type: 'video',
maxResults: this.maxResults,
order: this.order
};
if (this.queryType == 'video') {
data.q = this.query;
} else {
data.channelId = this.query;
}
if(this.pageToken)
data.pageToken = this.pageToken;
return data;
},
getRequest: function () {
var self = this;
$.getJSON(self.service, self.getParam())
.fail(function (jqXHR, textStatus,errorThrown) {
if (self.fail)
self.fail(jqXHR, textStatus,errorThrown)
else
throw(textStatus);
})
.done (function (data, textStatus, jqXHR) {
self.nextPageToken = data.nextPageToken;
self.prevPageToken = data.prevPageToken;
if(self.done)
self.done(data.items, textStatus, jqXHR);
else
throw ('Non è stato definito alcuna fubzione di callback.')
})
.always(function (data, textStatus, jqHXR) {
if(self.always)
self.always(data, textStatus, jqHXR);
})
},
search: function (query, queryType) {
if (query)
this.query = query;
if (queryType)
this.queryType = queryType;
this.pageToken = '';
this.getRequest();
},
goNext: function() {
if (this.nextPageToken){
this.pageToken = this.nextPageToken;
this.getRequest();
}
},
goPrev: function () {
if (this.prevPageToken) {
this.pageToken = this.prevPageToken;
this.getRequest();
}
}
}
js/main.js
$(document).ready(function () {
$('#query').tooltip({
container: 'body',
trigger: 'focus',
placement: 'top',
title: function () {
return $(this).attr('placeholder');
}
});
function getOutput(item) {
var videoID = item.id.videoId;
var title = item.snippet.title;
var thumb = item.snippet.thumbnails.high.url;
var $output = $('<div />').addClass('col-sm-6 col-md-4 col-lg-3 mb-3');
var $img = $('<img />').attr ({
src: thumb,
alt: title,
class: 'img-fluid mb-2'
});
var $dida = $('<div />')
.addClass('text-center')
.html(title);
var $a = $('<a />')
.attr({
href: "https://www.youtube.com/watch?v=" + videoID,
'data-fancybox': 'gallery'
}).append($img, $dida);
return $output.append($a);
};
var myYoutube = new YoutubeSearch({
apikey:'AIzaSyB2Vaw44AZOYSgItgbNYeo8QOInBbFB4W8'
});
myYoutube.fail = function(jqXHR, textStatus, erorrThrown ) {
if (erorrThrown) {
alert("Errore: " + erorrThrown);
} else {
var err = jqXHR.responseJSON;
if (err.error) {
alert('Errore ' + err.error.code + ", " + err.error.message);
}
}
};
myYoutube.done = function (items, textStatus, jqXHR) {
$.each(items, function (i,item) {
var $video = getOutput(item);
$('#results').append($video);
});
if (this.nextPageToken) {
$('#next').parent().removeClass('disabled');
} else {
$('#next').parent().addClass('disabled');
}
if (this.prevPageToken) {
$('#prev').parent().removeClass('disabled');
} else {
$('#prev').parent().addClass('disabled');
}
};
myYoutube.always = function () {
$('.loader').remove();
}
$('#search-btn').click(function (e) {
e.preventDefault();
var q = $('#query').val();
var wich = $('#query-type').val();
if (q) {
$('#results').html('').append('<div class="loader">Loading...</div>');
myYoutube.search(q, wich == 1 ? 'video' : 'channel');
}
});
$('#next').click(function (e) {
e.preventDefault();
$('#results').html('').append('<div class="loader">Loading...</div>');
myYoutube.goNext();
});
$('#prev').click(function (e) {
e.preventDefault();
$('#results').html('').append('<div class="loader">Loading...</div>');
myYoutube.goPrev();
});
});