Use registerWidgetType from MKWS code.
[mkws-moved-to-github.git] / src / mkws-widgets.js
1 // Factory function for widget objects.
2 function widget($, team, type, node) {
3     var that = {
4         team: team,
5         type: type,
6         node: node
7     };
8
9     mkws.registerWidgetType('Targets', promoteTargets);
10     mkws.registerWidgetType('Stat', promoteStat);
11     mkws.registerWidgetType('Termlists', promoteTermlists);
12     mkws.registerWidgetType('Pager', promotePager);
13     mkws.registerWidgetType('Records', promoteRecords);
14     mkws.registerWidgetType('Navi', promoteNavi);
15     mkws.registerWidgetType('Sort', promoteSort);
16     mkws.registerWidgetType('Perpage', promotePerpage);
17
18     var M = mkws.M;
19
20     var promote = mkws.promotionFunction(type);
21     if (promote) {
22         promote();
23         log("made " + type + " widget(node=" + node + ")");
24     } else {
25         log("made UNENCAPSULATED widget(type=" + type + ", node=" + node + ")");
26     }
27
28     return that;
29
30
31     function log(s) {
32         team.log(s);
33     }
34
35     // Functions follow for promoting the regular widget object into
36     // widgets of specific types. These could be moved outside of the
37     // widget object, or even into their own source files.
38
39     function promoteTargets() {
40         team.queue("targets").subscribe(function(data) {
41             var table ='<table><thead><tr>' +
42                 '<td>' + M('Target ID') + '</td>' +
43                 '<td>' + M('Hits') + '</td>' +
44                 '<td>' + M('Diags') + '</td>' +
45                 '<td>' + M('Records') + '</td>' +
46                 '<td>' + M('State') + '</td>' +
47                 '</tr></thead><tbody>';
48
49             for (var i = 0; i < data.length; i++) {
50                 table += "<tr><td>" + data[i].id +
51                     "</td><td>" + data[i].hits +
52                     "</td><td>" + data[i].diagnostic +
53                     "</td><td>" + data[i].records +
54                     "</td><td>" + data[i].state + "</td></tr>";
55             }
56             
57             table += '</tbody></table>';
58             var subnode = $(node).children('.mkwsBytarget');
59             subnode.html(table);
60         });
61     }
62
63
64     function promoteStat() {
65         team.queue("stat").subscribe(function(data) {
66             if (node.length === 0)  alert("huh?!");
67
68             $(node).html('<span class="head">' + M('Status info') + '</span>' +
69                 ' -- ' +
70                 '<span class="clients">' + M('Active clients') + ': ' + data.activeclients + '/' + data.clients + '</span>' +
71                 ' -- ' +
72                 '<span class="records">' + M('Retrieved records') + ': ' + data.records + '/' + data.hits + '</span>');
73         });
74     }
75
76
77     function promoteTermlists() {
78         team.queue("termlists").subscribe(function(data) {
79             if (!node) {
80                 alert("termlists event when there are no termlists");
81                 return;
82             }
83
84             // no facets: this should never happen
85             if (!mkws_config.facets || mkws_config.facets.length == 0) {
86                 alert("onTerm called even though we have no facets: " + $.toJSON(data));
87                 $(node).hide();
88                 return;
89             }
90
91             // display if we first got results
92             $(node).show();
93
94             var acc = [];
95             acc.push('<div class="title">' + M('Termlists') + '</div>');
96             var facets = mkws_config.facets;
97
98             for (var i = 0; i < facets.length; i++) {
99                 if (facets[i] == "xtargets") {
100                     addSingleFacet(acc, "Sources",  data.xtargets, 16, null);
101                 } else if (facets[i] == "subject") {
102                     addSingleFacet(acc, "Subjects", data.subject,  10, "subject");
103                 } else if (facets[i] == "author") {
104                     addSingleFacet(acc, "Authors",  data.author,   10, "author");
105                 } else {
106                     alert("bad facet configuration: '" + facets[i] + "'");
107                 }
108             }
109
110             $(node).html(acc.join(''));
111
112             function addSingleFacet(acc, caption, data, max, pzIndex) {
113                 acc.push('<div class="facet mkwsFacet' + caption + ' mkwsTeam_' + team.name() + '">');
114                 acc.push('<div class="termtitle">' + M(caption) + '</div>');
115                 for (var i = 0; i < data.length && i < max; i++) {
116                     acc.push('<div class="term">');
117                     acc.push('<a href="#" ');
118                     var action = '';
119                     if (!pzIndex) {
120                         // Special case: target selection
121                         acc.push('target_id='+data[i].id+' ');
122                         if (!team.targetFiltered(data[i].id)) {
123                             action = 'mkws.limitTarget(\'' + team.name() + '\', this.getAttribute(\'target_id\'),this.firstChild.nodeValue)';
124                         }
125                     } else {
126                         action = 'mkws.limitQuery(\'' + team.name() + '\', \'' + pzIndex + '\', this.firstChild.nodeValue)';
127                     }
128                     acc.push('onclick="' + action + ';return false;">' + data[i].name + '</a>'
129                              + ' <span>' + data[i].freq + '</span>');
130                     acc.push('</div>');
131                 }
132                 acc.push('</div>');
133             }
134         });
135     }
136
137
138     function promotePager() {
139         team.queue("pager").subscribe(function(data) {
140             $(node).html(drawPager(data))
141
142             function drawPager(data) {
143                 var s = '<div style="float: right">' + M('Displaying') + ': '
144                     + (data.start + 1) + ' ' + M('to') + ' ' + (data.start + data.num) +
145                     ' ' + M('of') + ' ' + data.merged + ' (' + M('found') + ': '
146                     + data.total + ')</div>';
147
148                 //client indexes pages from 1 but pz2 from 0
149                 var onsides = 6;
150                 var pages = Math.ceil(team.totalRecordCount() / team.perpage());
151                 var currentPage = team.currentPage();
152
153                 var firstClkbl = (currentPage - onsides > 0)
154                     ? currentPage - onsides
155                     : 1;
156
157                 var lastClkbl = firstClkbl + 2*onsides < pages
158                     ? firstClkbl + 2*onsides
159                     : pages;
160
161                 var prev = '<span class="mkwsPrev">&#60;&#60; ' + M('Prev') + '</span><b> | </b>';
162                 if (currentPage > 1)
163                     prev = '<a href="#" class="mkwsPrev" onclick="mkws.pagerPrev(\'' + team.name() + '\');">'
164                     +'&#60;&#60; ' + M('Prev') + '</a><b> | </b>';
165
166                 var middle = '';
167                 for(var i = firstClkbl; i <= lastClkbl; i++) {
168                     var numLabel = i;
169                     if(i == currentPage)
170                         numLabel = '<b>' + i + '</b>';
171
172                     middle += '<a href="#" onclick="mkws.showPage(\'' + team.name() + '\', ' + i + ')"> '
173                         + numLabel + ' </a>';
174                 }
175
176                 var next = '<b> | </b><span class="mkwsNext">' + M('Next') + ' &#62;&#62;</span>';
177                 if (pages - currentPage > 0)
178                     next = '<b> | </b><a href="#" class="mkwsNext" onclick="mkws.pagerNext(\'' + team.name() + '\')">'
179                     + M('Next') + ' &#62;&#62;</a>';
180
181                 var predots = '';
182                 if (firstClkbl > 1)
183                     predots = '...';
184
185                 var postdots = '';
186                 if (lastClkbl < pages)
187                     postdots = '...';
188
189                 s += '<div style="float: clear">'
190                     + prev + predots + middle + postdots + next + '</div>';
191
192                 return s;
193             }
194         });
195     }                        
196
197
198     function promoteRecords() {
199         team.queue("records").subscribe(function(data) {
200             var html = [];
201             for (var i = 0; i < data.hits.length; i++) {
202                 var hit = data.hits[i];
203                 var divId = team.recordElementId(hit.recid[0]);
204                 html.push('<div class="record mkwsTeam_' + team.name() + ' ' + divId + '">', renderSummary(hit), '</div>');
205                 // ### At some point, we may be able to move the
206                 // m_currentRecordId and m_currentRecordData members
207                 // from the team object into this widget.
208                 if (hit.recid == team.currentRecordId()) {
209                     if (team.currentRecordData())
210                         html.push(team.renderDetails(team.currentRecordData()));
211                 }
212             }
213             $(node).html(html.join(''));
214
215             function renderSummary(hit)
216             {
217                 var template = team.loadTemplate("Summary");
218                 hit._id = team.recordElementId(hit.recid[0]);
219                 hit._onclick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;"
220                 return template(hit);
221             }
222         });
223     }
224
225
226     function promoteNavi() {
227         team.queue("navi").subscribe(function() {
228             var filters = team.filters();
229             var text = "";
230
231             for (var i in filters) {
232                 if (text) {
233                     text += " | ";
234                 }
235                 var filter = filters[i];
236                 if (filter.id) {
237                     text += M('source') + ': <a class="crossout" href="#" onclick="mkws.delimitTarget(\'' + team.name() +
238                         "', '" + filter.id + "'" + ');return false;">' + filter.name + '</a>';
239                 } else {
240                     text += M(filter.field) + ': <a class="crossout" href="#" onclick="mkws.delimitQuery(\'' + team.name() +
241                         "', '" + filter.field + "', '" + filter.value + "'" +
242                         ');return false;">' + filter.value + '</a>';
243                 }
244             }
245
246             $(node).html(text);
247         });
248     }
249
250
251     function promoteSort() {
252         // It seems this and the Perpage widget doen't need to
253         // subscribe to anything, since they produce events rather
254         // than consuming them.
255         $(node).change(function () {
256             team.set_sortOrder($(node).val());
257             if (team.submitted()) {
258                 team.resetPage();
259                 team.reShow();
260             }
261             return false;
262         });
263     }
264
265
266     function promotePerpage() {
267         $(node).change(function() {
268             team.set_perpage($(node).val());
269             if (team.submitted()) {
270                 team.resetPage();
271                 team.reShow();
272             }
273             return false;
274         });
275     }
276 }