Template for Pager
[mkws-moved-to-github.git] / src / mkws-widget-main.js
1 // Functions follow for promoting the regular widget object into
2 // widgets of specific types. These could be moved into their own
3 // source files.
4
5
6 mkws.registerWidgetType('Targets', function() {
7   if (!this.config.show_switch) return;
8   var that = this;
9
10   this.node.html('No information available yet.');
11   this.node.css("display", "none");
12
13   this.team.queue("targets").subscribe(function(data) {
14     // There is a bug in pz2.js wherein it makes each data object an array but
15     // simply assigns properties to it.
16     // TODO: remove this when PAZ-946 is addressed.
17     var cleandata = [];
18     for (var i = 0; i < data.length; i++) {
19       var cur = {};
20       cur.id = data[i].id;
21       cur.hits = data[i].hits;
22       cur.diagnostic = data[i].diagnostic;
23       cur.records = data[i].records;
24       cur.state = data[i].state;
25       cleandata.push(cur);
26     }
27
28     var template = that.team.loadTemplate(that.config.template || "Targets");
29     that.node.html(template({data: cleandata}));
30   });
31 });
32
33
34 mkws.registerWidgetType('Stat', function() {
35   var that = this;
36   this.team.queue("stat").subscribe(function(data) {
37     var template = that.team.loadTemplate(that.config.template || "Stat");
38     that.node.html(template(data));
39   });
40 });
41
42
43 mkws.registerWidgetType('Pager', function() {
44   var that = this;
45   var M = mkws.M;
46
47   this.team.queue("pager").subscribe(function(data) {
48     var teamName = that.team.name();
49     var output = {};
50     output.first = data.start + 1;
51     output.last = data.start + data.num;
52     output.count = data.merged;
53     output.found = data.total;
54
55     //client indexes pages from 1 but pz2 from 0
56     var onsides = 6;
57     var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
58     var currentPage = that.team.currentPage();
59
60     var firstClkbl = (currentPage - onsides > 0)
61       ? currentPage - onsides
62       : 1;
63     var lastClkbl = firstClkbl + 2*onsides < pages
64       ? firstClkbl + 2*onsides
65       : pages;
66
67     if (firstClkbl > 1) output.morePrev = true;
68     if (lastClkbl < pages) output.moreNext = true;
69
70     if (currentPage > 1) output.prevClick = "mkws.pagerPrev(\'" + teamName + "\');";
71
72     output.pages = [];
73     for(var i = firstClkbl; i <= lastClkbl; i++) {
74       var o = {};
75       o.number = i;
76       if (i !== currentPage) {
77         o.click = "mkws.showPage(\'" + teamName + "\', " + i + ");";
78       }
79       output.pages.push(o);
80     }
81
82     if (pages - currentPage > 0) output.nextClick = "mkws.pagerNext(\'" + teamName + "\')";
83
84     var template = that.team.loadTemplate(that.config.template || "Pager");
85     that.node.html(template(output));
86   });
87 });
88
89
90 mkws.registerWidgetType('Records', function() {
91   var that = this;
92   var team = this.team;
93
94   this.team.queue("records").subscribe(function(data) {
95     for (var i = 0; i < data.hits.length; i++) {
96       var hit = data.hits[i];
97       that.team.queue("record").publish(hit);
98       hit.detailLinkId = team.recordElementId(hit.recid[0]);
99       hit.detailClick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;"
100       hit.containerClass = "mkwsSummary mkwsTeam_" + team.name();
101       hit.containerClass += " " + hit.detailLinkId;
102       // ### At some point, we may be able to move the
103       // m_currentRecordId and m_currentRecordData members
104       // from the team object into this widget.
105       if (hit.recid == team.currentRecordId()) {
106         if (team.currentRecordData()) {
107           hit.renderedDetails = team.renderDetails(team.currentRecordData());
108           console.log(hit.renderedDetails); 
109         } 
110       }
111     }
112     var template = team.loadTemplate(that.config.template || "Records");
113     var targs = $.extend({}, {"hits": data.hits}, that.config.template_vars);
114     that.node.html(template(targs));
115   });
116
117   that.autosearch();
118 });
119
120
121 mkws.registerWidgetType('Navi', function() {
122   var that = this;
123   var teamName = this.team.name();
124   var M = mkws.M;
125
126   this.team.queue("navi").subscribe(function() {
127     var filters = that.team.filters();
128     var text = "";
129
130     filters.visitTargets(function(id, name) {
131       if (text) text += " | ";
132       text += M('source') + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitTarget(\'' + teamName +
133         "', '" + id + "'" + ');return false;">' + name + '</a>';
134     });
135
136     filters.visitFields(function(field, value) {
137       if (text) text += " | ";
138       text += M(field) + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitQuery(\'' + teamName +
139         "', '" + field + "', '" + value + "'" +
140         ');return false;">' + value + '</a>';
141     });
142
143     that.node.html(text);
144   });
145 });
146
147
148 // It seems this and the Perpage widget doen't need to subscribe to
149 // anything, since they produce events rather than consuming them.
150 //
151 mkws.registerWidgetType('Sort', function() {
152   var that = this;
153
154   this.node.change(function() {
155     that.team.set_sortOrder(that.node.val());
156     if (that.team.submitted()) {
157       that.team.reShow();
158     }
159     return false;
160   });
161 });
162
163
164 mkws.registerWidgetType('Perpage', function() {
165   var that = this;
166
167   this.node.change(function() {
168     that.team.set_perpage(that.node.val());
169     if (that.team.submitted()) {
170       that.team.reShow();
171     }
172     return false;
173   });
174 });
175
176
177 mkws.registerWidgetType('Done', function() {
178   var that = this;
179
180   this.team.queue("complete").subscribe(function(n) {
181     that.node.html("Search complete: found " + n + " records");
182   });
183 });
184
185
186 mkws.registerWidgetType('Switch', function() {
187   if (!this.config.show_switch) return;
188   var tname = this.team.name();
189   this.node.html('\
190 <a href="#" onclick="mkws.switchView(\'' + tname + '\', \'records\')">Records</a><span> \
191 | \
192 </span><a href="#" onclick="mkws.switchView(\'' + tname + '\', \'targets\')">Targets</a>');
193   this.hideWhenNarrow();
194 });
195
196
197 mkws.registerWidgetType('Search', function() {
198   var tname = this.team.name();
199   var M = mkws.M;
200
201   this.node.html('\
202 <form name="mkwsSearchForm" class="mkwsSearchForm mkwsTeam_' + tname + '" action="" >\
203   <input class="mkwsQuery mkwsTeam_' + tname + '" type="text" size="' + this.config.query_width + '" />\
204   <input class="mkwsButton mkwsTeam_' + tname + '" type="submit" value="' + M('Search') + '" />\
205 </form>');
206 });
207
208
209 mkws.registerWidgetType('SearchForm', function() {
210   var team = this.team;
211   this.node.submit(function() {
212     var val = team.widget('Query').value();
213     team.newSearch(val);
214     return false;
215   });
216 });
217
218
219 mkws.registerWidgetType('Results', function() {
220   var tname = this.team.name();
221
222   this.node.html('\
223 <table width="100%" border="0" cellpadding="6" cellspacing="0">\
224   <tr>\
225     <td class="mkwsTermlists-Container-wide mkwsTeam_' + tname + '" width="250" valign="top">\
226       <div class="mkwsTermlists mkwsTeam_' + tname + '"></div>\
227     </td>\
228     <td class="mkwsMOTDContainer mkwsTeam_' + tname + '" valign="top">\
229       <div class="mkwsRanking mkwsTeam_' + tname + '"></div>\
230       <div class="mkwsPager mkwsTeam_' + tname + '"></div>\
231       <div class="mkwsNavi mkwsTeam_' + tname + '"></div>\
232       <div class="mkwsRecords mkwsTeam_' + tname + '"></div>\
233     </td>\
234   </tr>\
235   <tr>\
236     <td colspan="2">\
237       <div class="mkwsTermlists-Container-narrow mkwsTeam_' + tname + '"></div>\
238     </td>\
239   </tr>\
240 </table>');
241
242   this.autosearch();
243 });
244
245
246 mkws.registerWidgetType('Ranking', function() {
247   var tname = this.team.name();
248   var that = this;
249   var M = mkws.M;
250
251   var s = '<form>';
252   if (this.config.show_sort) {
253     s +=  M('Sort by') + ' ' + mkwsHtmlSort() + ' ';
254   }
255   if (this.config.show_perpage) {
256     s += M('and show') + ' ' + mkwsHtmlPerpage() + ' ' + M('per page') + '.';
257   }
258   s += '</form>';
259
260   this.node.html(s);
261
262
263   function mkwsHtmlSort() {
264     var order = that.team.sortOrder();
265
266     that.log("making sort HTML, sortOrder = '" + order + "'");
267     var sort_html = '<select class="mkwsSort mkwsTeam_' + tname + '">';
268
269     for(var i = 0; i < that.config.sort_options.length; i++) {
270       var opt = that.config.sort_options[i];
271       var key = opt[0];
272       var val = opt.length == 1 ? opt[0] : opt[1];
273
274       sort_html += '<option value="' + key + '"';
275       if (order == key || order == val) {
276         sort_html += ' selected="selected"';
277       }
278       sort_html += '>' + M(val) + '</option>';
279     }
280     sort_html += '</select>';
281
282     return sort_html;
283   }
284
285   function mkwsHtmlPerpage() {
286     var perpage = that.team.perpage();
287
288     that.log("making perpage HTML, perpage = " + perpage);
289     var perpage_html = '<select class="mkwsPerpage mkwsTeam_' + tname + '">';
290
291     for(var i = 0; i < that.config.perpage_options.length; i++) {
292       var key = that.config.perpage_options[i];
293
294       perpage_html += '<option value="' + key + '"';
295       if (key == perpage) {
296         perpage_html += ' selected="selected"';
297       }
298       perpage_html += '>' + key + '</option>';
299     }
300     perpage_html += '</select>';
301
302     return perpage_html;
303   }
304 });
305
306
307 mkws.registerWidgetType('Lang', function() {
308   // dynamic URL or static page? /path/foo?query=test
309   /* create locale language menu */
310   if (!this.config.show_lang) return;
311
312   var lang_default = "en";
313   var lang = this.config.lang || lang_default;
314   var list = [];
315
316   /* display a list of configured languages, or all */
317   var lang_options = this.config.lang_options || [];
318   var toBeIncluded = {};
319   for (var i = 0; i < lang_options.length; i++) {
320     toBeIncluded[lang_options[i]] = true;
321   }
322
323   for (var k in mkws.locale_lang) {
324     if (toBeIncluded[k] || lang_options.length == 0)
325       list.push(k);
326   }
327
328   // add english link
329   if (lang_options.length == 0 || toBeIncluded[lang_default])
330     list.push(lang_default);
331
332   this.log("language menu: " + list.join(", "));
333
334   /* the HTML part */
335   var data = "";
336   for (var i = 0; i < list.length; i++) {
337     var l = list[i];
338     if (data)
339       data += ' | ';
340
341     if (lang == l) {
342       data += ' <span>' + l + '</span> ';
343     } else {
344       data += ' <a href="' + lang_url(l) + '">' + l + '</a> '
345     }
346   }
347
348   this.node.html(data);
349   this.hideWhenNarrow();
350
351
352   // set or re-set "lang" URL parameter
353   function lang_url(lang) {
354     var query = location.search;
355     // no query parameters? done
356     if (!query) {
357       return "?lang=" + lang;
358     }
359
360     // parameter does not exist
361     if (!query.match(/[\?&]lang=/)) {
362       return query + "&lang=" + lang;
363     }
364
365     // replace existing parameter
366     query = query.replace(/\?lang=([^&#;]*)/, "?lang=" + lang);
367     query = query.replace(/\&lang=([^&#;]*)/, "&lang=" + lang);
368     return query;
369   }
370 });
371
372
373 mkws.registerWidgetType('MOTD', function() {
374   var container = this.team.widget('MOTDContainer');
375   if (container) {
376     // Move the MOTD from the provided element down into the container
377     this.node.appendTo(container.node);
378   }
379 });
380
381
382 // This widget has no functionality of its own, but its configuration
383 // is copied up into its team, allowing it to affect other widgets in
384 // the team.
385 //
386 mkws.registerWidgetType('Config', function() {
387   var c = this.config;
388   for (var name in c) {
389     if (c.hasOwnProperty(name)) {
390       this.team.config[name] = c[name];
391       this.log(this + " copied property " + name + "='" + c[name] + "' up to team");
392     }
393   }
394 });
395
396
397 mkws.registerWidgetType('Progress', function() {
398   var that = this;
399
400   this.node.hide();
401   this.team.queue("stat").subscribe(function(data) {
402     var s = '<span class="mkwsDone">';
403     for (var i = 0; i < data.clients; i++) {
404       if (i == data.clients - data.activeclients) {
405         s += '</span>';
406         s += '<span class="mkwsWaiting">';
407       }
408       s += '&#x2588;';
409     }
410     s += '</span>';
411     that.node.html(s);
412     that.node.show();
413   });
414 });
415
416
417 // Some elements have mkws* classes that makes them appear as widgets
418 // -- for example, because we want to style them using CSS -- but have
419 // no actual functionality. We register these to prevent ignorable
420 // warnings when they occur.
421
422 mkws.registerWidgetType('Query', function() {});
423 mkws.registerWidgetType('MOTDContainer', function() {});
424 mkws.registerWidgetType('Button', function() {});
425
426