<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
-
- <body onload="onSearch();">
+
+ <body onload="onSearch();">
<form onmouseenter="ToolTip.stopTooltipTimer();">
- <input id="search" onclick="onSearch();" type="button" value="Search"/>
+ <input id="search" onclick="onSearch();" type="button" value="Search"/>
<span class="term">Author: <input id="aut" type="text"/></span>
<span class="term">Title: <input id="tit" type="text"/></span>
<span class="term">Series: <input id="ser" type="text"/></span>
<span class="term">Language: <input id="lan" type="text"/></span>
<span class="term">Lists: <input id="lst" type="text"/></span>
+ <span class="term">
+ Sort:
+ <select id="srt">
+ <option value="aut">Author</option>
+ <option value="arr">New Arrivals</option>
+ <!-- <option value="pub">Publication</option> (not yet implemented)-->
+ <option value="tit">Title</option>
+ </select>
+ </span>
</form>
<div class="pager">
var my = {},
booksModel = undefined;
- const terms = ['aut', 'lan', 'lst', 'ser', 'tit'];
+ const textFields = ['aut', 'lan', 'ser', 'tit'];
+ const terms = textFields.concat(['lst', 'srt']);
// ==============
// Public methods
my.init = function(linkedBooksModel) {
booksModel = linkedBooksModel;
- for (var idx in terms) {
- addEnterListener(terms[idx]);
+ for (var idx in textFields) {
+ addEnterListener(textFields[idx]);
}
};
else {
url += '&';
}
- if (term === 'lst') {
- url += term + '=' + encodeURIComponent('' + value);
+ if (textFields.includes(term)) {
+ url += term + '=' + encodeURIComponent('%' + value + '%');
}
else {
- url += term + '=' + encodeURIComponent('%' + value + '%');
+ url += term + '=' + encodeURIComponent('' + value);
}
}
}
// ---------------------------------------------------------------------------
type Field string
const (
- Author, Language, List, Series, Title Field = "aut", "lan", "lst", "ser", "tit"
+ Author, Language, List, Series, Sort, Title Field = "aut", "lan", "lst", "ser", "srt", "tit"
)
func (f Field) String() string {
Text string
}
+// ---------------------------------------------------------------------------
+type SortOrder string
+const (
+ ByArrival, ByAuthor, ByPublication, ByTitle SortOrder = "arr", "aut", "pub", "tit"
+)
+
+func (so SortOrder) String() string {
+ return string(so)
+}
+
+// ---------------------------------------------------------------------------
var g_db *sql.DB = nil
var g_mutex = &sync.Mutex{}
// ============================================================================
+func conditional(count int) (string, int) {
+ if (count == 0) {
+ return "WHERE", 1
+ } else {
+ return "AND", (count + 1)
+ }
+}
+
func dbShutdown() {
if nil != g_db {
g_db.Close()
" INNER JOIN Authors a ON a.id=b.author" +
" LEFT OUTER JOIN Series s ON s.id=b.series" +
" LEFT OUTER JOIN Lists_Books lb ON b.id=lb.book" +
- " LEFT OUTER JOIN Lists l ON l.id=lb.list"
+ " LEFT OUTER JOIN Lists l ON l.id=lb.list" +
+ " "
args := make([]interface{}, 0)
-
- i := 0
+ conjunction := "WHERE"
+ count := 0
+ sort := ByAuthor
for _, criterion := range criteria {
- if 0 == i {
- query += " WHERE "
- } else {
- query += " AND "
- }
-
switch criterion.Attribute {
case Author:
- query += " UPPER(a.grouping) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+ conjunction, count = conditional(count)
+ query += conjunction + " UPPER(a.grouping) LIKE UPPER($" + strconv.Itoa(count) + ")"
args = append(args, strings.Replace(criterion.Text, " ", "", -1))
case Language:
- query += " UPPER(b.language) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+ conjunction, count = conditional(count)
+ query += conjunction + " UPPER(b.language) LIKE UPPER($" + strconv.Itoa(count) + ")"
args = append(args, criterion.Text)
case List:
+ conjunction, count = conditional(count)
codes := strings.Split(criterion.Text, ",")
- query += " UPPER(l.code) IN ("
+ query += conjunction + " UPPER(l.code) IN ("
for j, code := range codes {
if j > 0 {
query += ","
}
- query += "UPPER($" + strconv.Itoa(i + j + 1) + ")"
+ query += "UPPER($" + strconv.Itoa(count + j + 1) + ")"
args = append(args, code)
}
query += ")"
- i += len(codes) - 1
+ count += len(codes) - 1
case Series:
- query += " UPPER(s.descr) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+ conjunction, count = conditional(count)
+ query += conjunction + " UPPER(s.descr) LIKE UPPER($" + strconv.Itoa(count) + ")"
args = append(args, criterion.Text)
+ case Sort:
+ sort = SortOrder(criterion.Text)
case Title:
- query += " UPPER(b.title) LIKE UPPER($" + strconv.Itoa(i + 1) + ")"
+ conjunction, count = conditional(count)
+ query += conjunction + " UPPER(b.title) LIKE UPPER($" + strconv.Itoa(count) + ")"
args = append(args, criterion.Text)
default:
report("Error: unrecognized search field in queryIds(): " + criterion.Attribute.String(), nil)
return nil
}
-
- i++
}
- query += " ORDER BY a.grouping,s.descr,b.volume,b.title,b.path"
+ switch sort {
+ case ByArrival:
+ query += " ORDER BY b.arrived DESC,a.grouping,s.descr,b.volume,b.title,b.path"
+ case ByAuthor:
+ query += " ORDER BY a.grouping,s.descr,b.volume,b.title,b.path,b.arrived DESC"
+ case ByPublication:
+ report("Error: cannot sort by publication (not yet implemented)", nil)
+ return nil
+ case ByTitle:
+ query += " ORDER BY b.title,a.grouping,s.descr,b.volume,b.path,b.arrived DESC"
+ default:
+ report("Error: unrecognized sort order in queryIds(): " + sort.String(), nil)
+ return nil
+ }
res := []int{}