$(document).ready(function() { var getLinks = function(row) { if (!row.links || row.links.length === 0) { return false; } return row.links.map(function(link) { return '' + link.text + ''; }); }; window.doSearch = function() { // In case the source doesn't supply data required for DT to calculate // pagination, we need to do it ourselves var ownPagination = false; var directionSet = false; var start = 0; var forward = true; // true == forward, false == backwards // Arbitrary starting value, it will be corrected by the first // page of results var pageSize = 20; var tableTmpl = { ajax: { cache: true, // Prevent DT appending a "_" cache param }, columns: [ // defaultContent prevents DT from choking if // the API response doesn't return a column { title: 'Source', data: 'source', defaultContent: '' }, { data: 'title', defaultContent: '' }, { data: 'author', defaultContent: '' }, { data: 'isbn', defaultContent: '' }, { data: 'issn', defaultContent: '' }, { data: 'date', defaultContent: '' } ] }; // render functions don't get copied across when we make a dereferenced // copy of them, so we have to reattach them once we have a copy // Here we store them var renders = { title: function(data, type, row) { var links = getLinks(row); if (links) { return row.title + ' - ' + links.join(', '); } else if (row.url) { return '' + row.title + ''; } else { return row.title; } }, source: function(data, type, row) { return row.opac_url ? ''+row.source+'' : row.source; } }; services.forEach(function(service) { // Create a deferenced copy of our table definition object var tableDef = JSON.parse(JSON.stringify(tableTmpl)); // Iterate the table's columns array and add render functions // as necessary tableDef.columns.forEach(function(column) { if (renders[column.data]) { column.render = renders[column.data]; } }); tableDef.ajax.dataSrc = function(data) { var results = data.results.search_results; // The source appears to be returning it's own pagination // data if ( data.hasOwnProperty('recordsFiltered') || data.hasOwnProperty('recordsTotal') ) { return results; } // Set up our own pagination values based on what we just // got back ownPagination = true; directionSet = false; pageSize = results.length; // These values are completely arbitrary, but they enable // us to display pagination links data.recordsFiltered = 5000, data.recordsTotal = 5000; return results; }; tableDef.ajax.data = function(data) { // Datatables sends a bunch of superfluous params // that we don't want to litter our API schema // with, so just remove them from the request if (data.hasOwnProperty('columns')) { delete data.columns; } if (data.hasOwnProperty('draw')) { delete data.draw; } if (data.hasOwnProperty('order')) { delete data.order; } if (data.hasOwnProperty('search')) { delete data.search; } // If we're handling our own pagination, set the properties // that DT will send in the request if (ownPagination) { start = forward ? start + pageSize : start - pageSize; data.start = start; data['length'] = pageSize; } // We may need to restrict the service IDs being queries, this // needs to be handled in the plugin's API module var restrict = $('#service_id_restrict'). attr('data-service_id_restrict_ids'); if (restrict && restrict.length > 0) { data.restrict = restrict; } }; // Add any datatables config options passed from the service // to the table definition tableDef.ajax.url = service.endpoint + metadata; if (service.hasOwnProperty('datatablesConfig')) { var conf = service.datatablesConfig; for (var key in conf) { // The config from the service definition comes from a Perl // hashref, therefore can't contain true/false, so we // special case it if (conf.hasOwnProperty(key)) { if (conf[key] == 'false') { // Special case false values tableDef[key] = false; } else if (conf[key] == 'true') { // Special case true values tableDef[key] = true; } else { // Copy the property value tableDef[key] = conf[key]; } } } } // Create event watchers for the "next" and "previous" pagination // links, this enables us to set the direction the next request is // going in when we're doing our own pagination. We use "hover" // because the click event is caught after the request has been // sent tableDef.drawCallback = function() { $('.paginate_button.next:not(.disabled)', this.api().table().container() ).on('hover', function() { forward = true; directionSet = true; }); $('.paginate_button.previous:not(.disabled)', this.api().table().container() ).on('hover', function() { forward = false; directionSet = true; }); } // Initialise the table // Since we're not able to use the columns settings in core, // we need to mock the object that it would return var table_settings = { "columns": [ { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'source', is_hidden : 0 }, { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'title', is_hidden : 0 }, { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'author', is_hidden : 0 }, { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'isbn', is_hidden : 0 }, { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'issn', is_hidden : 0 }, { cannot_be_modified : 0, cannot_be_toggled : 0, columnname : 'date', is_hidden : 0 } ] }; // Hide pagination buttons if appropriate tableDef.drawCallback = function() { var pagination = $(this).closest('.dataTables_wrapper') .find('.dataTables_paginate'); pagination.toggle(this.api().page.info().pages > 1); } KohaTable(service.id, tableDef, table_settings); }); } });