--- /dev/null
+<div id="<?php print $divId ?>"> </div>
--- /dev/null
+ <div id="mkdru">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="250" height="100" align="center"><b>PAZPAR2</b></td>
+ <td>
+ <form class="mkdru-search">
+ <input type="text" size="50"/>
+ <input id="button" type="button" value="Search"/>
+ </form>
+ </td>
+ <td>
+ <a href="http://www.indexdata.com"><img border="0" title="IndexData home page" src="id.gif" align="right" alt="" /></a>
+ </td>
+ </tr>
+ </table>
+
+ </div>
+
+ <div id="recordview">
+
+ <div id="ranking">
+
+ <form>
+ Sort by
+ <select id="mkdru-sort">
+ <option value="relevance" selected="selected">relevance</option>
+ <option value="title:1">title</option>
+ <option value="date:0">newest</option>
+ <option value="date:1">oldest</option>
+
+ </select>
+ and show
+ <select id="mkdru-perpage">
+ <option value="10">10</option>
+ <option value="20" selected="selected">20</option>
+ <option value="30">30</option>
+ <option value="50">50</option>
+ </select>
+ per page.
+ </form>
+ </div>
+ <div id="mkdru-pager"></div>
+ <div id="mkdru-navi"></div>
+ <div id="mkdru-results"></div>
+ </div>
--- /dev/null
+<?php
+function jsdemo2_admin_settings() {
+ $form['jsdemo2_author_max']=array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum authors to display'),
+ '#default_value' => variable_get('jsdemo2_author_max', 10),
+ '#size' => 3,
+ '#maxlength' => 3,
+ );
+
+ $form['jsdemo2_source_max']=array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum sources to display'),
+ '#default_value' => variable_get('jsdemo2_source_max', 16),
+ '#size' => 3,
+ '#maxlength' => 3,
+ );
+
+ $form['jsdemo2_subject_max']=array(
+ '#type' => 'textfield',
+ '#title' => t('Maximum subjects to display'),
+ '#default_value' => variable_get('jsdemo2_subject_max', 10),
+ '#size' => 3,
+ '#maxlength' => 3,
+ );
+
+ return system_settings_form($form);
+}
+
+function jsdemo2_admin_settings_validate($form, $form_state) {
+ if (!is_numeric($form_state['values']['jsdemo2_source_max'])) {
+ form_set_error('jsdemo2_source_max', t('Please enter a number.'));
+ }
+ if (!is_numeric($form_state['values']['jsdemo2_author_max'])) {
+ form_set_error('jsdemo2_author_max', t('Please enter a number.'));
+ }
+ if (!is_numeric($form_state['values']['jsdemo2_subject_max'])) {
+ form_set_error('jsdemo2_subject_max', t('Please enter a number.'));
+ }
+}
--- /dev/null
+// Set up namespace and some state.
+var mkdru = {
+ // Settings to pass to pz2.js
+ usesessions: true,
+ showResponseType: '',
+ // Variables
+ curPage: 1,
+ recPerPage: 20,
+ totalRec: 0,
+ curSort: 'relevance',
+ curFilter: null,
+ submitted: false,
+ sourceMax: 16, // facets
+ subjectMax: 10,
+ authorMax: 10,
+ pz2: null,
+ pazpar2Path: '/pazpar2/search.pz2',
+};
+
+
+
+// pz2.js event handlers:
+mkdru.pz2Init = function () {
+ mkdru.pz2.stat();
+ mkdru.pz2.bytarget();
+};
+
+mkdru.pz2Show = function (data) {
+ mkdru.totalRec = data.merged;
+ $('#mkdru-pager').html(Drupal.theme('mkdruPager', data, mkdru.curPage,
+ Math.ceil(mkdru.totalRec / mkdru.recPerPage)));
+ $('.mkdru-next').bind('click', mkdru.nextPage);
+ $('.mkdru-prev').bind('click', mkdru.prevPage);
+
+ var html = "";
+ for (var i = 0; i < data.hits.length; i++) {
+ html += Drupal.theme('mkdruResult', data.hits[i],
+ i + 1 + mkdru.recPerPage *
+ (mkdru.curPage - 1));
+ }
+ $('#mkdru-results').html(html);
+};
+
+mkdru.pz2Status = function (data) {
+};
+
+mkdru.pz2Term = function (data) {
+ var html = "";
+ for (var i = 0; i < data.xtargets.length && i < mkdru.SourceMax; i++ ) {
+ html += Drupal.theme('mkdruTerm', data.xtargets[i].name, data.xtargets[i].freq,
+ 'mkdru-facet-link-source', data.xtargets[i].id);
+ }
+ $('#mkdru-sources').html(html);
+
+ html = "";
+ for (var i = 0; i < data.subject.length && i < mkdru.SubjectMax; i++ ) {
+ html += Drupal.theme('mkdruTerm', data.subject[i].name, data.subject[i].freq,
+ 'mkdru-facet-link-subject', data.subject[i].id);
+ }
+ $('#mkdru-subjects').html(html);
+
+ html = "";
+ for (var i = 0; i < data.author.length && i < mkdru.AuthorMax; i++ ) {
+ html += Drupal.theme('mkdruTerm', data.author[i].name, data.author[i].freq,
+ 'mkdru-facet-link-author', data.author[i].id);
+ }
+ $('#mkdru-authors').html(html);
+};
+
+mkdru.pz2ByTarget = function (data) {
+
+};
+
+
+
+// UI functions:
+mkdru.submitQuery = function () {
+ mkdru.submitted = true;
+// mkdru.resetPage();
+// mkdru.pollDropDowns();
+ mkdru.search();
+};
+
+mkdru.search = function () {
+ mkdru.pz2.search($('.mkdru-search input:text').attr('value'),
+ mkdru.recPerPage, mkdru.curSort, mkdru.curFilter);
+};
+
+mkdru.pollDropDowns = function () {
+ mkdru.recPerPage = $('#mkdru-perpage').value;
+ mkdru.curSort = $('#mkdru-sort').value;
+ if (!mkdru.submitted) return false;
+ mkdru.resetPage();
+ mkdru.pz2.show(0, mkdru.recPerPage, mkdru.curSort);
+};
+
+mkdru.limitQuery = function (field, value) {
+
+};
+
+mkdru.resetPage = function () {
+ mkdru.curPage = 1;
+ mkdru.totalRec = 0;
+};
+
+mkdru.showPage = function (pageNum) {
+ mkdru.curPage = pageNum;
+ mkdru.pz2.showPage(pageNum-1);
+};
+
+mkdru.nextPage = function () {
+ if (mkdru.totalRec - mkdru.recPerPage * mkdru.curPage > 0) {
+ mkdru.pz2.showNext();
+ mkdru.curPage++;
+ }
+};
+
+mkdru.prevPage = function () {
+ if (mkdru.pz2.showPrev() != false) {
+ mkdru.curPage--;
+ }
+};
+
+
+// wait until the DOM is ready, bind events
+// and instantiate pz2 library
+$(document).ready(function () {
+ $('.mkdru-search input:button').bind('click', mkdru.submitQuery);
+ $('.mkdru-search input:text').attr('value', '');
+ $('#mkdru-perpage').bind('change', function () { mkdru.pollDropDowns() });
+ $('#mkdru-sort').bind('change', function () { mkdru.pollDropDowns() });
+ mkdru.pz2 = new pz2( { "onshow": mkdru.pz2Show,
+ "showtime": 500, //each timer (show, stat, term, bytarget) can be specified this way
+ "pazpar2path": mkdru.pazpar2path,
+ "oninit": mkdru.pz2Init,
+ "onstat": mkdru.pz2Status,
+ "onterm": mkdru.pz2Term,
+ "termlist": "xtargets,subject,author",
+ "onbytarget": mkdru.pz2ByTarget,
+ "usesessions" : mkdru.usesessions,
+ "showResponseType": mkdru.showResponseType,
+ "onrecord": mkdru.pz2Record } );
+});
\ No newline at end of file
--- /dev/null
+name = Z39.50 metasearch
+description = Metasearching of Z39.50 and other targets via Index Data's Pazpar2 and associated tool stack.
+core = 6.x
--- /dev/null
+<?php
+
+/**
+* Implementation of hook_node_info().
+*/
+function mkdru_node_info() {
+ return array(
+ 'mkdru' => array(
+ 'name' => t("Z39.50/SRU metasearch interface"),
+ 'module' => 'mkdru',
+ 'description' => t("Metasearch interface for Z39.50/SRU and other targets via a Pazpar2/Service Proxy backend"),
+
+ )
+ );
+}
+
+/**
+* Implementation of hook_perm().
+*/
+function mkdru_perm() {
+ return array('create metasearch interface', 'edit any metasearch interface', 'edit own metasearch interface');
+}
+
+/**
+* Implementation of hook_access().
+*/
+function mkdru_access($op, $node, $account) {
+
+ if ($op == 'create') {
+ // Only users with permission to do so may create this node type.
+ return user_access('create metasearch interface', $account);
+ }
+
+ // Users who create a node may edit or delete it later, assuming they have the
+ // necessary permissions.
+ if ($op == 'update' || $op == 'delete') {
+ if (user_access('edit own metasearch interface', $account) && ($account->uid == $node->uid)) {
+ return TRUE;
+ } else if (user_access('edit any metasearch interface', $account)) {
+ return TRUE;
+ }
+ }
+}
+
+/**
+* Implementation of hook_form().
+*/
+function mkdru_form(&$node, $form_state) {
+ $type = node_get_types('type', $node);
+
+ $form['title'] = array(
+ '#type' => 'textfield',
+ '#title' => check_plain($type->title_label),
+ '#required' => TRUE,
+ '#default_value' => $node->title,
+ '#weight' => -5
+ );
+
+ return $form;
+}
+
+/**
+* Implementation of hook_theme().
+*/
+function mkdru_theme() {
+ return array(
+ 'mkdru_page' => array(
+ 'template' => 'mkdru-page',
+ 'arguments' => array(),
+ ),
+ 'mkdru_page_js' => array(
+ 'arguments' => array(),
+ ),
+// 'mkdru_block_facet' => array(
+// 'template' => 'mkdru-block-facet',
+// 'arguments' => array('divId' => NULL),
+// ),
+ );
+}
+
+/**
+* Theme function to include Javascript search client and deps
+*/
+function theme_mkdru_page_js() {
+ $path = drupal_get_path('module', 'mkdru');
+ drupal_add_js('pazpar2/js/pz2.js', 'module', 'footer');
+ drupal_add_js($path . '/mkdru.theme.js', 'module', 'footer');
+ drupal_add_js($path . '/mkdru.client.js', 'module', 'footer');
+}
+
+/**
+* Implementation of hook_view()
+*/
+function mkdru_view($node, $teaser = FALSE, $page = FALSE) {
+ $node->content['mkdru_page_js'] = array(
+ '#value' => theme('mkdru_page_js'),
+ '#weight' => 0,
+ );
+ $node->content['mkdru_page'] = array(
+ '#value' => theme('mkdru_page'),
+ '#weight' => 1,
+ );
+ return $node;
+}
+
+/**
+* Implementation of hook_block()
+*/
+function mkdru_block($op='list', $delta='sources', $edit=array()) {
+ switch ($op) {
+ case 'list':
+ $blocks['mkdru_sources']['info'] = t('mkdru - source facets');
+ $blocks['mkdru_sources']['cache'] = BLOCK_NO_CACHE;
+ $blocks['mkdru_subjects']['info'] = t('mkdru - subject facets');
+ $blocks['mkdru_subjects']['cache'] = BLOCK_NO_CACHE;
+ $blocks['mkdru_authors']['info'] = t('mkdru - author facets');
+ $blocks['mkdru_authors']['cache'] = BLOCK_NO_CACHE;
+ return $blocks;
+
+ case 'view':
+ switch ($delta) {
+ // TODO: make the facet themable, I have no clue why this won't work
+// case 'mkdru_sources':
+// $block['subject'] = t('Source');
+// $block['content'] = theme('mkdru_block_facet', 'mkdru-sources');
+// return $block;
+// case 'mkdru_subjects':
+// $block['subject'] = t('Subject');
+// $block['content'] = theme('mkdru_block_facet', 'mkdru-subjects');
+// return $block;
+// case 'mkdru_authors':
+// $block['subject'] = t('Author');
+// $block['content'] = theme('mkdru_block_facet', 'mkdru-authors');
+// return $block;
+ case 'mkdru_sources':
+ $block['subject'] = t('Source');
+ $block['content'] = '<div id="mkdru-sources"> </div>';
+ return $block;
+ case 'mkdru_subjects':
+ $block['subject'] = t('Subject');
+ $block['content'] = '<div id="mkdru-subjects"> </div>';
+ return $block;
+ case 'mkdru_authors':
+ $block['subject'] = t('Author');
+ $block['content'] = '<div id="mkdru-authors"> </div>';
+ return $block;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+Drupal.theme.prototype.mkdruResult = function(hit, num) {
+ var html = [];
+ html.push('<div class="record" id="recdiv_' + hit.recid + '" >'
+ + '<span>' + num + '. </span>'
+ + '<a href="#" id="rec_' + hit.recid
+ + '"><b>'
+ + hit["md-title"] + ' </b></a>');
+ if (hit["md-title-remainder"] !== undefined) {
+ html.push('<span>' + hit["md-title-remainder"] + ' </span>');
+ }
+ if (hit["md-title-responsibility"] !== undefined) {
+ html.push('<span><i>'+hit["md-title-responsibility"]+'</i></span>');
+ }
+ html.push('</div>');
+ return (html.join(''));
+};
+
+Drupal.theme.prototype.mkdruPager = function (data, curPage, pages) {
+ var caption = '<hr/><div style="float: right">Displaying: '
+ + (data.start + 1) + ' to ' + (data.start + data.num) +
+ ' of ' + data.merged + ' (found: '
+ + data.total + ')</div>';
+
+ var onsides = 6;
+
+ var firstClkbl = ( curPage - onsides > 0 )
+ ? curPage - onsides
+ : 1;
+
+ var lastClkbl = firstClkbl + 2*onsides < pages
+ ? firstClkbl + 2*onsides
+ : pages;
+
+ var prev = '<span id="prev"><< Prev</span><b> | </b>';
+ if (curPage > 1)
+ var prev = '<a href="#" class="mkdru-prev">'
+ +'<< Prev</a><b> | </b>';
+
+ var middle = '';
+ for(var i = firstClkbl; i <= lastClkbl; i++) {
+ var numLabel = i;
+ if(i == curPage)
+ numLabel = '<b>' + i + '</b>';
+
+ middle += '<a href="#" onclick="mkdru.showPage(' + i + ')"> '
+ + numLabel + ' </a>';
+ }
+
+ var next = '<b> | </b><span id="next">Next >></span>';
+ if (pages - curPage > 0)
+ var next = '<b> | </b><a href="#" class="mkdru-next">'
+ +'Next >></a>';
+
+ predots = '';
+ if (firstClkbl > 1)
+ predots = '...';
+
+ postdots = '';
+ if (lastClkbl < pages)
+ postdots = '...';
+
+ return ('<div style="float: clear">' +
+ caption + prev + predots + middle + postdots + next + '</div><hr/>');
+};
+
+Drupal.theme.prototype.mkdruTerm = function (term, freq, linkClass, id) {
+ var html = '<a href="#"';
+ if (id)
+ html += ' target_id="' + id + '"';
+ html += ' class="' + linkClass + '">' + term + '</a><span> (' + freq + ')</span><br/>';
+ return html;
+};
\ No newline at end of file