Added islandora_advanced_search module.

This commit is contained in:
Nigel Banks 2021-02-10 13:14:52 +00:00
commit 698cbcad8b
52 changed files with 4329 additions and 0 deletions

View file

@ -0,0 +1,146 @@
//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/facets-view.ajax.js
/**
* @file
* Overrides the facets-view-ajax.js behavior from the 'facets' module.
*/
(function ($, Drupal) {
"use strict";
// Generate events on push state.
(function (history) {
var pushState = history.pushState;
history.pushState = function (state, title, url) {
var ret = pushState.apply(this, arguments);
var event = new Event("pushstate");
window.dispatchEvent(event);
return ret;
};
})(window.history);
function reload(url) {
// Update View.
if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
var view_path = drupalSettings.views.ajax_path;
$.each(drupalSettings.views.ajaxViews, function (views_dom_id) {
var views_parameters = Drupal.Views.parseQueryString(url);
var views_arguments = Drupal.Views.parseViewArgs(url, "search");
var views_settings = $.extend(
{},
Drupal.views.instances[views_dom_id].settings,
views_arguments,
views_parameters
);
var views_ajax_settings =
Drupal.views.instances[views_dom_id].element_settings;
views_ajax_settings.submit = views_settings;
views_ajax_settings.url =
view_path + "?" + $.param(Drupal.Views.parseQueryString(url));
Drupal.ajax(views_ajax_settings).execute();
});
}
// Replace filter, pager, summary, and facet blocks.
var blocks = {};
$(
".block[class*='block-plugin-id--islandora-advanced-search-result-pager'], .block[class*='block-plugin-id--views-exposed-filter-block'], .block[class*='block-plugin-id--facet']"
).each(function () {
var id = $(this).attr("id");
var block_id = id
.slice("block-".length, id.length)
.replace(/--.*$/g, "")
.replace(/-/g, "_");
blocks[block_id] = "#" + id;
});
Drupal.ajax({
url: Drupal.url("islandora-advanced-search-ajax-blocks"),
submit: {
link: url,
blocks: blocks,
},
}).execute();
}
// On location change reload all the blocks / ajax view.
window.addEventListener("pushstate", function (e) {
reload(window.location.href);
});
window.addEventListener("popstate", function (e) {
if (e.state != null) {
reload(window.location.href);
}
});
/*** Push state on form/pager/facet change.
*/
Drupal.behaviors.islandoraAdvancedSearchViewsAjax = {
attach: function (context, settings) {
window.historyInitiated = true;
// Remove existing behavior from form.
if (settings && settings.views && settings.views.ajaxViews) {
$.each(settings.views.ajaxViews, function (index, settings) {
var exposed_form = $(
"form#views-exposed-form-" +
settings.view_name.replace(/_/g, "-") +
"-" +
settings.view_display_id.replace(/_/g, "-")
);
exposed_form
.once()
.find("input[type=submit], input[type=image]")
.not("[data-drupal-selector=edit-reset]")
.each(function (index) {
$(this).unbind("click");
$(this).click(function (e) {
// Let ctrl/cmd click open in a new window.
if (e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
e.preventDefault();
e.stopPropagation();
var href = window.location.href;
var params = Drupal.Views.parseQueryString(href);
// Remove the page if set as submitting the form should always take
// the user to the first page (facets do the same).
delete params.page;
// Include values from the form in the URL.
$.each(exposed_form.serializeArray(), function () {
params[this.name] = this.value;
});
href = href.split("?")[0] + "?" + $.param(params);
window.history.pushState(null, document.title, href);
});
});
});
}
// Attach behavior to pager, summary, facet links.
$("[data-drupal-pager-id], [data-drupal-facets-summary-id], [data-drupal-facet-id]")
.once()
.find("a:not(.facets-soft-limit-link)")
.click(function (e) {
// Let ctrl/cmd click open in a new window.
if (e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
e.preventDefault();
window.history.pushState(null, document.title, $(this).attr("href"));
});
// Trigger on sort change.
$('[data-drupal-pager-id] select[name="order"]')
.once()
.change(function () {
var href = window.location.href;
var params = Drupal.Views.parseQueryString(href);
var selection = $(this).val();
var option = $('option[value="' + selection + '"]');
params.sort_order = option.data("sort_order");
params.sort_by = option.data("sort_by");
href = href.split("?")[0] + "?" + $.param(params);
window.history.pushState(null, document.title, href);
});
},
};
})(jQuery, Drupal);

70
js/facets/soft-limit.js Normal file
View file

@ -0,0 +1,70 @@
//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/soft-limit.js
/**
* @file
* Overrides the soft-limit.js behavior from the 'facets' module.
* As when having many facets the original version causes the page to slow down and snap to hidden when rendering.
*/
(function ($) {
'use strict';
Drupal.behaviors.facetSoftLimit = {
attach: function (context, settings) {
if (settings.facets.softLimit !== 'undefined') {
$.each(settings.facets.softLimit, function (facet, limit) {
Drupal.facets.applySoftLimit(facet, limit, settings);
});
}
}
};
Drupal.facets = Drupal.facets || {};
/**
* Applies the soft limit UI feature to a specific facets list.
*
* @param {string} facet
* The facet id.
* @param {string} limit
* The maximum amount of items to show.
* @param {object} settings
* Settings.
*/
Drupal.facets.applySoftLimit = function (facet, limit, settings) {
var zero_based_limit = (limit - 1);
var facet_id = facet;
var facetsList = $('ul[data-drupal-facet-id="' + facet_id + '"]');
// In case of multiple instances of a facet, we need to key them.
if (facetsList.length > 1) {
facetsList.each(function (key, $value) {
$(this).attr('data-drupal-facet-id', facet_id + '-' + key);
});
}
// Add "Show more" / "Show less" links.
facetsList.filter(function () {
return $(this).next('ul').length == 1; // Has expanding list.
}).each(function () {
var facet = $(this);
var expand = facet.next('ul');
var link = expand.next('a');
var showLessLabel = settings.facets.softLimitSettings[facet_id].showLessLabel;
var showMoreLabel = settings.facets.softLimitSettings[facet_id].showMoreLabel;
link.text(showMoreLabel)
.once()
.on('click', function () {
if (!expand.is(":visible")) {
expand.slideDown();
$(this).addClass('open').text(showLessLabel);
}
else {
expand.slideUp();
$(this).removeClass('open').text(showMoreLabel);
}
return false;
})
});
};
})(jQuery);

View file

@ -0,0 +1,113 @@
//# sourceURL=modules/contrib/islandora_advanced_search/js/islandora-advanced-search.admin.js
/**
* @file
* Largely based on core/modules/blocks/js/blocks.js
*
* This file allows for moving rows between two regions in a table and have the
* 'region' field update appropriately.
*/
(function ($, window, Drupal) {
Drupal.behaviors.islandoraAdvancedSearchAdmin = {
attach: function attach(context, settings) {
if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag['advanced-search-fields'] === 'undefined') {
return;
}
function checkEmptyRegions(table, rowObject) {
table.find('tr.region-message').each(function () {
var $this = $(this);
if ($this.prev('tr').get(0) === rowObject.element) {
if (rowObject.method !== 'keyboard' || rowObject.direction === 'down') {
rowObject.swap('after', this);
}
}
if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
$this.removeClass('region-populated').addClass('region-empty');
} else if ($this.is('.region-empty')) {
$this.removeClass('region-empty').addClass('region-populated');
}
});
}
function updateLastPlaced(table, rowObject) {
table.find('.color-success').removeClass('color-success');
var $rowObject = $(rowObject);
if (!$rowObject.is('.drag-previous')) {
table.find('.drag-previous').removeClass('drag-previous');
$rowObject.addClass('drag-previous');
}
}
function updateFieldWeights(table, region) {
var weight = -Math.round(table.find('.draggable').length / 2);
table.find('.region-' + region + '-message').nextUntil('.region-title').find('select.field-weight').val(function () {
return ++weight;
});
}
var table = $('#advanced-search-fields');
var tableDrag = Drupal.tableDrag['advanced-search-fields'];
tableDrag.row.prototype.onSwap = function (swappedRow) {
checkEmptyRegions(table, this);
updateLastPlaced(table, this);
};
tableDrag.onDrop = function () {
var dragObject = this;
var $rowElement = $(dragObject.rowObject.element);
var regionRow = $rowElement.prevAll('tr.region-message').get(0);
var regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
var regionField = $rowElement.find('select.field-display');
if (regionField.find('option[value=' + regionName + ']').length === 0) {
window.alert(Drupal.t('The field cannot be placed in this region.'));
regionField.trigger('change');
}
if (!regionField.is('.field-display-' + regionName)) {
var weightField = $rowElement.find('select.field-weight');
var oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*field-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
regionField.removeClass('field-display-' + oldRegionName).addClass('field-display-' + regionName);
weightField.removeClass('field-weight-' + oldRegionName).addClass('field-weight-' + regionName);
regionField.val(regionName);
}
updateFieldWeights(table, regionName);
};
$(context).find('select.field-display').once('field-display').on('change', function (event) {
var row = $(this).closest('tr');
var select = $(this);
tableDrag.rowObject = new tableDrag.row(row[0]);
var regionMessage = table.find('.region-' + select[0].value + '-message');
var regionItems = regionMessage.nextUntil('.region-message, .region-title');
if (regionItems.length) {
regionItems.last().after(row);
} else {
regionMessage.after(row);
}
updateFieldWeights(table, select[0].value);
checkEmptyRegions(table, tableDrag.rowObject);
updateLastPlaced(table, row);
if (!tableDrag.changed) {
$(Drupal.theme('tableDragChangedWarning')).insertBefore(tableDrag.table).hide().fadeIn('slow');
tableDrag.changed = true;
}
select.trigger('blur');
});
}
};
})(jQuery, window, Drupal);

View file

@ -0,0 +1,114 @@
//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/islandora-advanced-search.form.js
/**
* @file
* Handles Ajax submission / updating form action on url change, etc.
*/
(function ($, Drupal, drupalSettings) {
// Gets current parameters minus ones provided by the form.
function getParams(query_parameter, recurse_parameter) {
var params = Drupal.Views.parseQueryString(window.location.href);
// Remove Advanced Search Query Parameters.
const param_match = "query\\[\\d+\\]\\[.+\\]".replace("query", query_parameter);
const param_regex = new RegExp(param_match, "g");
for (const param in params) {
if (param.match(param_regex)) {
delete params[param];
}
}
// Remove Recurse parameter.
delete params[recurse_parameter];
return params;
}
// Groups form inputs by search term.
function getTerms(inputs) {
const input_regex = /terms\[(?<index>\d+)\]\[(?<component>.*)\]/;
const terms = [];
for (const input in inputs) {
const name = inputs[input].name;
const value = inputs[input].value;
const found = name.match(input_regex);
if (found) {
const index = parseInt(found.groups.index);
const component = found.groups.component;
if (typeof terms[index] !== 'object') {
terms[index] = {};
}
terms[index][component] = value;
}
}
return terms;
}
// Checks if the form user has set recursive to true in the form.
function getRecurse(inputs) {
for (const input in inputs) {
const name = inputs[input].name;
const value = inputs[input].value;
if (name == "recursive" && value == "1") {
return true;
}
}
return false;
}
function url(inputs, settings) {
const terms = getTerms(inputs);
const recurse = getRecurse(inputs);
const params = getParams(settings.query_parameter, settings.recurse_parameter);
for (const index in terms) {
const term = terms[index];
// Do not include terms with no value.
if (term.value.length != 0) {
for (const component in term) {
const value = term[component];
const param = "query[index][component]"
.replace("query", settings.query_parameter)
.replace("index", index)
.replace("component", settings.mapping[component]);
params[param] = value;
}
}
}
if (recurse) {
params[settings.recurse_parameter] = '1';
}
return window.location.href.split("?")[0] + "?" + $.param(params);
}
Drupal.behaviors.islandora_advanced_search_form = {
attach: function (context, settings) {
if (settings.islandora_advanced_search_form.id !== 'undefined') {
const $form = $('form#' + settings.islandora_advanced_search_form.id).once();
if ($form.length > 0) {
window.addEventListener("pushstate", function (e) {
$form.attr('action', window.location.pathname + window.location.search);
});
window.addEventListener("popstate", function (e) {
if (e.state != null) {
$form.attr('action', window.location.pathname + window.location.search);
}
});
// Prevent form submission and push state instead.
//
// Logic server side / client side should match to generate the
// approprirate URL with javascript enabled or disable.
$form.submit(function (e) {
e.preventDefault();
e.stopPropagation();
const inputs = $form.serializeArray();
const href = url(inputs, settings.islandora_advanced_search_form);
window.history.pushState(null, document.title, href);
});
// Reset should trigger refresh of AJAX Blocks / Views.
$form.find('input[data-drupal-selector = "edit-reset"]').mousedown(function (e) {
const inputs = [];
const href = url(inputs, settings.islandora_advanced_search_form);
window.history.pushState(null, document.title, href);
});
}
}
}
};
})(jQuery, Drupal, drupalSettings);