Skip to content

Commit 2cc7a98

Browse files
committed
showing collected books
1 parent 3c5cbc7 commit 2cc7a98

File tree

4 files changed

+237
-143
lines changed

4 files changed

+237
-143
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/Ex*
2-
/styleLinks.html
3-
/table.html
2+
/*.html
43
*.exe
54
*.db

WebApp/main.go

+55-10
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,29 @@ import (
44
"database/sql"
55
"encoding/json"
66
"encoding/xml"
7+
"fmt"
78
"io/ioutil"
89
"log"
910
"net/http"
1011
"net/url"
11-
"text/template"
1212

1313
_ "github.com/mattn/go-sqlite3"
1414
"github.com/urfave/negroni"
15+
"github.com/yosssi/ace"
1516
)
1617

1718
var port = ":8080"
1819

20+
type Book struct {
21+
PK string
22+
Title string
23+
Author string
24+
Classification string
25+
ID string
26+
}
27+
1928
type Page struct {
20-
Name string
21-
DBStatus bool
29+
Books []Book
2230
}
2331

2432
type SearchResult struct {
@@ -53,20 +61,44 @@ func verifyDBConnection(w http.ResponseWriter, r *http.Request, next http.Handle
5361
} else {
5462
next(w, r)
5563
}
56-
5764
}
5865

5966
func main() {
6067
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Llongfile)
6168

62-
templates := template.Must(template.ParseFiles("templates/index.html"))
69+
template, err := ace.Load("templates/index", "", nil)
70+
if err != nil {
71+
log.Println("func main :: error while loading template error = ", err.Error())
72+
return
73+
}
6374

64-
db, _ = sql.Open("sqlite3", "dev.db")
75+
db, err = sql.Open("sqlite3", "dev.db")
76+
if err != nil {
77+
log.Println("func main :: error while connecting to database error = ", err.Error())
78+
return
79+
}
6580

6681
mux := http.NewServeMux()
6782

6883
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
69-
err := templates.ExecuteTemplate(w, "index.html", nil)
84+
p := Page{
85+
Books: []Book{},
86+
}
87+
88+
rows, err := db.Query("select pk, Title, Author, Classification, ID from books")
89+
if err != nil {
90+
log.Println("func main :: error while fetching books from database")
91+
http.Error(w, err.Error(), http.StatusInternalServerError)
92+
return
93+
}
94+
95+
for rows.Next() {
96+
var b Book
97+
rows.Scan(&b.PK, &b.Title, &b.Author, &b.Classification, &b.ID)
98+
p.Books = append(p.Books, b)
99+
}
100+
101+
err = template.Execute(w, p)
70102
if err != nil {
71103
http.Error(w, err.Error(), http.StatusInternalServerError)
72104
return
@@ -106,18 +138,31 @@ func main() {
106138
return
107139
}
108140

109-
_, err = db.Exec("insert into books (pk, title, author, id, classification) values (?, ?, ?, ?, ?)",
141+
result, err := db.Exec("insert into books (pk, title, author, id, classification) values (?, ?, ?, ?, ?)",
110142
nil, book.BookData.Title, book.BookData.Author, book.BookData.ID, book.Classification.MostPopular)
111143
if err != nil {
112144
log.Println("/books/add qs = ", qs, " error while inserting into DB error = ", err.Error())
113145
http.Error(w, err.Error(), http.StatusInternalServerError)
114146
return
115147
}
116148

117-
log.Println("/books/add qs = ", qs, " successfully inserted into db")
149+
pk, err := result.LastInsertId()
150+
if err != nil {
151+
log.Println("/books/add qs = ", qs, " error while retriving last inserted id error = ", err.Error())
152+
http.Error(w, err.Error(), http.StatusInternalServerError)
153+
return
154+
}
155+
156+
b := Book{
157+
PK: fmt.Sprint(pk),
158+
Title: book.BookData.Title,
159+
Author: book.BookData.Author,
160+
Classification: book.Classification.MostPopular,
161+
ID: book.BookData.ID,
162+
}
118163

119164
encoder := json.NewEncoder(w)
120-
err = encoder.Encode(book)
165+
err = encoder.Encode(b)
121166
if err != nil {
122167
http.Error(w, err.Error(), http.StatusInternalServerError)
123168
return

WebApp/templates/index.ace

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
= doctype html
2+
html
3+
head
4+
title Search Books
5+
script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"
6+
script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"
7+
link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"
8+
link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"
9+
script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"
10+
script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"
11+
12+
body onload="onLoadFunction()"
13+
nav class="navbar navbar-dark bg-dark"
14+
a class="navbar-brand" href="#"
15+
span class="mr-sm-2"
16+
i class="fas fa-book-reader"
17+
text Search Books
18+
19+
ul class="list-group"
20+
li class="list-group-item"
21+
div class="container"
22+
div class="modal fade" id="addBookResultModal" role="dialog"
23+
div class="modal-dialog"
24+
div class="modal-content"
25+
div class="modal-header"
26+
h4 class="modal-title" id="addBookResultModalHead"
27+
button type="button" class="close" data-dismiss="modal" ×
28+
div class="modal-body"
29+
a id="addBookResultModalBody"
30+
div class="modal-footer"
31+
button type="button" class="btn btn-default" data-dismiss="modal" Close
32+
33+
li
34+
35+
li
36+
ul
37+
li
38+
button class="btn btn-dark" title="Search Form" type="button" onclick="toggleId('li-search-form')" Search for books
39+
40+
li
41+
42+
li
43+
ul
44+
li
45+
button class="btn btn-dark" title="Collection Form" type="button" onclick="toggleId('table-collection')" Collection of books
46+
47+
li
48+
49+
li
50+
ul
51+
li id="li-search-form" class="list-group-item"
52+
form id="search-form" class="form-inline" onsubmit="return false"
53+
input class="form-control mr-sm-2" type="search" name="queryString" placeholder="Search" aria-label="Search"
54+
button class="btn btn-outline-success" title="Search" type="submit" onclick="return submitSearch()" Search
55+
56+
li
57+
58+
li
59+
ul class="list-group"
60+
table class="table table-hover table-bordered table-dark" id="table-collection"
61+
thead
62+
tr
63+
th scope="col" #
64+
th scope="col" Title
65+
th scope="col" Author
66+
th scope="col" Classification
67+
th scope="col" ID
68+
tbody id="collection-results"
69+
{{range .Books}}
70+
tr
71+
td {{.PK}}
72+
td {{.Title}}
73+
td {{.Author}}
74+
td {{.Classification}}
75+
td {{.ID}}
76+
{{end}}
77+
78+
table class="table table-hover table-bordered table-dark" id="table-search"
79+
thead
80+
tr
81+
th scope="col" Title
82+
th scope="col" Author
83+
th scope="col" Year
84+
th scope="col" ID
85+
th scope="col" Action
86+
tbody id="search-results"
87+
88+
script type="text/javascript" src="js/helper.js"
89+
= javascript
90+
function showId(id){
91+
id = "#" + id;
92+
$(id).show();
93+
}
94+
95+
function hideId(id){
96+
id = "#" + id;
97+
$(id).hide();
98+
}
99+
100+
function toggleId(id){
101+
id = "#" + id;
102+
$(id).toggle();
103+
}
104+
105+
function onLoadFunction() {
106+
idsToHide = [
107+
"table-head-search",
108+
"table-head-collection",
109+
"li-search-form",
110+
"li-collection-form",
111+
"table-collection",
112+
"table-search"
113+
];
114+
idsToHide.forEach(function(id){
115+
hideId(id);
116+
});
117+
}
118+
119+
function submitSearch() {
120+
$.ajax({
121+
url: "/search",
122+
method: "POST",
123+
data: $("#search-form").serialize(),
124+
success: function (rawData) {
125+
hideId("table-collection");
126+
var searchResults = $("#search-results");
127+
searchResults.empty();
128+
129+
var parsed = JSON.parse(rawData);
130+
if (!parsed) return;
131+
132+
showId("table-search");
133+
134+
parsed.forEach(function (result) {
135+
var actionForm = `
136+
<form id="${'add-book-form' + result.ID}" class="form-inline" onsubmit="return false">
137+
<input class="form-control mr-sm-2" type="text" name="id" value="${result.ID}" hidden>
138+
<button class="btn btn-outline-success" title="Add this book" type="submit" onclick="return addBook(${result.ID})">
139+
<i class="fas fa-plus-square"></i>
140+
</button>
141+
</form>
142+
`
143+
var row = $("<tr><td>" + result.Title + "</td><td>" + result.Author + "</td><td>" + result.Year + "</td><td>" + result.ID + "</td><td>" + actionForm + "</td></tr>");
144+
searchResults.append(row);
145+
});
146+
}
147+
});
148+
return false;
149+
}
150+
151+
function addBook(id) {
152+
$.ajax({
153+
url: "/books/add",
154+
method: "POST",
155+
data: $("#add-book-form" + id).serialize(),
156+
success: function (rawData) {
157+
hideId("table-search");
158+
if(rawData){
159+
var parsed = JSON.parse(rawData);
160+
if (parsed && parsed.Title) {
161+
var collectionResults = $("#collection-results");
162+
var row = $("<tr><td>" + parsed.PK + "</td><td>" + parsed.Title + "</td><td>" + parsed.Author + "</td><td>" + parsed.Classification + "</td><td>" + parsed.ID + "</td></tr>");
163+
collectionResults.append(row);
164+
$('#addBookResultModalHead').html(`Success <i class="far fa-smile"></i>`);
165+
$('#addBookResultModalBody').text(`${parsed.Title} has been added to database`);
166+
$('#addBookResultModal').modal('show');
167+
showId("table-collection");
168+
return false;
169+
}
170+
}
171+
$('#addBookResultModalHead').html(`Sorry <i class="far fa-sad-tear"></i>`);
172+
$('#addBookResultModalBody').text(`Failed to add the book you selected. It is not popular. Please try again...`);
173+
$('#addBookResultModal').modal('show');
174+
showId("table-search");
175+
}
176+
});
177+
return false;
178+
}
179+
180+
181+

0 commit comments

Comments
 (0)