abca5b81c8de54f4bd5da3ebc9c1c0fa17c39c1f
[mkdru-moved-to-drupal.org.git] / mkdru.client.js
1 // Set up namespace and some state.
2 var mkdru = {
3   // Settings to pass to pz2.js
4   usesessions: Drupal.settings.mkdru.use_sessions === '1',
5   //   showResponseType: 'json',
6   // Variables
7   submitted: false,
8   pz2: null,
9   totalRec: 0,
10   pagerRange: 6,
11   sourceMax: Drupal.settings.mkdru.source_max,
12   subjectMax: Drupal.settings.mkdru.subject_max,
13   authorMax: Drupal.settings.mkdru.author_max,
14   pazpar2Path: Drupal.settings.mkdru.pz2_path,
15   // State
16   defaultState: {
17     page: 1,
18     perpage: 20,
19     sort: 'relevance',
20     filter: null,
21     query:null,
22     recid:null,
23   },
24   state: {}
25 };
26
27
28
29 // So we can use jQuery BBQ with Drupal 6 and its 1.2.6 jQuery
30 if (!$.isArray) $.isArray = function(obj) {
31   return Object.prototype.toString.call(obj) === "[object Array]";
32 },
33
34
35
36 // pz2.js event handlers:
37 mkdru.pz2Init = function () {
38   if (mkdru.state.recid) {
39     mkdru.pz2.record(mkdru.state.recid);
40   } else if (mkdru.state.query) {
41     mkdru.triggerSearch();
42   }
43   //mkdru.pz2.stat();
44   //mkdru.pz2.bytarget();
45 };
46
47 mkdru.pz2Show = function (data) {
48   mkdru.totalRec = data.merged;
49   $('.mkdru-pager').html(mkdru.generatePager());
50   var countsHtml = Drupal.t('Displaying: ') + (data.start + 1) + 
51     Drupal.t(' to ') + (data.start + data.num) + Drupal.t(' of ')
52     + data.merged + Drupal.t(' (found: ') + data.total + ')';
53   $('.mkdru-counts').html(countsHtml);
54
55   var html = "";
56   for (var i = 0; i < data.hits.length; i++) {
57     html += Drupal.theme('mkdruResult', data.hits[i], 
58       i + 1 + mkdru.state.perpage * (mkdru.state.page - 1),
59       "#" + $.param.fragment($.param.fragment(
60         window.location.href, {recid: data.hits[i].recid})) + "\n"
61     );
62   }
63   $('.mkdru-result-list').html(html);
64   $('.mkdru-results').show();
65 };
66
67 mkdru.pz2Status = function (data) {
68 };
69
70 mkdru.pz2Term = function (data) {
71   var html = "";
72   for (var i = 0; i < data.xtargets.length && i < mkdru.sourceMax; i++ ) {
73     html += Drupal.theme('mkdruTerm', data.xtargets[i].name, data.xtargets[i].freq, 
74                           'mkdru-facet-source', data.xtargets[i].id);
75   }
76   $('.mkdru-facet-sources').html(html);
77
78   html = "";
79   for (var i = 0; i < data.subject.length && i < mkdru.subjectMax; i++ ) {
80     html += Drupal.theme('mkdruTerm', data.subject[i].name, data.subject[i].freq, 
81                           'mkdru-facet-subject', data.subject[i].id);
82   }
83   $('.mkdru-facet-subjects').html(html);
84
85   html = "";
86   for (var i = 0; i < data.author.length && i < mkdru.authorMax; i++ ) {
87     html += Drupal.theme('mkdruTerm', data.author[i].name, data.author[i].freq, 
88                           'mkdru-facet-author', data.author[i].id);
89   }
90   $('.mkdru-facet-authors').html(html);
91
92   $('.mkdru-facet-source').bind('click', function (e) {
93     mkdru.limitTarget(this.getAttribute('target_id'), this.firstChild.nodeValue);
94     return false;
95   });
96
97   $('.mkdru-facet-subject').bind('click', function (e) {
98     mkdru.limitQuery('su', this.firstChild.nodeValue);
99     return false;
100   });
101
102   $('.mkdru-facet-author').bind('click', function (e) {
103     mkdru.limitQuery('au', this.firstChild.nodeValue);
104     return false;
105   });
106 };
107
108 mkdru.pz2ByTarget = function (data) {
109   
110 };
111
112 mkdru.pz2Record = function (data) {
113   clearTimeout(mkdru.pz2.showTimer);
114   $('.mkdru-results').hide();
115   $('.mkdru-detail').html(Drupal.theme('mkdruDetail', data));
116   $('.mkdru-detail-back').bind('click', function () {$.bbq.removeState('recid');});
117   $('.mkdru-detail').show();
118   clearTimeout(mkdru.pz2.recordTimer);
119 };
120
121
122
123 // State and URL handling 
124
125 // populate state from an object and fill in the blanks with defaults
126 mkdru.stateFromObject = function (obj) {
127   for (var key in mkdru.defaultState) {
128     if (typeof(obj[key]) != "undefined") {
129       mkdru.state[key] = obj[key];
130     }
131     else {
132       mkdru.state[key] = mkdru.defaultState[key];
133     }
134   }
135 };
136
137 // populate state from current window's hash string
138 mkdru.stateFromHash = function () {
139   mkdru.stateFromObject($.deparam.fragment());
140 };
141
142 // set current window's hash string from state
143 mkdru.hashFromState = function () {
144   // only include non-default settings in the URL
145   var alteredState = {};
146   for (var key in mkdru.defaultState) {
147     if (mkdru.state[key] != mkdru.defaultState[key]) {
148       alteredState[key] = mkdru.state[key];
149     }
150   }
151   $.bbq.pushState(alteredState);
152 };
153
154 // update mkdru_form theme's ui to match state
155 mkdru.uiFromState = function () {
156   for (var key in mkdru.state) {
157     switch(key) {
158     case 'query':
159       $('.mkdru-search input:text').attr('value', mkdru.state[key]);
160       break;
161     case 'perpage':
162       $('.mkdru-perpage').attr('value', mkdru.state[key]);
163       break;
164     case 'sort':
165       $('.mkdru-sort').attr('value', mkdru.state[key]);
166       break;
167     }
168   }
169 };
170
171 mkdru.hashChange = function () {
172   mkdru.stateFromHash();
173   // Request for details
174   if (mkdru.state.recid) {
175     mkdru.pz2.record(mkdru.state.recid);
176   }
177   // Other internal link
178   else {
179     mkdru.pz2.showPage(mkdru.state.page-1);
180     $('.mkdru-detail').hide();
181     $('.mkdru-results').show();
182   }
183 };
184
185
186
187 // UI functions:
188 mkdru.submitQuery = function () {
189   mkdru.state.query = $('.mkdru-search input:text').attr('value');
190   mkdru.resetPage();
191   mkdru.pollDropDowns();
192   mkdru.hashFromState();
193   mkdru.search();
194   mkdru.submitted = true;
195   return false;
196 };
197
198 mkdru.triggerSearch = function () {
199   mkdru.search();
200   mkdru.submitted = true;
201 };
202
203 mkdru.search = function () {
204   mkdru.pz2.search(mkdru.state.query, mkdru.state.perpage, mkdru.state.sort,
205       mkdru.state.filter);
206 };
207
208 mkdru.pollDropDowns = function () {
209   mkdru.state.perpage = $('.mkdru-perpage').attr('value');
210   mkdru.state.sort = $('.mkdru-sort').attr('value');
211   if (!mkdru.submitted) return false;
212   mkdru.resetPage();
213   mkdru.hashFromState();
214   mkdru.pz2.show(0, mkdru.state.perpage, mkdru.state.sort);
215   return false;
216 };
217
218 mkdru.limitQuery = function (field, value) {
219   $('.mkdru-search input:text').attr('value', function () {
220     return this.value += ' and ' + field + '="' + value + '"';
221   });
222   mkdru.submitQuery();
223 };
224
225 mkdru.limitTarget = function (id, name) {
226   var navi = document.getElementById('mkdru-navi');
227   navi.innerHTML = 
228         'Source: <a class="crossout" href="#" onclick="delimitTarget();return false;">'
229         + name + '</a>';
230   navi.innerHTML += '<hr/>';
231   mkdru.state.filter = 'pz:id=' + id;
232   mkdru.resetPage();
233   mkdru.pollDropDowns();
234   mkdru.search();
235   return false;
236 };
237
238 mkdru.generatePager = function () {
239   var total = Math.ceil(mkdru.totalRec / mkdru.state.perpage);
240   var first = (mkdru.state.page - mkdru.pagerRange > 0)
241       ? mkdru.state.page - mkdru.pagerRange : 1;
242   var last = first + 2 * mkdru.pagerRange < total
243       ? first + 2 * mkdru.pagerRange : total;  
244   var prev = null;
245   var next = null;
246   var pages = [];
247
248   if ((mkdru.state.page - 1) >= first) {
249     prev = "#" + $.param.fragment($.param.fragment(
250                window.location.href, {page: mkdru.state.page - 1}))
251   }
252   if ((mkdru.state.page + 1) <= total) {
253     next = "#" + $.param.fragment($.param.fragment(
254                window.location.href, {page: mkdru.state.page + 1}))
255   }
256
257   for (var i = first; i <= last; i++) {
258     pages.push("#" + $.param.fragment($.param.fragment(
259                window.location.href, {page: i})));
260   }
261
262   return Drupal.theme('mkdruPager', pages, first, mkdru.state.page,
263                       total, prev, next);
264 };
265
266 mkdru.resetPage = function () {
267   mkdru.state.page = 1;
268   mkdru.totalRec = 0;
269 };
270
271
272
273 // wait until the DOM is ready, bind events
274 // and instantiate pz2 library
275 $(document).ready(function () {
276   $(window).bind( 'hashchange', mkdru.hashChange);
277   $('.mkdru-search').bind('submit', mkdru.submitQuery);
278   $('.mkdru-search input:text').attr('value', '');
279   $('.mkdru-perpage').bind('change', function () { mkdru.pollDropDowns() });
280   $('.mkdru-sort').bind('change', function () { mkdru.pollDropDowns() });
281
282   mkdru.pz2 = new pz2( { "onshow": mkdru.pz2Show,
283               "showtime": 500, //each timer (show, stat, term, bytarget) can be specified this way
284               "pazpar2path": mkdru.pazpar2path,
285               "oninit": mkdru.pz2Init,
286               "onstat": mkdru.pz2Status,
287               "onterm": mkdru.pz2Term,
288               "termlist": "xtargets,subject,author",
289               "onbytarget": mkdru.pz2ByTarget,
290               "usesessions" : mkdru.usesessions,
291               "showResponseType": mkdru.showResponseType,
292               "onrecord": mkdru.pz2Record,
293               "autoInit": false } );
294
295   // initialise state to hash string or defaults
296   mkdru.stateFromHash();
297   // and update UI to match
298   mkdru.uiFromState();
299
300   // ting thing
301   if (typeof(Drupal.settings.mkdru.query) !== "undefined") {
302     mkdru.state.query = Drupal.settings.mkdru.query
303   }
304
305   if (mkdru.usesessions) {
306     mkdru.pz2.init();
307   } else if (mkdru.state.recid) {
308     mkdru.pz2.record(mkdru.state.recid);
309   } else if (mkdru.state.query) {
310     mkdru.triggerSearch();
311   }
312 });