Commit 9695e811 authored by Gradl, Tobias's avatar Gradl, Tobias
Browse files

1311: Refactor search javascript

Task-Url: https://pm.winseda.de/issues/1311
parent ea27139d
This diff is collapsed.
var QueryHandler = function(options) {
var _this = this;
this.options = $.extend({
customSearch : null,
}, options)
this.schemaId = null;
this.query = {};
this.lastDelayedQueryTs = null; // Helper variable for delayed queries (results slider)
this.responseHandler = this.options.responseHandler;
__translator.addTranslations(["~eu.dariah.de.minfba.search.view.result.resources.score",
"~eu.dariah.de.minfba.common.view.label.and",
"~eu.dariah.de.minfba.search.view.datamodel_info.document",
"~eu.dariah.de.minfba.search.view.datamodel_info.title",
"~eu.dariah.de.minfba.search.view.datamodel_info.target_mappings",
"~eu.dariah.de.minfba.search.view.datamodel_info.collections",
"~eu.dariah.de.minfba.search.view.datamodel_info.documents",
"~eu.dariah.de.minfba.search.view.datamodel_info.datamodels",
"~eu.dariah.de.minfba.search.view.datamodel_info.no_query_possible",
"~eu.dariah.de.minfba.search.search.collections.terms",
"~eu.dariah.de.minfba.search.search.collections.subjects",
"~eu.dariah.de.minfba.search.view.result.n_of_m_results",
"~eu.dariah.de.minfba.search.view.result.results_in_n_collections",
"~eu.dariah.de.minfba.search.view.result.no_results",
"~eu.dariah.de.minfba.search.view.result.no_frequent_terms",
"~eu.dariah.de.minfba.search.view.result.no_significant_terms",
"~eu.dariah.de.minfba.search.view.result.resources.no_preview",
"~eu.dariah.de.minfba.search.view.result.no_title"]);
$("#schemaId").change(function() { _this.selectFacetingSchema(); });
/*if ($("#expression").length>0) {
this.doSearch();
}*/
if ($("#schemaId").length>0) {
this.selectFacetingSchema();
}
};
QueryHandler.prototype.expandSearch = function(expression) {
if (expression==null || expression==="") {
return;
}
var _this = this;
if ($("#expression").length>0) {
if ($("#expression").val().length>0) {
$("#expression").val($("#expression").val() + " " + expression);
} else {
$("#expression").val(expression);
}
this.doSearch();
} else if ("#facet-selection-container".length > 0) {
this.addSearchFacet(function(facetElement) {
$(facetElement).find(".search-facet-expression").val(expression);
//_this.doSearch();
});
}
};
QueryHandler.prototype.selectFacetingSchema = function() {
this.schemaId = $("#schemaId").val();
var container = $("#facet-schema-info");
var _this = this;
this.clearSearchFacets();
$(container).text("");
$.ajax({
url: __util.getBaseUrl() + "search/extended/schemaInfo/?s=" + this.schemaId,
type: "GET",
dataType: "json",
success: function(data, textStatus, jqXHR ) {
if (!data.success) {
__util.processServerError(jqXHR, textStatus);
return;
}
var schemaInfo = "<label class=\"control-label\" style=\"font-size: 95%;\">";
if (data.pojo.datasourceIds.length>0) {
schemaInfo += "<p>" +
__translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.title") +
data.pojo.datasourceIds.length + " " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.collections") +
" " + __translator.translate("~eu.dariah.de.minfba.common.view.label.and") + " " +
data.pojo.documentCount + " " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.documents") +
"</p>";
}
if (data.pojo.mappingTargetSchemaIds.length>0) {
schemaInfo += "<p>" +
__translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.target_mappings") +
data.pojo.mappingTargetDatasourceIds.length + " " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.collections") +
" " + __translator.translate("~eu.dariah.de.minfba.common.view.label.and") + " " +
data.pojo.mappingTargetSchemaIds.length + " " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.datamodels") +
"</p>";
}
if (data.pojo.datasourceIds.length==0 && data.pojo.mappingTargetSchemaIds.length==0) {
schemaInfo += "<p style=\"color: #FF0000;\">" +
__translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.no_query_possible") +
"</p>"
}
schemaInfo += "</label>";
$(container).html(schemaInfo);
_this.insertSearchFacet();
},
error: __util.processServerError
});
};
QueryHandler.prototype.clearSearchFacets = function() {
$("#search-facets-container").text("");
};
QueryHandler.prototype.insertSearchFacet = function() {
var _this = this;
$.ajax({
url: __util.getBaseUrl() + "search/extended/facet/?s=" + this.schemaId,
type: "GET",
dataType: "html",
success: function(data, textStatus, jqXHR ) {
$("#search-facets-container").append(data);
_this.reorderFacets();
},
error: __util.processServerError
});
};
QueryHandler.prototype.reorderFacets = function() {
var index = 0;
$(".search-facet").each(function() {
$(this).find(".facet-fieldselect-hiddenindex").val(index);
$(this).find(".search-facet-element")
.prop("name", "facets[" + index + "].schemaElementId")
.prop("id", "facets" + index + ".schemaElementId");
$(this).find(".search-facet-expression")
.prop("name", "facets[" + index + "].expression")
.prop("id", "facets" + index + ".expression");
$(this).find("input[type='radio']").prop("name", "search-facet-flags-" + index);
$(this).find("input.search-facet-not-flag").prop("name", "search-facet-not-" + index);
index++;
});
};
QueryHandler.prototype.removeSearchFacet = function(control) {
$(control).closest(".search-facet").remove();
this.reorderFacets();
};
QueryHandler.prototype.doSearch = function(isShowMore) {
//if (isShowMore===null || isShowMore===undefined) {
isShowMore=false;
//}
var _this = this;
this.query = this.buildQuery(isShowMore);
this.imageQueue = [];
$(".wordcloud").text("");
this.clouds = [];
if (this.query!==null) {
$("#search-loading-indicator").removeClass("fade");
$.ajax({
url: __util.getBaseUrl() + "query/",
type: "POST",
dataType: "json",
data: JSON.stringify(_this.query),
contentType: "application/json",
success: function(data, jqXHR, textStatus) {
$("#search-loading-indicator").addClass("fade");
if (data==null) {
__util.processServerError(jqXHR, textStatus);
}
_this.responseHandler.process(data, isShowMore);
},
error : function(jqXHR, textStatus, message) {
$("#search-loading-indicator").addClass("fade");
__util.processServerError(jqXHR, textStatus);
}
});
}
};
QueryHandler.prototype.doSearchDelayed = function() {
var ts = new Date();
search.queryHandler.lastDelayedQueryTs = ts;
setTimeout(function() { search.queryHandler.delaySearch(ts); }, 1000);
};
QueryHandler.prototype.delaySearch = function(timestamp) {
if (timestamp===this.lastDelayedQueryTs) {
this.lastDelayedQueryTs = null;
this.doSearch();
}
};
QueryHandler.prototype.addFilter = function(queryFilter, html) {
var match = false;
$(".applied-filter").each(function() {
if (JSON.stringify($(this).data("queryFilter"))===JSON.stringify(queryFilter)) {
match = true;
}
});
if (match) {
return;
}
var filterLabel = $("<span class='label search-result-label'>")
.html(html)
.append("&nbsp;<i class=\"fa fa-cross\" aria-hidden=\"true\"></i>");
var filter = $("<div class='applied-filter search-result-label-wrapper'>")
.data("queryFilter", queryFilter)
.html(filterLabel)
.bind("click", function() {
$(this).remove();
if ($("#applied-filters-container .applied-filter").length==0) {
$("#applied-filters-container").addClass("hide");
}
queryHandler.doSearchDelayed();
});
$("#applied-filters-container #applied-filters").append(filter).append(" ");
$("#applied-filters-container").removeClass("hide");
queryHandler.doSearchDelayed();
};
QueryHandler.prototype.removeAllFilters = function() {
$('#applied-filters-container .applied-filter').remove();
$('#applied-filters-container').addClass('hide');
this.doSearchDelayed();
};
QueryHandler.prototype.buildQuery = function(isShowMore) {
var query = {
filters : []
};
$(".applied-filter").each(function() {
query.filters.push($(this).data("queryFilter"));
});
// Simple query view
if ($("#expression").length>0) {
query.queryString = $("#expression").val();
if ((query.queryString==null || query.queryString=="") && query.filters.length==0) {
return null;
}
} else {
query.facets = [];
var doQuery = false;
$(".search-facet").each(function() {
if ($(this).find(".search-facet-expression").val().trim().length>0) {
query.facets.push({
"elementId" : $(this).find(".search-facet-element").val(),
"value": $(this).find(".search-facet-expression").val(),
"must": $(this).find(".search-facet-must-flag").prop("checked"),
"not" : $(this).find(".search-facet-not-flag").prop("checked")
});
doQuery = true;
}
});
if (!doQuery && query.filters.length==0) {
return null;
}
query.schemaId = $("#schemaId").val();
}
query.size = $("#size").val();
query.explain = $("#explain").prop('checked');
query.sourceIds = search.getSelectedSourceIds();
query.customSearch = this.options.customSearch;
//query.providerIds = JSON.parse($("#providerIds").val());
//query.userCollectionId = parseInt($("#userCollectionId").val());
/*if (query.userCollectionId>-2 && query.providerIds.length==0) {
return null;
}
if (isShowMore) {
query.startIndex = $("#search-results-resources").find(".search-results-resource-item").length;
}*/
return query;
};
\ No newline at end of file
var ResponseHandler = function(options) {
this.options = $.extend({
highlightTexts: {
maxPerResultItem: 10
},
images: {
maxTries: 5
},
visualisations: {
wordclouds: {
height: 500,
width: 700,
size: 100
}
}
}, options)
this.elements = {
placeholderWordcloud: $("#wordcloud-placeholder"),
resultsContainer : $("#search-results-container"),
resourcesContainer: $("#search-results-resources"),
resourcesHeading: $("#search-results-resources-heading"),
explanationTab: $("#search-results-explanations-tab").closest("li"),
explanationContainer: $("#executed-queries")
}
__translator.addTranslations([ "~eu.dariah.de.minfba.search.view.result.no_results",
"~eu.dariah.de.minfba.search.view.result.n_of_m_results",
"~eu.dariah.de.minfba.search.view.result.resources.no_preview",
"~eu.dariah.de.minfba.search.view.result.no_title",
"~eu.dariah.de.minfba.search.view.result.resources.relevance_score",
"~eu.dariah.de.minfba.search.view.result.resources.hits_in_document",
"~eu.dariah.de.minfba.search.view.result.show_more"
]);
this.imageQueue = [];
};
ResponseHandler.prototype.process = function(data, isShowMore) {
this.elements.resultsContainer.removeClass("hide");
this.elements.placeholderWordcloud.addClass("hide");
this.processExecutedQueries(data.executedQueries);
this.processResources(isShowMore, data.resultElements, data.startIndex, data.totalHits, data.took, data.hasMore);
this.processResponseDatasources(data.resultDatasources);
//_this.processResponseTerms();
//_this.processResponseSubjects();
//
};
ResponseHandler.prototype.processExecutedQueries = function(queries) {
this.elements.explanationContainer.empty();
if (search.isExplain()) {
this.elements.explanationTab.removeClass("hide");
for (var i=0; i<queries.length; i++) {
this.elements.explanationContainer.append("<pre>" + queries[i] + "</pre>");
}
} else {
this.elements.explanationTab.addClass("hide");
// Select first unhidden tab, if explanation tab is currently shown
if (this.elements.explanationTab.find("a").hasClass("show")) {
this.elements.explanationTab.closest("ul.nav").find("li[class!='hidden']:first-child a").tab('show');
}
}
}
ResponseHandler.prototype.processResources = function(isShowMore, resultElements, startIndex, totalHits, took, hasMore) {
if (!isShowMore) {
this.elements.resourcesContainer.empty();
} else {
this.elements.resourcesContainer.find(".search-results-resources-show-more").remove()
}
if (resultElements==null || resultElements.length==0) {
this.elements.resourcesHeading.text(__translator.translate("~eu.dariah.de.minfba.search.view.result.no_results"));
this.elements.resourcesContainer.empty();
return;
}
this.elements.resourcesHeading.text(String.format(__translator.translate("~eu.dariah.de.minfba.search.view.result.n_of_m_results"), resultElements.length, totalHits));
var indexOffset = this.elements.resourcesContainer.find(".search-results-item").length;
for (var i=0; i<resultElements.length; i++) {
var resultItem = $("<div class='search-results-item d-md-flex flex-row' style='display: none;'>");
this.elements.resourcesContainer.append(resultItem);
this.processResource(i+indexOffset, resultItem, resultElements[i]);
resultItem.fadeIn("slow");
}
this.processImages();
if (hasMore) {
this.elements.resourcesContainer.append(
"<div class='search-results-resources-show-more'>" +
"<button onclick='queryHandler.doSearch(true);' class='btn btn-default btn-lg'>" +
__translator.translate("~eu.dariah.de.minfba.search.view.result.show_more") +
"</button>" +
"</div>");
}
};
ResponseHandler.prototype.processResource = function(index, resultItem, resultElement) {
// Image container
resultItem.append( "<div class='search-result-image-container' id='search-result-image-container-" + index + "'>" +
"<div class='image-loading-overlay'>" +
"<i class='fas fa-circle-notch fa-spin fa-3x'></i>" +
"</div>" +
"<div class='no-preview-overlay hide'>" +
__translator.translate("~eu.dariah.de.minfba.search.view.result.resources.no_preview") +
"</div>" +
"</div>");
var itemContainer = $("<div class='search-results-resource-item flex-grow-1 d-flex flex-column'>");
resultItem.append(itemContainer);
var resultId = encodeURIComponent(resultElement.id).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
var datamodelId = resultElement.datasetId;
// Collection title
itemContainer.append("<h3 class='search-result-datasource'>" + resultElement.collectionName + "</h3>");
// Elements of presentation model: title, objects, images
var title;
var objects;
if (resultElement.presentation !== undefined && resultElement.presentation != null && resultElement.presentation.Presentation !== undefined) {
if (resultElement.presentation.Presentation.Title !== undefined) {
title = this.renderResultValue(resultElement.presentation.Presentation.Title, 200);
}
if (resultElement.presentation.Presentation.Objects!==undefined) {
objects = this.handleObjects(resultElement.presentation.Presentation.Objects, i);
}
// Being loaded in-queue
this.handleImages(resultElement, index);
}
if (title==undefined || title.length==0) {
title = "<em>" + __translator.translate("~eu.dariah.de.minfba.search.view.result.no_title") + "</em>";
}
itemContainer.append( "<h2 class='search-result-title'>" +
"<a target='_self' href='" + __util.composeUrl("item/" + datamodelId + "/" + resultId + "/") + "'>" +
"<i class='fas fa-external-link-square-alt'></i> " + title +
"</a>" +
"</h2>");
if (objects!=undefined && objects.length>0) {
itemContainer.append("<div class='search-result-objects'>" + objects + "</div>");
}
var highlights = this.renderHighlightTexts(resultElement);
if (highlights!=undefined && highlights.length>0) {
itemContainer.append("<div class='search-result-highlights'><h4>" + __translator.translate("~eu.dariah.de.minfba.search.view.result.resources.hits_in_document") + "</h4>" + highlights + "</div>");
}
if (search.isExplain()) {
itemContainer.append(this.renderExplanation(resultItem));
}
};
ResponseHandler.prototype.handleImages = function(resultElement, index) {
var images = {
containerSelector : "#search-result-image-container-" + index,
resources: [],
placeholders: []
};
if (resultElement.presentation.Presentation.Images!==undefined) {
if (resultElement.presentation.Presentation.Images.Resource!==undefined) {
images.resources = this.prepImages(resultElement.collectionId, resultElement.endpointId, resultElement.datasetId, this.getValues(resultElement.presentation.Presentation.Images.Resource));
}
if (resultElement.presentation.Presentation.Images.Placeholder!==undefined) {
images.placeholders = this.prepImages(resultElement.collectionId, resultElement.endpointId, resultElement.datasetId, this.getValues(resultElement.presentation.Presentation.Images.Placeholder));
}
}
if (images.resources.length+images.placeholders.length > 0) {
this.imageQueue.push(images);
} else {
// Show placeholder right away
this.showImage(images.containerSelector, __util.composeUrl("theme/img/placeholder-logo.png"), undefined);
}
};
ResponseHandler.prototype.prepImages = function(collectionId, endpointId, datasetId, imageUrls) {
var images = [];
for (var i=0; i<imageUrls.length && i<this.options.images.maxTries; i++) {
images.push(__util.composeUrl("cachedimages/" + collectionId + "/" + endpointId + "/" + datasetId + "?i=" + encodeURIComponent(imageUrls[i])));
}
return images;
};
ResponseHandler.prototype.processImages = function(imageContainer) {
if (imageContainer==undefined) {
if (this.imageQueue.length==0) {
return;
}
imageContainer = this.imageQueue.shift();
}
var _this = this;
var url;
var placeholder = false;
if (imageContainer.resources.length>0) {
url = imageContainer.resources.shift();
} else if (imageContainer.placeholders.length>0) {
url = imageContainer.placeholders.shift();
placeholder = true;
} else {
// Nothing left to try with this container -> show placeholder
_this.showImage(imageContainer.containerSelector, __util.composeUrl("theme/img/placeholder-logo.png"), undefined);
this.processImages();
return;
}
var image = new Image();
image.src = url;
image.onload = function() {
_this.showImage(imageContainer.containerSelector, image.src, ( placeholder ? undefined : image.src + "&type=DISPLAY"));
// Go on with next in queue
_this.processImages();
}
image.onerror = function() {
// Retry with next image
_this.processImages(imageContainer);
}
};
ResponseHandler.prototype.showImage = function(containerSelector, tmbsrc, src) {
var image;
if (src===undefined) {
$(containerSelector).find(".no-preview-overlay").removeClass("hide");
image = "<div class=\"search-result-image\" style=\"background-image: url(" + tmbsrc + ");\"></div>";
} else {
image = "<a href=\"" + src + "\" class=\"venobox\">" +
"<div class=\"search-result-image\" style=\"background-image: url(" + tmbsrc + ");\"></div>" +
"<a>";
}
$(containerSelector).append(image);
if (src!==undefined) {
$(containerSelector).find(".venobox").venobox();
}
$(containerSelector).find(".image-loading-overlay").addClass("hide");
};
ResponseHandler.prototype.renderHighlightTexts = function(resultElement) {
var strHighlight;
// Search highlights (content matches)
if (resultElement.fieldHighlights!==undefined && resultElement.fieldHighlights.length>0) {
var highlights = [];
for (var i=0; i<resultElement.fieldHighlights.length; i++) {
for (var j=0; j<resultElement.fieldHighlights[i].highlightTexts.length; j++) {
var contained = false;
for (var k=0; k<highlights.length; k++) {
if (highlights[k]==resultElement.fieldHighlights[i].highlightTexts[j]) {
contained = true;
break;
}
}
if (!contained) {
highlights.push(resultElement.fieldHighlights[i].highlightTexts[j]);
}
if (highlights.length==this.options.highlightTexts.maxPerResultItem) {
break;
}
}
if (highlights.length==this.options.highlightTexts.maxPerResultItem) {
break;
}