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
var queryHandler;
var search;
$(document).ready(function() {
queryHandler = new QueryHandler({
search = new Search({
customSearch: $("#customSearchPrefix").val()
});
__translator.getTranslations();
$("#btn-exec-search").click(function() { queryHandler.doSearch(); });
$("#explain").change(function() { queryHandler.doSearch(); });
$('#expression').keyup(function (e) { if (e.which==13) { queryHandler.doSearch(); }});
$("#size").bind("slider:changed", function (event, data) {
$("#size_shown").text(data.value);
queryHandler.doSearchDelayed();
});
// Required for page reload in FF
$("#query_size").bind("slider:ready", function (event, data) {
$("#query_size_shown").text(data.value);
});
var clouds = [];
queryHandler.loadPlaceholderTagcloud();
queryHandler.doSearch();
$('.venobox').venobox();
search.init();
});
$(window).resize(function() {
queryHandler.resize();
search.resize();
});
var QueryHandler = function(options) {
var _this = this;
var Search = function(options) {
this.options = $.extend({
customSearch : null,
wordcloud : {
tags : {
aggregator: "Wordcloud",
size: 100
},
animate: true,
animateDirection: "topDown",
height: 500,
width: 700,
tagsize: {
factor: 60,
offset: 12
}
},
images: {
maxTries: 5
}
}, options)
this.schemaId = null;
this.query = {};
this.lastDelayedQueryTs = null; // Helper variable for delayed queries (results slider)
this.imageQueue = [];
__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.no_title"]);
__translator.getTranslations();
$("#schemaId").change(function() { _this.selectFacetingSchema(); });
sourceSelection.renderDatasourceList();
/*if ($("#expression").length>0) {
this.doSearch();
}*/
if ($("#schemaId").length>0) {
this.selectFacetingSchema();
}
};
QueryHandler.prototype.loadPlaceholderTagcloud = function() {
var url = __util.getBaseUrl();
if (this.options.customSearch!=null && this.options.customSearch!="") {
url += "/custom/" + this.options.customSearch + "/";
}
url += "tags?analyzer=" + this.options.wordcloud.tags.aggregator + "&size=" + this.options.wordcloud.tags.size;
var _this = this;
$.ajax({
url: url,
type: "GET",
dataType: "json",
success: function(data) {
var tags = [];
for (var i=0; i<data.length; i++) {
tags.push({
text: data[i].term,
size: (data[i].weight * 80) + 7,
title: data[i].count + " occurences"
});
}
tagCloud = new TagCloud({
tags: tags,
containerSelector: "#wordcloud-placeholder",
animateFontSize: true,
w: 600,
h: 400,
textClickEvent: function(tag) {
_this.expandSearch(tag.text);
}
});
}
});
};
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;
Search.prototype.init = function() {
this.elements = {
checkExplain: $("#explain")
};
this.clearSearchFacets();
$(container).text("");
this.initComponents();
this.bindEvents();
$.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("");
__translator.getTranslations();
};
QueryHandler.prototype.resize = function() {
var tagCloudWidth = $("#search-results-container").width() - 50;
Search.prototype.bindEvents = function() {
/*for (var i=0; i<this.clouds.length; i++) {
this.clouds[i].size(tagCloudWidth, this.options.wordcloud.height);
}*/
$("#btn-exec-search").click(function() { search.queryHandler.doSearch(); });
$("#explain").change(function() { search.queryHandler.doSearch(); });
$('#expression').keyup(function (e) { if (e.which==13) { search.queryHandler.doSearch(); }});
$(".wordcloud svg").attr("width", tagCloudWidth);
};
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++;
$("#size").bind("slider:changed", function (event, data) {
$("#size_shown").text(data.value);
search.queryHandler.doSearchDelayed();
});
};
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.processResponse(data, isShowMore);
},
error : function(jqXHR, textStatus, message) {
$("#search-loading-indicator").addClass("fade");
__util.processServerError(jqXHR, textStatus);
}
});
}
};
QueryHandler.prototype.doSearchDelayed = function() {
var ts = new Date();
queryHandler.lastDelayedQueryTs = ts;
setTimeout(function() { queryHandler.delaySearch(ts); }, 1000);
};
QueryHandler.prototype.delaySearch = function(timestamp) {
if (timestamp===this.lastDelayedQueryTs) {
this.lastDelayedQueryTs = null;
this.doSearch();
}
};
QueryHandler.prototype.processResponseExecutedQueries = function(queries, explain) {
$("#executed-queries").text("");
if (explain) {
$("#search-results-explanations-tab").closest("li").removeClass("hide");
for (var i=0; i<queries.length; i++) {
$("#executed-queries").append("<pre>" + queries[i] + "</pre>");
}
} else {
$("#search-results-explanations-tab").closest("li").addClass("hide");
}
}
QueryHandler.prototype.processResponse = function(data, isShowMore) {
var _this = this;
var explain = $("#explain").prop('checked');
this.processResponseExecutedQueries(data.executedQueries, explain);
$("#search-results-container").removeClass("hide");
$("#wordcloud-placeholder").addClass("hide");
$.ajax({
url: window.location.pathname + "incl/resultItemTemplate?explain=" + explain,
type: "GET",
dataType: "text",
success: function(template) {
_this.processResponseResources(isShowMore, data.resultElements, data.startIndex, data.totalHits, data.took, data.hasMore, template);
_this.processResponseTerms();
_this.processResponseSubjects();
_this.processResponseDatasources(data.resultDatasources);
},
error : function() {}
// Required for page reload in FF
$("#query_size").bind("slider:ready", function (event, data) {
$("#query_size_shown").text(data.value);
});
};
QueryHandler.prototype.processResponseSubjects = function() {
$("#search-results-subjects").html("<div id=\"subjects-wordcloud-Subject\" class=\"wordcloud\"></div><div id=\"subjects-wordcloud-significant-Subject\" class=\"wordcloud\"></div>");
var _this = this;
var tagQuery = this.buildQuery(false);
Search.prototype.initComponents = function() {
this.responseHandler = new ResponseHandler();
tagQuery.tagAggregators = ["Subject"];
tagQuery.size = this.options.wordcloud.tags.size;
$.ajax({
url: __util.composeUrl("query/tags/"),
data: JSON.stringify({query : tagQuery }),
context: {
aggs : tagQuery.tagAggregators,
},
type: "POST",
dataType: "json",
contentType: "application/json",
success: function(data) {
for (var i=0; i<this.aggs.length; i++) {
if (data.tags.hasOwnProperty(this.aggs[i])) {
_this.fillWordcloud("#subjects-wordcloud-" + this.aggs[i], data.tags[this.aggs[i]]);
}
}
},
error: __util.processServerError
this.queryHandler = new QueryHandler({
customSearch: this.options.customSearch,
responseHandler: this.responseHandler
});
}
QueryHandler.prototype.processResponseTerms = function() {
$("#search-results-terms").html("<div id=\"terms-wordcloud-Wordcloud\" class=\"wordcloud\"></div><div id=\"terms-wordcloud-significant-Wordcloud\" class=\"wordcloud\"></div>");
this.sourceSelection = new SourceSelection();
this.sourceSelection.init();
var _this = this;
var tagQuery = this.buildQuery(false);
tagQuery.tagAggregators = ["Wordcloud"];
tagQuery.size = this.options.wordcloud.tags.size;
$.ajax({
url: __util.composeUrl("query/tags/"),
data: JSON.stringify({query : tagQuery }),
context: {
aggs : tagQuery.tagAggregators,
},
type: "POST",
dataType: "json",
contentType: "application/json",
success: function(data) {
for (var i=0; i<this.aggs.length; i++) {
if (data.tags.hasOwnProperty(this.aggs[i])) {
_this.fillWordcloud("#terms-wordcloud-" + this.aggs[i], data.tags[this.aggs[i]]);
}
}
},
error: __util.processServerError
});
}
QueryHandler.prototype.processResponseDatasources = function(datasources) {
$("#search-results-collections").text("");
$(".search-available-collection-doccount").text("");
if (datasources==null || datasources.length==0) {
$("#search-results-collections-heading").text(__translator.translate("~eu.dariah.de.minfba.search.view.result.no_results"));
$("#search-results-collections").text("");
return;
}
var _this = this;
$("#search-results-collections-heading").text(String.format(__translator.translate("~eu.dariah.de.minfba.search.view.result.results_in_n_collections"), datasources.length));
for (var i=0; i<datasources.length; i++) {
var fmtDocCount = datasources[i].hitCount.toLocaleString();
var provider = "<div class=\"result-collection \">" +
"<h2>" + datasources[i].providerName + " <small>";
if (datasources[i].hitCount==1) {
provider += "1 " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.document");
} else {
provider += fmtDocCount + " " + __translator.translate("~eu.dariah.de.minfba.search.view.datamodel_info.documents");
}
provider += "</small></h2>";
provider += "<div id='collection-results-item'>" +
"<ul class='nav nav-tabs' role='tablist'>" +
"<li class='nav-item'>" +
"<a class='nav-link active' id='collection-results" + i + "-terms-tab' href='#collection-results" + i + "-terms-panel' data-toggle='tab' role='tab' aria-controls='collection-results" + i + "-terms-panel' aria-selected='true'>" +
__translator.translate("~eu.dariah.de.minfba.search.search.collections.terms") +
"</a>" +
"</li>" +
"<li class='nav-item'>" +
"<a class='nav-link' id='collection-results" + i + "-subjects-tab' href='#collection-results" + i + "-subjects-panel' data-toggle='tab' role='tab' aria-controls='collection-results" + i + "-subjects-panel' aria-selected='true'>" +
__translator.translate("~eu.dariah.de.minfba.search.search.collections.subjects") +
"</a>" +
"</li>" +
"</ul>" +
"<div class='tab-content'>" +
"<div class='tab-pane fade show active' id='collection-results" + i + "-terms-panel' role='tabpanel' aria-labelledby='collection-results" + i + "-terms-tab'>" +
"<div id=\"datasource-wordcloud-" + datasources[i].providerId + "-Wordcloud\" class=\"wordcloud\" style=\"height: " + this.options.wordcloud.height + "px;\"></div>" +
"</div>" +
"<div class='tab-pane fade' id='collection-results" + i + "-subjects-panel' role='tabpanel' aria-labelledby='collection-results" + i + "-subjects-tab'>" +
"<div id=\"datasource-wordcloud-" + datasources[i].providerId + "-Subject\" class=\"wordcloud\" style=\"height: " + this.options.wordcloud.height + "px;\"></div>" +
"</div>" +
"</div>" +
"</div>";
$("#search-results-collections").append(provider);
$("#search-available-collection-" + datasources[i].providerId).find(".search-available-collection-doccount").text(fmtDocCount);
var tagQuery = this.buildQuery(false);
// Deep clone of the original query
/*var tagQuery = jQuery.extend(true, {}, _this.query);*/
tagQuery.sourceIds = [ datasources[i].providerId ];
tagQuery.tagAggregators = ["Wordcloud", "Subject"];
tagQuery.size = this.options.wordcloud.tags.size;
if (datasources[i].loadTags) {
$.ajax({
url: __util.composeUrl("query/tags/"),
data: JSON.stringify({query : tagQuery }),
context: {
datasourceId: datasources[i].providerId,
aggs : tagQuery.tagAggregators
},
type: "POST",
dataType: "json",
contentType: "application/json",
success: function(data) {
for (var i=0; i<this.aggs.length; i++) {
if (data.tags.hasOwnProperty(this.aggs[i])) {
var onclick;
if (this.aggs[i]=="Wordcloud") {
onclick = function(tag) { _this.expandSearch(tag.text); }
} else {
onclick = function(tag) { _this.expandSearch(tag.text); }
}
_this.fillWordcloud("#datasource-wordcloud-" + this.datasourceId + "-" + this.aggs[i], data.tags[this.aggs[i]], false, onclick);
}
}
},
error: __util.processServerError
});
}
}
sourceSelection.renderDatasourceList();
};
QueryHandler.prototype.fillWordcloud = function(container, data, significant, onclick) {
var _this = this;
var tags = [];
for (var i=0; i<data.length; i++) {
tags.push({
text: data[i].term.length>35 ? (data[i].term.substring(0, 32) + "...") : data[i].term,
size: (data[i].weight * _this.options.wordcloud.tagsize.factor) + _this.options.wordcloud.tagsize.offset,
title: data[i].count + " occurences"
});
}
if (tags.length==0) {
if (significant) {
$(container).html(__translator.translate("~eu.dariah.de.minfba.search.view.result.no_significant_terms"));
} else {
$(container).html(__translator.translate("~eu.dariah.de.minfba.search.view.result.no_frequent_terms"));
}
return;
}
var width = $("#search-results-container").width() - 50;
this.clouds.push (new TagCloud({
tags: tags,
containerSelector: container,
animateTransform: _this.options.wordcloud.animate,
animateTransformDir: _this.options.wordcloud.animateDirection,
w: width,
h: _this.options.wordcloud.height,
textClickEvent: function(tag) { if (onclick!==undefined) { onclick(tag); } }
}));
this.vis = new Vis();
this.vis.init();
};
QueryHandler.prototype.processResponseResources = function(isShowMore, resultElements, startIndex, totalHits, took, hasMore, itemTemplate) {
if (isShowMore) {
$(".search-results-resources-show-more").addClass("hide");
} else {
$("#search-results-resources").html("");
}
if (resultElements==null || resultElements.length==0) {
$("#search-results-resources-heading").text(__translator.translate("~eu.dariah.de.minfba.search.view.result.no_results"));
$("#search-results-resources").text("");
return;
}
$("#search-results-resources-heading").text(String.format(__translator.translate("~eu.dariah.de.minfba.search.view.result.n_of_m_results"), resultElements.length, totalHits));
var explain = $("#explain").prop('checked');
for (var i=0; i<resultElements.length; i++) {
var content = [];
var hideElements = [];
content.push(["index", i]);
// TODO arrays, rest
content.push(["datasource", resultElements[i].collectionName]);
content.push(["resultId", encodeURIComponent(resultElements[i].id).replace(/[!'()]/g, escape).replace(/\*/g, "%2A")]);
content.push(["type", resultElements[i].datasetId]);
if (explain) {
content.push(["score", __translator.translate("~eu.dariah.de.minfba.search.view.result.resources.score") + ": " + resultElements[i].score]);
} else {