Search books

This commit is contained in:
Meutel 2017-01-14 17:38:40 +01:00
parent f72ae08370
commit fce863d8f7
4 changed files with 151 additions and 2 deletions

View File

@ -60,8 +60,8 @@ sinclude GNUmakefile.local
DATABASE = metadata.db DATABASE = metadata.db
OBJS = db.o db_author.o db_book.o db_series.o json.o main.o 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 HTMLS = index.html book.html author.html series.html search.html
JSMINS = index.min.js book.min.js author.min.js series.min.js JSMINS = index.min.js book.min.js author.min.js series.min.js search.min.js
EXTJS = externals/vue.min.js EXTJS = externals/vue.min.js
CSS = externals/bootstrap.min.css CSS = externals/bootstrap.min.css
FONTS = externals/fonts/* FONTS = externals/fonts/*

View File

@ -11,6 +11,20 @@
<link rel="prefetch" href="js/vue.min.js"> <link rel="prefetch" href="js/vue.min.js">
</head> </head>
<body> <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="container" id="app">
<div class="jumbotron"> <div class="jumbotron">
<h1>Bouquins</h1> <h1>Bouquins</h1>

45
search.html Normal file
View 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
View 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();
}
})