Skip to content

Instantly share code, notes, and snippets.

@TrueType
Created December 1, 2022 13:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TrueType/557bc9f1cd3fcc73ae3414efe89b06bd to your computer and use it in GitHub Desktop.
Save TrueType/557bc9f1cd3fcc73ae3414efe89b06bd to your computer and use it in GitHub Desktop.
'use strict';
class Elasticsearch {
$elasticsearch;
$form;
$searchwords;
awesomplete;
ajaxUrl = '/?type=215236';
isHeaderMode;
data;
page;
limit;
constructor(elasticsearch) {
let that = this;
this.$elasticsearch = $(elasticsearch);
this.$form = this.$elasticsearch.find('form.elasticsearch__filters');
this.$searchwords = this.$form.find('input.searchwords');
this.isHeaderMode = this.$form.find('.isHeaderMode').length === 1;
this.$searchresults = this.$elasticsearch.find('.searchresults');
this.page = this.$form.find('.pagination_page').val();
this.limit = this.$form.find('.pagination_perpage').val();
this.$form.on('submit', this.get_search_results);
if (!this.isHeaderMode) {
this.$form.submit();
this.$form.find('.showAllFilters').show();
} else {
this.$searchwords.parent().removeClass('row');
}
this.$searchwords.after('<button class="header_searchfield_button_submit" aria-label="Suche starten">' +
' <i class="header_searchfield_button_icon fas fa-search"></i>' +
'</button>');
this.$elasticsearch.find('.header_searchfield_button_icon').on('click', function() {
that.$form.submit()})
this.awesomplete = new Awesomplete(this.$searchwords[0], {
list: []
});
this.$searchwords.on('keyup', this.autocompletion);
this.$searchwords.on('awesomplete-selectcomplete', function() {
that.$form.submit();
})
this.$form.find('.timefilter_selector,.mediatype_selector').on('change', function(){
that.$form.submit();
});
this.$form.find('.reset').on('click', function(e) {
that.$searchwords.val('');
that.$form.find('.timefilter_selector,.mediatype_selector').val(null);
that.$form.submit();
})
this.$form.find('.search-help-button').on('click', function() {
that.$form.find('.search-help-text').toggleClass('d-none');
})
this.$searchresults.find('.pagination_next_page').on('click', function(event) {
event.preventDefault();
that.$searchresults.find('.page-item.active').next('.page-item').find('a').click();
})
this.$searchresults.find('.pagination_previous_page').on('click', function(event) {
event.preventDefault();
that.$searchresults.find('.page-item.active').prev('.page-item').find('a').click();
})
}
/**
* provide autocomplete functionality
* @param event
*/
autocompletion = event => {
const upDownKeys = [13, 38, 40];
if (upDownKeys.includes(event.keyCode || event.which)) {
return;
}
this.awesomplete.list = [];
const $input = $(event.target);
const searchstring = $input.val().trim().toLowerCase();
if (searchstring.length === 0) {
return;
}
// be careful with .pop()
let allWords = searchstring.split(' ');
allWords.pop();
let fullWords = allWords;
let that = this;
this.$form.find('input.prefix').val(1)
$.ajax({
method: 'POST',
url: this.ajaxUrl,
dataType: 'json',
data: this.$form.serialize(),
async: true,
success: function(data) {
if (data['success'] === false) {
console.log(data['message']);
return;
}
let words = [];
let wordsOriginal = [];
for (let i = 0; i < data['results']['hits']['hits'].length ; i++) {
let result = data['results']['hits']['hits'][i];
if (typeof result.highlight === 'undefined') {
continue;
}
for (let x in result.highlight) {
for (let j = 0; j < result.highlight[x].length; j++) {
let startSplits = [];
startSplits = result.highlight[x][j].split('HIGHLIGHT_START');
for (let m = 0; m < startSplits.length; m++) {
let endSplits = startSplits[m].split('HIGHLIGHT_END');
if (endSplits.length !== 2) {
continue;
}
const wordOriginal = endSplits[0];
const word = wordOriginal.toLowerCase();
if (fullWords.includes(word)) {
continue;
}
if (words.includes(word)) {
continue;
}
words.push(word);
wordsOriginal.push(wordOriginal);
}
}
}
}
let autocompletes = [];
for (let i = 0; i < wordsOriginal.length; i++) {
autocompletes.push((fullWords.length ? (fullWords.join(' ') + ' ') : '') + wordsOriginal[i])
}
that.awesomplete.list = autocompletes;
that.$searchwords.focus();
},
error: function() {
console.log('Es ist ein Fehler aufgetreten!');
}
})
}
/**
* search results
* @param event
*/
get_search_results = event => {
event.preventDefault();
this.$form.find('input.prefix').val(0)
let that = this;
$.ajax({
method: 'POST',
url: this.ajaxUrl,
dataType: 'json',
data: this.$form.serialize(),
success: function(data) {
if (data['success'] === false) {
console.log(data['message']);
return;
}
if (that.isHeaderMode) {
window.location.href = that.$form.attr('action');
return;
}
that.data = data;
if (that.data.params.searchObject.initialize > 0) {
that.$form.find('input.initialize').val(0);
return;
}
that.resultlist_draw();
that.pagination_draw();
},
error: function() {
console.log('Es ist ein Fehler aufgetreten!');
}
})
}
/**
* draw search result list
*/
resultlist_draw = () => {
let $resultlist = this.$searchresults.find('.searchresultlist');
$resultlist.empty();
if ( typeof this.data.results === 'undefined'
|| typeof this.data.results.hits.hits.length === 'undefined'
) {
this.$elasticsearch.find('.searchresultlist_placeholder').show();
return;
}
this.$elasticsearch.find('.searchresultlist_placeholder').hide();
let from = (((this.page - 1) * this.limit) + 1);
let until = (this.page * this.limit);
if (until > this.data['results']['hits']['total']['value']) {
until = this.data['results']['hits']['total']['value'];
}
let counter_display;
if (this.data['results']['hits']['total']['value'] > 0) {
counter_display =
'<div class="searchresultlist-count">' +
'<h2>Suchergebnisse:</h2>' +
'Ergebnisse: Zeige <b>' + from + '</b> bis <b>' + until +
'</b> von <span class="searchresultlist-count__number font-weight-bold">' + this.data['results']['hits']['total']['value'] +
'</span>' +
'</div>'
;
} else {
counter_display = 'Anzahl der Ergebnisse: <b>0</b>'
}
$resultlist.append(counter_display);
let $resulttemplate = this.$elasticsearch.find('.searchresulttemplate .searchresult');
for (let i = 0; i < this.data['results']['hits']['hits'].length ; i++) {
let result = this.data['results']['hits']['hits'][i];
let $searchresult = $resulttemplate.clone();
let uri = result['_source']['url'];
if (typeof uri !== 'undefined' && uri.length > 0) {
if (uri.indexOf('fileadmin/') === 0 ) {
uri = '/' + uri;
}
$searchresult.find('.title a').attr('href', uri);
$searchresult.find('.resulturi a').attr('href', uri).html(decodeURI(uri));
} else {
$searchresult.find('.resulturi a').html('<span style="background-color:red;">Missing URL</span>');
}
if (typeof result['_source']['title'] !== 'undefined') {
let title = result['_source']['title'];
if (typeof result['highlight'] !== 'undefined' && typeof result['highlight']['title'] !== 'undefined' && result['highlight']['title'].length > 0) {
title = result['highlight']['title'][0];
title = title.replace(/(<([^>]+)>)/gi, "");
title = title.replace(/HIGHLIGHT_START/gi, '<span class="highlighted">');
title = title.replace(/HIGHLIGHT_END/gi, '</span>')
}
$searchresult.find('.title h3').html(title).on('click', function() {
window.location = uri;
});
}
if (typeof result['_source']['tstamp'] != 'undefined') {
let date = new Date(result['_source']['tstamp']*1000);
let day = date.getDate().length === 1 ? '0' + date.getDate() : date.getDate();
let month = date.getMonth()+1;
month = month.length === 1 ? '0' + month : month;
$searchresult.find('.timestamp').html(day + '.' + month + '.' + date.getFullYear());
}
// media type
let labels = {
ckan: 'Datensatz',
page: 'Webseite',
news: 'Aktuelles/Events',
file: 'Datei'
}
$searchresult.find('.mediatype').text(labels[result['_source']['type']]);
// content
if (typeof result['highlight'] !== 'undefined' && typeof result['highlight']['content'] !== 'undefined' && result['highlight']['content'].length > 0) {
result['highlight']['content'].forEach(function (value,i ) {
value = value.replace(/(<([^>]+)>)/gi, "");
value = value.replace(/HIGHLIGHT_START/gi, '<span class="highlighted">')
value = value.replace(/HIGHLIGHT_END/gi, '</span>')
$searchresult.find('.content').append('<span> ... ' + value + ' ... </span>');
});
}
// add to list
$resultlist.append($searchresult);
}
}
/**
* draw the pagination
*/
pagination_draw = () => {
this.$elasticsearch.find('.pagination_next_page').hide();
this.$elasticsearch.find('.pagination_previous_page').hide();
let $pagination = this.$elasticsearch.find('.pagination_list');
if (this.data['results']['hits']['total']['value'] > this.limit) {
this.$elasticsearch.find('.pagination_next_page').show();
this.$elasticsearch.find('.pagination_previous_page').show();
}
let totalResults = this.data['results']['hits']['total']['value'];
let resultsPerPage = parseInt(this.limit);
let page = parseInt(this.data.params.searchObject.page);
let showPages = 10;
let totalPages = Math.ceil(totalResults/resultsPerPage);
let start = 1;
let calcStartPage = page - (showPages / 2);
if (calcStartPage > 1) {
start = calcStartPage;
}
let calcEndPage = page + (showPages / 2);
if (calcEndPage < showPages) {
calcEndPage = showPages;
}
if (calcEndPage > totalPages) {
calcEndPage = totalPages;
}
$pagination.find('.bind-page').remove();
if (totalPages > 1){
let liLinkHtml = '';
for(let i=start; i<=calcEndPage; i++){
let activeClass = '';
let isActive = false;
if (parseInt(this.data.params.searchObject.page) === i){
activeClass = 'active';
isActive = true
}
liLinkHtml+= '<li class="page-item bind-page '+activeClass+'">' +
'<a href="javascript:void(0);" class="page-link" data-value="'+i+'" data-active="'+isActive+'" aria-label="Zu Seite '+i+'">'+i+'</a>' +
'</li>';
}
$pagination.find('.bind-prev:eq(0)').after($(liLinkHtml));
}
/* reset form value per default on page = 1 */
this.$form.find('.pagination_page').val(1);
this.page = 1;
let that = this;
$pagination.find('.bind-page .page-link').on('click', function() {
let attrDataValue = parseInt($(this).attr('data-value'));
that.page = attrDataValue;
that.$form.find('.pagination_page').val(that.page);
window.location.hash = '#top';
that.$form.submit();
});
}
}
$('.elasticsearch').each(function() {
new Elasticsearch(this);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment