Factorize JS

This commit is contained in:
Meutel 2017-08-06 17:18:27 +02:00
parent 7b78861384
commit 606afb279d

View File

@ -1,51 +1,90 @@
var bus = new Vue(); var bus = new Vue();
// COMMONS //
var BOOKS = 'books', AUTHORS = 'authors', SERIES = 'series';
var BOUQUINS_TYPES = {
books: { icon: 'book', singular: 'livre', plural: 'livres',
tab_cols: [ { id: 'title', name: 'Titre', sort: 'title' },
{ id: 'authors', name: 'Auteur(s)' },
{ id: 'series', name: 'Serie' } ] },
authors: { icon: 'user', singular: 'auteur', plural: 'auteurs',
tab_cols: [ { id: 'author_name', name: 'Nom', sort: 'name' },
{ id: 'count', name: 'Livre(s)' } ] },
series: { icon: 'list', singular: 'serie', plural: 'series',
tab_cols: [ { id: 'serie_name', name: 'Nom', sort: 'name' },
{ id: 'count', name: 'Livre(s)' },
{ id: 'authors', name: 'Auteur(s)' } ] }
};
function ty(type) {
if (BOUQUINS_TYPES[type]) return BOUQUINS_TYPES[type]
console.log("ERROR: Unknown type: " + type);
return {}
}
function icon(type) {
return ty(type).icon;
}
function iconClass(type) {
return 'glyphicon glyphicon-' + icon(type);
}
function url(type, id) {
if (id) return ty(type) ? '/'+type+'/'+id:'';
return ty(type) ? '/'+type+'/':'';
}
function label(type, count) {
return count == 1 ? ty(type).singular : ty(type).plural;
}
function stdError(code, resp) {
console.log('ERROR ' + code + ': ' + resp);
}
function sendQuery(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);
}
// COMPONENTS // // COMPONENTS //
Vue.component('results-list', { Vue.component('results-list', {
template: '#results-list-template', template: '#results-list-template',
props: ['results', 'count', 'type'], props: ['results', 'count', 'type'],
methods: { methods: {
url: function(item) { url: function(item) { return url(this.type, item.id); },
return '/'+this.type+'/'+item.id;
},
label: function(item) { label: function(item) {
switch (this.type) { switch (this.type) {
case 'books': case BOOKS:
return item.title; return item.title;
case 'authors': case AUTHORS:
case 'series': case SERIES:
return item.name; return item.name;
default: default:
return ''; return '';
} }
}, },
iconClass: function() { iconClass: function() {
return 'glyphicon glyphicon-' + this.icon(); return iconClass(this.type);
},
icon: function() {
switch (this.type) {
case 'books':
return 'book';
case 'authors':
return 'user';
case 'series':
return 'list';
default:
return '';
}
}, },
countlabel: function() { countlabel: function() {
switch (this.type) { return label(this.type, this.count);
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 '';
}
} }
} }
}); });
@ -64,20 +103,11 @@ Vue.component('result-cell', {
}, },
props: ['item', 'col'], props: ['item', 'col'],
methods: { methods: {
bookUrl: function(id) { link: function(h, type, text, id) {
return '/books/' + id;
},
authorUrl: function(id) {
return '/authors/' + id;
},
seriesUrl: function(id) {
return '/series/' + id;
},
link: function(h, icon, text, url) {
return [ return [
h('span',{ attrs: { class: 'glyphicon glyphicon-'+icon } },''), h('span',{ attrs: { class: iconClass(type) } },''),
' ', ' ',
h('a', { attrs: { href: url } }, text) h('a', { attrs: { href: url(type, id) } }, text)
]; ];
}, },
badge: function(h, num) { badge: function(h, num) {
@ -86,19 +116,19 @@ Vue.component('result-cell', {
cellContent: function(h) { cellContent: function(h) {
switch (this.col.id) { switch (this.col.id) {
case 'author_name': case 'author_name':
return this.link(h, 'user', this.item.name, this.authorUrl(this.item.id)); return this.link(h, AUTHORS, this.item.name, this.item.id);
case 'serie_name': case 'serie_name':
return this.link(h, 'list', this.item.name, this.authorUrl(this.item.id)); return this.link(h, SERIES, this.item.name, this.item.id);
case 'count': case 'count':
return this.item.count; return this.item.count;
case 'title': case 'title':
return this.link(h, 'book', this.item.title, this.bookUrl(this.item.id)); return this.link(h, BOOKS, this.item.title, this.item.id);
case 'authors': case 'authors':
var elts = []; var elts = [];
var authors = this.item.authors; var authors = this.item.authors;
if (authors) { if (authors) {
for (i=0;i<authors.length;i++) { for (i=0;i<authors.length;i++) {
elts[i] = this.link(h, 'user', authors[i].name, this.authorUrl(authors[i].id)); elts[i] = this.link(h, AUTHORS, authors[i].name, authors[i].id);
} }
} }
return elts; return elts;
@ -106,7 +136,7 @@ Vue.component('result-cell', {
var series = this.item.series; var series = this.item.series;
if (series) { if (series) {
return [ return [
this.link(h, 'list', series.name, this.seriesUrl(series.id)), this.link(h, SERIES, series.name, series.id),
h('span', { attrs: { class: 'badge' } }, this.item.series_idx) h('span', { attrs: { class: 'badge' } }, this.item.series_idx)
]; ];
} }
@ -166,14 +196,10 @@ if (document.getElementById("index")) {
this.updateResults(); this.updateResults();
}, },
order: function(query) { order: function(query) {
if (this.order_desc) return query + (this.order_desc ? '&order=desc' : '');
return query + '&order=desc';
return query;
}, },
sort: function(query) { sort: function(query) {
if (this.sort_by) return query + (this.sort_by ? '&sort=' + this.sort_by : '');
return query + '&sort=' + this.sort_by;
return query;
}, },
paginate: function(query) { paginate: function(query) {
return query + '?page=' + this.page + '&perpage=' + this.perpage; return query + '?page=' + this.page + '&perpage=' + this.perpage;
@ -182,43 +208,22 @@ if (document.getElementById("index")) {
return this.order(this.sort(this.paginate(url))); return this.order(this.sort(this.paginate(url)));
}, },
updateResults: function() { updateResults: function() {
this.sendQuery(this.params(this.url), this.stdError, this.loadResults); sendQuery(this.params(this.url), stdError, this.loadResults);
}, },
showSeries: function() { showSeries: function() {
this.url = '/series/'; this.url = url(SERIES);
this.updateResults(); this.updateResults();
}, },
showAuthors: function() { showAuthors: function() {
this.url = '/authors/'; this.url = url(AUTHORS);
this.updateResults(); this.updateResults();
}, },
showBooks: function() { showBooks: function() {
this.url = '/books/'; this.url = url(BOOKS);
this.updateResults(); this.updateResults();
}, },
loadCols: function(type) { loadCols: function(type) {
switch (type) { this.cols = ty(type).tab_cols;
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) { loadResults(resp) {
this.results = []; this.results = [];
@ -230,33 +235,6 @@ if (document.getElementById("index")) {
} else { } else {
this.page = 0; 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() { mounted: function() {
@ -269,17 +247,17 @@ if (document.getElementById("author")) {
new Vue({ new Vue({
el: '#author', el: '#author',
data: { data: {
tab: "books" tab: BOOKS
}, },
methods: { methods: {
showBooks: function() { showBooks: function() {
this.tab = "books"; this.tab = BOOKS;
}, },
showAuthors: function() { showAuthors: function() {
this.tab = "authors"; this.tab = AUTHORS;
}, },
showSeries: function() { showSeries: function() {
this.tab = "series"; this.tab = SERIES;
} }
} }
}); });
@ -303,8 +281,7 @@ if (document.getElementById("search")) {
}, },
methods: { methods: {
searchParams: function(url) { searchParams: function(url) {
var res = url; var res = url + '?perpage=' + this.perpage;
res += '?perpage=' + this.perpage;
for (var i=0; i<this.terms.length; i++) { for (var i=0; i<this.terms.length; i++) {
var t = this.terms[i]; var t = this.terms[i];
if (t.trim()) if (t.trim())
@ -317,24 +294,23 @@ if (document.getElementById("search")) {
this.authors = res.results; this.authors = res.results;
}, },
searchAuthors: function() { searchAuthors: function() {
this.sendQuery(this.searchParams('/authors/'), this.stdError, this.searchAuthorsSuccess); sendQuery(this.searchParams(url(AUTHORS)), stdError, this.searchAuthorsSuccess);
}, },
searchBooksSuccess: function(res) { searchBooksSuccess: function(res) {
this.booksCount = res.count; this.booksCount = res.count;
this.books = res.results; this.books = res.results;
}, },
searchBooks: function() { searchBooks: function() {
this.sendQuery(this.searchParams('/books/'), this.stdError, this.searchBooksSuccess); sendQuery(this.searchParams(url(BOOKS)), stdError, this.searchBooksSuccess);
}, },
searchSeriesSuccess: function(res) { searchSeriesSuccess: function(res) {
this.seriesCount = res.count; this.seriesCount = res.count;
this.series = res.results; this.series = res.results;
}, },
searchSeries: function() { searchSeries: function() {
this.sendQuery(this.searchParams('/series/'), this.stdError, this.searchSeriesSuccess); sendQuery(this.searchParams(url(SERIES)), stdError, this.searchSeriesSuccess);
}, },
searchAll: function() { searchAll: function() {
this.clear();
this.searchAuthors(); this.searchAuthors();
this.searchBooks(); this.searchBooks();
this.searchSeries(); this.searchSeries();
@ -350,22 +326,20 @@ if (document.getElementById("search")) {
searchFull: function() { searchFull: function() {
if (this.q) { if (this.q) {
this.terms = this.q.split(' '); this.terms = this.q.split(' ');
this.clear();
switch (this.which) { switch (this.which) {
case 'all': case AUTHORS:
this.searchAll();
break;
case 'authors':
this.clear();
this.searchAuthors(); this.searchAuthors();
break; break;
case 'books': case BOOKS:
this.clear();
this.searchBooks(); this.searchBooks();
break; break;
case 'series': case SERIES:
this.clear();
this.searchSeries(); this.searchSeries();
break; break;
default:
this.searchAll();
break;
} }
} }
return false; return false;
@ -373,6 +347,7 @@ if (document.getElementById("search")) {
searchUrl: function() { searchUrl: function() {
if (this.urlParams.q) { if (this.urlParams.q) {
this.terms = this.urlParams.q.split(' '); this.terms = this.urlParams.q.split(' ');
this.clear();
this.searchAll(); this.searchAll();
this.q = this.urlParams.q; this.q = this.urlParams.q;
} }
@ -385,34 +360,7 @@ if (document.getElementById("search")) {
query = window.location.search.substring(1); query = window.location.search.substring(1);
while (match = search.exec(query)) while (match = search.exec(query))
this.urlParams[decode(match[1])] = decode(match[2]); this.urlParams[decode(match[1])] = decode(match[2]);
}, }
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);
}
}, },
created: function() { created: function() {
this.urlParse(); this.urlParse();