Add slider to enable distant paging.
[quanweb.git] / app / lib.js
1 // QuanLib:  eBook Library
2 // (C) 2017 by Christian Jaekl (cejaekl@yahoo.com)
3
4 g_state = {
5   cache: {},
6   count: 0,
7   first: 0,
8   ids: [],
9   last: (-1),
10   pageSize: 9
11 }
12
13 function adjustPos(setting) {
14   var value = parseInt(setting)
15   
16   if (g_state.first === value) {
17     // No change
18     return;
19   }
20
21   var maxFirst = g_state.count - g_state.pageSize;
22
23   if (value < 0) {
24     g_state.first = 0;
25   } else if (value > maxFirst) {
26     g_state.first = maxFirst;
27   } else {
28     g_state.first = value;
29   }
30
31   g_state.last = g_state.first + g_state.pageSize - 1;
32   if (g_state.last >= g_state.count) {
33     g_state.last = g_state.count - 1;
34   }
35
36   refreshData();
37 }
38
39 function constructSearchUrl() {
40   var url = window.location.protocol + '//' + window.location.host + '/search/';
41
42   var firstTime = true;
43   var terms = ['aut', 'tit', 'ser'];
44
45   for (idx in terms) {
46     var term = terms[idx];
47     var elem = document.getElementById(term);
48     if (null === elem) {
49       console.log('Error:  could not find form element for search term "' + term + '".');
50       continue;
51     }
52     
53     var value = elem.value;
54     if (value.length > 0) {
55       if (firstTime) {
56         url += '?';
57         firstTime = false;
58       }
59       else {
60         url += '&';
61       }
62       url += term + '=' + encodeURIComponent('%' + value + '%');
63     }
64   }
65
66   return url;
67 }
68
69 function onNext() {
70   if (g_state.last < (g_state.count - 1)) {
71     adjustPos(g_state.first + g_state.pageSize);
72   }
73 }
74
75 function onPrev() {
76   if (g_state.first > 0) {
77     adjustPos(g_state.first - g_state.pageSize);
78   }
79 }
80
81 function onSlide(value) {
82   adjustPos(value);
83 }
84
85 function onSearch() {
86   console.log('onSearch()');
87
88   var url = constructSearchUrl();
89
90   report('Loading data from server, please wait...')
91   console.log('Fetching:  "' + url + '"...')
92
93   fetch(url, {method:'GET', cache:'default'})
94   .then(response => response.json())
95   .then((jsonValue) => {
96     console.log('JSON response:  ', jsonValue);
97     g_state.ids = jsonValue
98     g_state.count = g_state.ids.length;
99     g_state.first = (-1)
100
101     var elem = document.getElementById('slider');
102     elem.max = g_state.count;
103     elem.value = '0'
104
105     adjustPos(0);
106   })
107   .catch(err => { 
108     var msg = 'Error fetching JSON from URL:  ' + url + ': ' + err + ':' + err.stack;
109     console.log(msg);
110     report(msg);
111   });
112 }
113
114 function refreshData() {
115   report('Loading details for books ' + g_state.first + ' through ' + g_state.last + ', please wait...');
116
117   var i;
118   var url = '/info/?ids=';
119   for (i = g_state.first; i <= g_state.last; ++i) {
120     if (i > g_state.first) {
121       url += ',';
122     }
123     url += g_state.ids[i];
124   }
125
126   fetch(url, {method:'GET', cache:'default'})
127   .then(response => response.json())
128   .then((jsonValue) => {
129     console.log('JSON response for info:  ', jsonValue);
130     report('');
131     g_state.cache = jsonValue;
132     refreshLayout();
133   })
134   .catch(err => {
135     var msg = 'Error fetching book details via URL:  ' + url + ': ' + err;
136     console.log(msg, err.stack);
137     report(msg);
138   });
139 }
140
141 function refreshLayout() {
142   var i;
143   var html = '';
144   var limit = g_state.last - g_state.first;
145   for (i = 0; i <= limit; ++i) {
146     var book = g_state.cache[i];
147     html += bookHtml(book);
148   }
149
150   document.getElementById('books').innerHTML = html;
151   document.getElementById('first').innerHTML = (g_state.first + 1);
152   document.getElementById('last').innerHTML = (g_state.last + 1);
153   document.getElementById('count').innerHTML = g_state.count;
154 }
155
156 function report(message) {
157   document.getElementById('books').innerHTML = message;
158 }
159
160 function bookHtml(book) {
161   console.log('bookHtml(): ', book);
162   var result = '<div class="book">'
163              +   '<table>'
164              +     '<tr>'
165              +       '<td><a href="/book/' + book.Id + '">';
166   if (0 == book.CoverId) {
167     result  +=          '(No cover available)'
168   } else {
169     result  +=          '<img class="cover-thumb" src="/download/' + book.CoverId + '"/>'
170   }
171   result    +=       '</a></td>'
172              +       '<td>'
173              +         '<p><b>' + book.Title + '</b></p>'
174              +         '<p>'
175              +           '<i>' + book.AuthorReading + '</i>';
176   if (typeof(book.SeriesName) !== 'undefined' && book.SeriesName.length > 0) {
177     result  +=           '<br/><i>' + book.SeriesName + ' ' + book.Volume + '</i>';
178   }
179   result    +=         '</p>'
180              +       '</td>'
181              +     '</tr>'
182              +   '</table>'
183              + '</div>';
184   return result;
185 }
186