go-bouquins/assets/js/bouquins.js

425 lines
11 KiB
JavaScript
Raw Normal View History

2017-08-06 11:12:59 +00:00
var bus = new Vue();
// COMPONENTS //
Vue.component('results-list', {
template: '#results-list-template',
props: ['results', 'count', 'type'],
methods: {
url: function(item) {
return '/'+this.type+'/'+item.id;
},
label: function(item) {
switch (this.type) {
case 'books':
return item.title;
case 'authors':
case 'series':
return item.name;
default:
return '';
}
},
iconClass: function() {
return 'glyphicon glyphicon-' + this.icon();
},
icon: function() {
switch (this.type) {
case 'books':
2017-08-06 13:41:58 +00:00
return 'book';
2017-08-06 11:12:59 +00:00
case 'authors':
return 'user';
case 'series':
return 'list';
default:
return '';
}
},
countlabel: function() {
switch (this.type) {
case 'books':
return this.count > 1 ? 'livres' : 'livre';
case 'authors':
return this.count > 1 ? 'auteurs' : 'auteur';
case 'series':
return this.count > 1 ? 'series' : 'serie';
default:
return '';
}
}
}
});
Vue.component('results', {
template: '#results-template',
props: ['results', 'cols','sort_by','order_desc'],
methods: {
sortBy: function(col) {
bus.$emit('sort-on', col);
}
}
});
Vue.component('result-cell', {
render: function(h) {
return h('td', this.cellContent(h));
},
props: ['item', 'col'],
methods: {
bookUrl: function(id) {
return '/books/' + id;
},
authorUrl: function(id) {
return '/authors/' + id;
},
seriesUrl: function(id) {
return '/series/' + id;
},
link: function(h, icon, text, url) {
return [
h('span',{ attrs: { class: 'glyphicon glyphicon-'+icon } },''),
' ',
h('a', { attrs: { href: url } }, text)
];
},
badge: function(h, num) {
return h('span', { attrs: { class: 'badge' } }, num);
},
cellContent: function(h) {
switch (this.col.id) {
case 'author_name':
return this.link(h, 'user', this.item.name, this.authorUrl(this.item.id));
case 'serie_name':
return this.link(h, 'list', this.item.name, this.authorUrl(this.item.id));
case 'count':
return this.item.count;
case 'title':
return this.link(h, 'book', this.item.title, this.bookUrl(this.item.id));
case 'authors':
var elts = [];
var authors = this.item.authors;
if (authors) {
for (i=0;i<authors.length;i++) {
elts[i] = this.link(h, 'user', authors[i].name, this.authorUrl(authors[i].id));
}
}
return elts;
case 'series':
var series = this.item.series;
if (series) {
return [
this.link(h, 'list', series.name, this.seriesUrl(series.id)),
h('span', { attrs: { class: 'badge' } }, this.item.series_idx)
];
}
return '';
default:
console.log('ERROR unknown col: ' + this.col.id)
return '';
}
}
}
});
Vue.component('paginate', {
template: '#paginate-template',
props: ['page','more'],
methods: {
prevPage: function() {
if (this.page > 1) bus.$emit('update-page', -1);
},
nextPage: function() {
if (this.more) bus.$emit('update-page', 1);
}
}
});
// PAGES //
if (document.getElementById("index")) {
new Vue({
el: '#index',
data: {
url: '',
page: 0,
perpage: 20,
more: false,
sort_by: null,
order_desc: false,
cols: [],
results: []
},
methods: {
sortBy: function(col) {
if (this.sort_by == col) {
if (this.order_desc) {
this.order_desc = false;
this.sort_by = null;
} else {
this.order_desc = true;
}
} else {
this.order_desc = false;
this.sort_by = col;
}
this.updateResults();
},
updatePage: function(p) {
this.page += p;
this.updateResults();
},
order: function(query) {
if (this.order_desc)
return query + '&order=desc';
return query;
},
sort: function(query) {
if (this.sort_by)
return query + '&sort=' + this.sort_by;
return query;
},
paginate: function(query) {
return query + '?page=' + this.page + '&perpage=' + this.perpage;
},
params: function(url) {
return this.order(this.sort(this.paginate(url)));
},
updateResults: function() {
this.sendQuery(this.params(this.url), this.stdError, this.loadResults);
},
showSeries: function() {
this.url = '/series/';
this.updateResults();
},
showAuthors: function() {
this.url = '/authors/';
this.updateResults();
},
showBooks: function() {
this.url = '/books/';
this.updateResults();
},
loadCols: function(type) {
switch (type) {
case 'books':
this.cols = [
{ id: 'title', name: 'Titre', sort: 'title' },
{ id: 'authors', name: 'Auteur(s)' },
{ id: 'series', name: 'Serie' }
];
break;
case 'series':
this.cols = [
{ id: 'serie_name', name: 'Nom', sort: 'name' },
{ id: 'count', name: 'Livre(s)' },
{ id: 'authors', name: 'Auteur(s)' }
];
break;
case 'authors':
this.cols = [
{ id: 'author_name', name: 'Nom', sort: 'name' },
{ id: 'count', name: 'Livre(s)' }
];
break;
}
},
loadResults(resp) {
this.results = [];
this.more = resp.more;
this.loadCols(resp.type);
if (resp.results) {
this.results = resp.results;
if (this.page == 0) this.page = 1;
} else {
this.page = 0;
}
},
sendQuery: function(url, error, success) {
var xmh = new XMLHttpRequest();
var v;
xmh.onreadystatechange = function() {
v = xmh.responseText;
if (xmh.readyState === 4 && xmh.status === 200) {
var res;
try {
res = JSON.parse(v);
} catch (err) {
if (null !== error)
error(err.name, err.message);
}
if (null !== success)
success(res);
} else if (xmh.readyState === 4) {
if (null !== error)
error(xmh.status, v);
}
};
xmh.open('GET', url, true);
xmh.setRequestHeader('Accept','application/json');
xmh.send(null);
},
stdError: function(code, resp) {
console.log('ERROR ' + code + ': ' + resp);
}
},
mounted: function() {
bus.$on('sort-on', this.sortBy);
bus.$on('update-page', this.updatePage);
}
});
}
if (document.getElementById("author")) {
new Vue({
el: '#author',
data: {
tab: "books"
},
methods: {
showBooks: function() {
this.tab = "books";
},
showAuthors: function() {
this.tab = "authors";
},
showSeries: function() {
this.tab = "series";
}
}
});
}
if (document.getElementById("search")) {
new Vue({
el: '#search',
data: {
2017-08-06 13:41:58 +00:00
urlParams: [],
2017-08-06 11:12:59 +00:00
authors: [],
books: [],
series: [],
authorsCount: 0,
booksCount: 0,
seriesCount: 0,
q: '',
which: 'all',
all: false,
perpage: 10
},
methods: {
searchParams: function(url) {
var res = url;
res += '?perpage=' + this.perpage;
for (var i=0; i<this.terms.length; i++) {
var t = this.terms[i];
if (t.trim())
res += '&term=' + encodeURIComponent(t.trim());
}
return res;
},
searchAuthorsSuccess: function(res) {
this.authorsCount = res.count;
this.authors = res.results;
},
searchAuthors: function() {
this.sendQuery(this.searchParams('/authors/'), this.stdError, this.searchAuthorsSuccess);
},
searchBooksSuccess: function(res) {
this.booksCount = res.count;
this.books = res.results;
},
searchBooks: function() {
this.sendQuery(this.searchParams('/books/'), this.stdError, this.searchBooksSuccess);
},
searchSeriesSuccess: function(res) {
this.seriesCount = res.count;
this.series = res.results;
},
searchSeries: function() {
this.sendQuery(this.searchParams('/series/'), this.stdError, this.searchSeriesSuccess);
},
searchAll: function() {
this.clear();
this.searchAuthors();
this.searchBooks();
this.searchSeries();
},
clear: function() {
this.authors = [];
this.books = [];
this.series = [];
this.authorsCount = 0;
this.booksCount = 0;
this.seriesCount = 0;
},
searchFull: function() {
if (this.q) {
this.terms = this.q.split(' ');
switch (this.which) {
case 'all':
this.searchAll();
break;
case 'authors':
this.clear();
this.searchAuthors();
break;
case 'books':
this.clear();
this.searchBooks();
break;
case 'series':
this.clear();
this.searchSeries();
break;
}
}
return false;
},
searchUrl: function() {
if (this.urlParams.q) {
this.terms = this.urlParams.q.split(' ');
this.searchAll();
this.q = this.urlParams.q;
}
},
2017-08-06 13:41:58 +00:00
urlParse: function() {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
while (match = search.exec(query))
this.urlParams[decode(match[1])] = decode(match[2]);
},
2017-08-06 11:12:59 +00:00
sendQuery: function(url, error, success) {
var xmh = new XMLHttpRequest();
var v;
xmh.onreadystatechange = function() {
v = xmh.responseText;
if (xmh.readyState === 4 && xmh.status === 200) {
var res;
try {
res = JSON.parse(v);
} catch (err) {
if (null !== error)
error(err.name, err.message);
}
if (null !== success)
success(res);
} else if (xmh.readyState === 4) {
if (null !== error)
error(xmh.status, v);
}
};
xmh.open('GET', url, true);
xmh.setRequestHeader('Accept','application/json');
xmh.send(null);
},
stdError: function(code, resp) {
console.log('ERROR ' + code + ': ' + resp);
}
2017-08-06 13:41:58 +00:00
},
created: function() {
this.urlParse();
},
mounted: function() {
this.searchUrl();
2017-08-06 11:12:59 +00:00
}
});
}