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