Search books
This commit is contained in:
parent
f72ae08370
commit
fce863d8f7
4
Makefile
4
Makefile
@ -60,8 +60,8 @@ sinclude GNUmakefile.local
|
||||
DATABASE = metadata.db
|
||||
OBJS = db.o db_author.o db_book.o db_series.o json.o main.o
|
||||
|
||||
HTMLS = index.html book.html author.html series.html
|
||||
JSMINS = index.min.js book.min.js author.min.js series.min.js
|
||||
HTMLS = index.html book.html author.html series.html search.html
|
||||
JSMINS = index.min.js book.min.js author.min.js series.min.js search.min.js
|
||||
EXTJS = externals/vue.min.js
|
||||
CSS = externals/bootstrap.min.css
|
||||
FONTS = externals/fonts/*
|
||||
|
14
index.html
14
index.html
@ -11,6 +11,20 @@
|
||||
<link rel="prefetch" href="js/vue.min.js">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse" id="nav">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a href="#">Accueil</a></li>
|
||||
<li><a href="search.html">Recherche</a></li>
|
||||
<li><a href="#">A propos</a></li>
|
||||
</ul>
|
||||
<form class="navbar-form navbar-right" role="search" method="get" action="search.html">
|
||||
<div class="form-group">
|
||||
<input name="q" type="text" class="form-control" placeholder="Recherche">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container" id="app">
|
||||
<div class="jumbotron">
|
||||
<h1>Bouquins</h1>
|
||||
|
45
search.html
Normal file
45
search.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<title>Bouquins</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<link rel="preload" href="js/search.min.js" as="script">
|
||||
<link rel="preload" href="js/vue.min.js" as="script">
|
||||
<link rel="prefetch" href="js/search.min.js">
|
||||
<link rel="prefetch" href="js/vue.min.js">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse" id="nav">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="index.html">Accueil</a></li>
|
||||
<li class="active"><a href="search.html">Recherche</a></li>
|
||||
<li><a href="#">A propos</a></li>
|
||||
</ul>
|
||||
<form class="navbar-form navbar-right" role="search" method="get" action="search.html">
|
||||
<div class="form-group">
|
||||
<input name="q" type="text" class="form-control" placeholder="Recherche">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container" id="app">
|
||||
<div class="jumbotron">
|
||||
<h1>Recherche</h1>
|
||||
</div>
|
||||
<div v-if="books.length > 0">
|
||||
<h2>Livres</h2>
|
||||
<ul>
|
||||
<li v-for="book in books">
|
||||
<span class="glyphicon glyphicon-book"></span>
|
||||
<a :href="'book.html?id='+book.id">{{ book.title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/vue.min.js"></script>
|
||||
<script src="js/search.min.js"></script>
|
||||
</body>
|
||||
</html>
|
90
search.js
Normal file
90
search.js
Normal file
@ -0,0 +1,90 @@
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
urlParams: {},
|
||||
authors: [],
|
||||
series: [],
|
||||
books: []
|
||||
},
|
||||
methods: {
|
||||
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]);
|
||||
},
|
||||
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.send(null);
|
||||
},
|
||||
stdError: function(code, resp) {
|
||||
console.log('ERROR ' + code + ': ' + resp);
|
||||
},
|
||||
searchParams: function(url) {
|
||||
var res = url;
|
||||
var first = true;
|
||||
for (var i=0; i<this.terms.length; i++) {
|
||||
var t = this.terms[i];
|
||||
if (t.trim()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
res += '?';
|
||||
} else
|
||||
res += '&';
|
||||
res += 'term=' + encodeURIComponent(t.trim());
|
||||
}
|
||||
}
|
||||
console.log(res);
|
||||
return res;
|
||||
},
|
||||
searchBooksSuccess: function(res) {
|
||||
this.books = res;
|
||||
},
|
||||
searchBooks: function() {
|
||||
this.sendQuery(this.searchParams('cgi-bin/bouquins/books'), this.stdError, this.searchBooksSuccess);
|
||||
},
|
||||
searchAll: function() {
|
||||
this.authors = [];
|
||||
this.books = [];
|
||||
this.series = [];
|
||||
this.searchBooks();
|
||||
},
|
||||
searchUrl: function() {
|
||||
if (this.urlParams.q) {
|
||||
this.terms = this.urlParams.q.split(' ');
|
||||
this.searchAll();
|
||||
// TODO copy in form
|
||||
}
|
||||
}
|
||||
},
|
||||
created: function() {
|
||||
this.urlParse();
|
||||
},
|
||||
mounted: function() {
|
||||
this.searchUrl();
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user