From ad636d308d4b59ee9c6b3576027e80e032ce7ed0 Mon Sep 17 00:00:00 2001 From: Stephan Porada Date: Tue, 22 Sep 2020 12:45:24 +0200 Subject: [PATCH] Bundle redundant event listeners. --- .../corpus_analysis/view/eventListeners.js | 216 ++++++++++++++++++ .../templates/corpora/analyse_corpus.html.j2 | 200 +++------------- .../templates/query_results/inspect.html.j2 | 87 ++----- 3 files changed, 257 insertions(+), 246 deletions(-) create mode 100644 web/app/static/js/modules/corpus_analysis/view/eventListeners.js diff --git a/web/app/static/js/modules/corpus_analysis/view/eventListeners.js b/web/app/static/js/modules/corpus_analysis/view/eventListeners.js new file mode 100644 index 00000000..3741955c --- /dev/null +++ b/web/app/static/js/modules/corpus_analysis/view/eventListeners.js @@ -0,0 +1,216 @@ +// Import the script that implements a spinner animation for buttons. +import { + loadingSpinnerHTML, +} from './spinner.js'; +/** + * This module contains vanilla javascript Event listeners which are listening + * for button clicks etc. the user is doing to interact with the page. + */ + +/** + * The following listener handles what functions are called when the user + * does use the page navigation to navigate to a new page. + */ + +function pageNavigation(resultsList, results, client) { + for (let element of resultsList.pagination) { + element.addEventListener("click", (event) => { + // Shows match context according to the user picked value on a new page. + resultsList.changeContext(); + // De- or activates expertMode on new page depending on switch value. + if (resultsList.displayOptionsFormExpertMode.checked) { + resultsList.expertModeOn('query-display', results); + } else { + resultsList.expertModeOff('query-display'); + } + // Activates inspect buttons on new page if client is not busy. + resultsList.toggleInspectButtons(client); + }); + } +} + +/** + * The following event Listener handles the expert mode switch for the list. + */ +function expertModeSwitch(resultsList, results) { + resultsList.displayOptionsFormExpertMode.onchange = (event) => { + if (event.target.checked) { + resultsList.expertModeOn('query-display', results); + } else { + resultsList.expertModeOff('query-display'); + } + }; +} + +/** + * The following event Listener handles the add-btn and the inspect-btn + * onclick events via bubbleing. + */ +function actionButtons(resultsList, results, client) { + resultsList.queryResultsTable.addEventListener('click', (event) => { + let dataIndex; + if (event.target.classList.contains('inspect-btn')) { + dataIndex = parseInt(event.target.closest('tr').dataset.index); + resultsList.inspect(client, results, [dataIndex], 'inspect'); + } else if (event.target.classList.contains('add-btn')) { + dataIndex = parseInt(event.target.closest('tr').dataset.index); + resultsList.addToSubResults(dataIndex, client); + } + }) +} + +/** + * Following event listeners handle the change of Context size per match and + * the number of matches shown per page. + */ +function displayOptions(resultsList, results, client) { + resultsList.displayOptionsFormResultsPerPage.onchange = (event) => { + resultsList.changeHitsPerPage(client, results); + }; + resultsList.displayOptionsFormResultContext.onchange = (event) => { + resultsList.changeContext(); + }; +} + +/** + * The following event listener handles the show metadata button and its + * functionality. + */ +function showMetaData(resultsList, results) { + resultsList.showMetaData.onclick = () => { + resultsList.metaDataModalContent.textContent = ''; + let table = resultsList.createMetaDataForModal(results.metaData); + resultsList.metaDataModalContent.insertAdjacentHTML('afterbegin', table); + resultsList.metaDataModal.open(); + let collapsibles = resultsList.metaDataModalContent.querySelectorAll(".text-metadata"); + for (let collapsible of collapsibles) { + collapsible.onclick = () => { + let elems = resultsList.metaDataModalContent.querySelectorAll('.collapsible'); + let instances = M.Collapsible.init(elems, {accordion: false}); + resultsList.createTextDetails(results.metaData); + } + } + }; +} + +/** + * Checks if resultsList.exportFullInspectContext switch is changed. + * If it has been changed reset all Download buttons. + */ +function exportFullContextSwitch(resultsList) { + resultsList.exportFullInspectContext.onchange = (event) => { + // Hide all download buttons. + resultsList.fullResultsExport.classList.toggle('hide', true); + resultsList.subResultsExport.classList.toggle('hide', true); + // Show result create buttons. + resultsList.fullResultsCreate.classList.toggle('hide', false); + resultsList.subResultsCreate.classList.toggle('hide', false); + } +} + +/** + * The following event listeners are handeling the data export. + * 1. Create full-results + * 2. Create sub-results + * 3. Download full-results + * 4. Download sub-results + * 5. Download single inspect-results + */ + +// 1. Add events for full-results create +function createFullResults(resultsList, results) { + resultsList.fullResultsCreate.onclick = (event) => { + resultsList.fullResultsCreate.querySelector('i').classList.toggle('hide'); + resultsList.fullResultsCreate.innerText = 'Creating...'; + resultsList.fullResultsCreate.insertAdjacentHTML('afterbegin', + loadingSpinnerHTML); + let dataIndexes = [...Array(results.data.match_count).keys()]; + // Empty fullResultsData so that no previous data is used. + results.fullResultsData.init(); + resultsList.notifyClient('get-results', { resultsType: 'full-results', + dataIndexes: dataIndexes, + resultsList: resultsList, + }); + } +} + +// 2. Add events for sub-results create +function createSubResults(resultsList, results) { + resultsList.subResultsCreate.onclick = (event) => { + let dataIndexes = []; + resultsList.addToSubResultsIdsToShow.forEach((id) => { + dataIndexes.push(id - 1); + }); + resultsList.subResultsCreate.querySelector('i').classList.toggle('hide'); + resultsList.subResultsCreate.innerText = 'Creating...'; + resultsList.subResultsCreate.insertAdjacentHTML('afterbegin', + loadingSpinnerHTML); + // Empty subResultsData so that no previous data is used. + results.subResultsData.init(); + resultsList.notifyClient('get-results', { resultsType: 'sub-results', + dataIndexes: dataIndexes, + resultsList: resultsList, + }); + } +} +// 3. Open download modal when full results export button is pressed +function exportFullResults(resultsList, results) { + resultsList.fullResultsExport.onclick = (event) => { + resultsList.queryResultsDownloadModal.open(); + // add onclick to download JSON button and download the file + resultsList.downloadResultsJson.onclick = (event) => { + let suffix = 'full-results' + if (resultsList.exportFullInspectContext.checked) { + suffix += '_full-context'; + } + let filename = results.fullResultsData.createDownloadFilename(suffix); + results.fullResultsData.addData(results.metaData); + results.fullResultsData.downloadJSONRessource(filename, + results.fullResultsData, + resultsList.downloadResultsJson)}; + } +} +// 4. Open download modal when sub results export button is pressed +function exportSubResults(resultsList, results) { + resultsList.subResultsExport.onclick = (event) => { + resultsList.queryResultsDownloadModal.open(); + // add onclick to download JSON button and download the file + resultsList.downloadResultsJson.onclick = (event) => { + let suffix = 'sub-results' + if (resultsList.exportFullInspectContext.checked) { + suffix += '_full-context'; + } + let filename = results.subResultsData.createDownloadFilename(suffix); + results.subResultsData.addData(results.metaData); + results.subResultsData.downloadJSONRessource(filename, + results.subResultsData, + resultsList.downloadResultsJson)}; + } +} +// 5. Open download modal when inspect-results-export button is pressed +function exportSingleMatch(resultsList, results) { + resultsList.inspectResultsExport.onclick = (event) => { + resultsList.queryResultsDownloadModal.open(); + // add onclick to download JSON button and download the file + resultsList.downloadResultsJson.onclick = (event) => { + let filename = results.subResultsData.createDownloadFilename('inspect-results_full-context'); + results.subResultsData.addData(results.metaData); + results.subResultsData.downloadJSONRessource(filename, + results.inspectResultsData, + resultsList.downloadResultsJson)}; + } +} + +export { + pageNavigation, + expertModeSwitch, + actionButtons, + displayOptions, + showMetaData, + exportFullContextSwitch, + createFullResults, + createSubResults, + exportFullResults, + exportSubResults, + exportSingleMatch, +} diff --git a/web/app/templates/corpora/analyse_corpus.html.j2 b/web/app/templates/corpora/analyse_corpus.html.j2 index 7f452930..08dd411a 100644 --- a/web/app/templates/corpora/analyse_corpus.html.j2 +++ b/web/app/templates/corpora/analyse_corpus.html.j2 @@ -118,11 +118,21 @@ import { // Import script that implements the scroll to top button. import { scrollToTop, -} from '../../static/js/modules/corpus_analysis/view/scrollToTop.js' -// Import the script that implements a spinner animation for buttons. +} from '../../static/js/modules/corpus_analysis/view/scrollToTop.js'; +// vanilla javascript Event listeners which are listening for button clicks etc import { - loadingSpinnerHTML, -} from '../../static/js/modules/corpus_analysis/view/spinner.js' + pageNavigation, + expertModeSwitch, + actionButtons, + displayOptions, + showMetaData, + exportFullContextSwitch, + createFullResults, + createSubResults, + exportFullResults, + exportSubResults, + exportSingleMatch, +} from '../../static/js/modules/corpus_analysis/view/eventListeners.js'; /** * Second Phase: @@ -249,175 +259,19 @@ document.addEventListener("DOMContentLoaded", () => { '#export-full-inspect-context', ]); - /** - * The following listener handles what functions are called when the user - * does use the page navigation to navigate to a new page. - */ - for (let element of resultsList.pagination) { - element.addEventListener("click", (event) => { - // Shows match context according to the user picked value on a new page. - resultsList.changeContext(); - // De- or activates expertMode on new page depending on switch value. - if (resultsList.displayOptionsFormExpertMode.checked) { - resultsList.expertModeOn('query-display', results); - } else { - resultsList.expertModeOff('query-display'); - } - // Activates inspect buttons on new page if client is not busy. - resultsList.toggleInspectButtons(client); - }); - } - - /** - * The following event Listener handles the expert mode switch for the list. - */ - resultsList.displayOptionsFormExpertMode.onchange = (event) => { - if (event.target.checked) { - resultsList.expertModeOn('query-display', results); - } else { - resultsList.expertModeOff('query-display'); - } - }; - - /** - * The following event Listener handles the add-btn and the inspect-btn - * onclick events via bubbleing. - */ - resultsList.queryResultsTable.addEventListener('click', (event) => { - let dataIndex; - if (event.target.classList.contains('inspect-btn')) { - dataIndex = parseInt(event.target.closest('tr').dataset.index); - resultsList.inspect(client, results, [dataIndex], 'inspect'); - } else if (event.target.classList.contains('add-btn')) { - dataIndex = parseInt(event.target.closest('tr').dataset.index); - resultsList.addToSubResults(dataIndex, client); - } - }) - - /** - * Following event listeners handle the change of Context size per match and - * the number of matches shown per page. - */ - resultsList.displayOptionsFormResultsPerPage.onchange = (event) => { - resultsList.changeHitsPerPage(client, results); - }; - resultsList.displayOptionsFormResultContext.onchange = (event) => { - resultsList.changeContext(); - }; - - /** - * The following event listener handles the show metadata button and its - * functionality. - */ - resultsList.showMetaData.onclick = () => { - resultsList.metaDataModalContent.textContent = ''; - let table = resultsList.createMetaDataForModal(results.metaData); - resultsList.metaDataModalContent.insertAdjacentHTML('afterbegin', table); - resultsList.metaDataModal.open(); - let collapsibles = resultsList.metaDataModalContent.querySelectorAll(".text-metadata"); - for (let collapsible of collapsibles) { - collapsible.onclick = () => { - let elems = resultsList.metaDataModalContent.querySelectorAll('.collapsible'); - let instances = M.Collapsible.init(elems, {accordion: false}); - resultsList.createTextDetails(results.metaData); - } - } - }; - - /** - * Checks if resultsList.exportFullInspectContext switch is changed.# - * If it has been changed reset all Download buttons. - */ - resultsList.exportFullInspectContext.onchange = (event) => { - // Hide all download buttons. - resultsList.fullResultsExport.classList.toggle('hide', true); - resultsList.subResultsExport.classList.toggle('hide', true); - // Show result create buttons. - resultsList.fullResultsCreate.classList.toggle('hide', false); - resultsList.subResultsCreate.classList.toggle('hide', false); - } - - /** - * The following event listeners are handeling the data export. - * 1. Create full-results - * 2. Create sub-results - * 3. Download full-results - * 4. Download sub-results - * 5. Download single inspect-results - */ - // 1. Add events for full-results create - resultsList.fullResultsCreate.onclick = (event) => { - resultsList.fullResultsCreate.querySelector('i').classList.toggle('hide'); - resultsList.fullResultsCreate.innerText = 'Creating...'; - resultsList.fullResultsCreate.insertAdjacentHTML('afterbegin', - loadingSpinnerHTML); - let dataIndexes = [...Array(results.data.match_count).keys()]; - // Empty fullResultsData so that no previous data is used. - results.fullResultsData.init(); - resultsList.notifyClient('get-results', { resultsType: 'full-results', - dataIndexes: dataIndexes, - resultsList: resultsList, - }); - } - // 2. Add events for sub-results create - resultsList.subResultsCreate.onclick = (event) => { - let dataIndexes = []; - resultsList.addToSubResultsIdsToShow.forEach((id) => { - dataIndexes.push(id - 1); - }); - resultsList.subResultsCreate.querySelector('i').classList.toggle('hide'); - resultsList.subResultsCreate.innerText = 'Creating...'; - resultsList.subResultsCreate.insertAdjacentHTML('afterbegin', - loadingSpinnerHTML); - // Empty subResultsData so that no previous data is used. - results.subResultsData.init(); - resultsList.notifyClient('get-results', { resultsType: 'sub-results', - dataIndexes: dataIndexes, - resultsList: resultsList, - }); - } - // 3. Open download modal when full results export button is pressed - resultsList.fullResultsExport.onclick = (event) => { - resultsList.queryResultsDownloadModal.open(); - // add onclick to download JSON button and download the file - resultsList.downloadResultsJson.onclick = (event) => { - let suffix = 'full-results' - if (resultsList.exportFullInspectContext.checked) { - suffix += '_full-context'; - } - let filename = results.fullResultsData.createDownloadFilename(suffix); - results.fullResultsData.addData(results.metaData); - results.fullResultsData.downloadJSONRessource(filename, - results.fullResultsData, - resultsList.downloadResultsJson)}; - } - // 4. Open download modal when sub results export button is pressed - resultsList.subResultsExport.onclick = (event) => { - resultsList.queryResultsDownloadModal.open(); - // add onclick to download JSON button and download the file - resultsList.downloadResultsJson.onclick = (event) => { - let suffix = 'sub-results' - if (resultsList.exportFullInspectContext.checked) { - suffix += '_full-context'; - } - let filename = results.subResultsData.createDownloadFilename(suffix); - results.subResultsData.addData(results.metaData); - results.subResultsData.downloadJSONRessource(filename, - results.subResultsData, - resultsList.downloadResultsJson)}; - } - // 5. Open download modal when inspect-results-export button is pressed - resultsList.inspectResultsExport.onclick = (event) => { - resultsList.queryResultsDownloadModal.open(); - // add onclick to download JSON button and download the file - resultsList.downloadResultsJson.onclick = (event) => { - let filename = results.subResultsData.createDownloadFilename('inspect-results_full-context'); - results.subResultsData.addData(results.metaData); - results.subResultsData.downloadJSONRessource(filename, - results.inspectResultsData, - resultsList.downloadResultsJson)}; - } - + // Call the vanilla event listeners listening for clicks etc. from the user. + pageNavigation(resultsList, results, client); + expertModeSwitch(resultsList, results); + actionButtons(resultsList, results, client); + displayOptions(resultsList, results, client); + showMetaData(resultsList, results); + // Still vanilla event listeners, but focused on result download and export + exportFullContextSwitch(resultsList); + createFullResults(resultsList, results); + createSubResults(resultsList, results); + exportFullResults(resultsList, results); + exportSubResults(resultsList, results); + exportSingleMatch(resultsList, results); // Enable scroll to Top functionality. scrollToTop('#headline', '#menu-scroll-to-top-div'); }); diff --git a/web/app/templates/query_results/inspect.html.j2 b/web/app/templates/query_results/inspect.html.j2 index 25a74683..0f1caf21 100644 --- a/web/app/templates/query_results/inspect.html.j2 +++ b/web/app/templates/query_results/inspect.html.j2 @@ -104,6 +104,14 @@ import { import { scrollToTop, } from '../../static/js/modules/corpus_analysis/view/scrollToTop.js' +// vanilla javascript Event listeners which are listening for button clicks etc +import { + pageNavigation, + expertModeSwitch, + actionButtons, + displayOptions, + showMetaData, +} from '../../static/js/modules/corpus_analysis/view/eventListeners.js'; /** * Second Phase: * Asynchronus and event driven code. @@ -184,80 +192,13 @@ document.addEventListener("DOMContentLoaded", () => { // Save meta data to results after the init callback from line above results.metaData = metaDataJson; client.eventListeners['corpus_analysis_query_results'].executeCallbacks([resultsJson]); - /** - * The following listener handles what functions are called when the user - * does use the page navigation to navigate to a new page. - */ - for (let element of resultsList.pagination) { - element.addEventListener("click", (event) => { - // Shows match context according to the user picked value on a new page. - resultsList.changeContext(); - // De- or activates expertMode on new page depending on switch value. - if (resultsList.displayOptionsFormExpertMode.checked) { - resultsList.expertModeOn('query-display', results); - } else { - resultsList.expertModeOff('query-display'); - } - // Activates inspect buttons on new page if client is not busy. - resultsList.toggleInspectButtons(client); - }); - } - /** - * The following event Listener handles the expert mode switch for the list. - */ - resultsList.displayOptionsFormExpertMode.onchange = (event) => { - if (event.target.checked) { - resultsList.expertModeOn('query-display', results); - } else { - resultsList.expertModeOff('query-display'); - } - }; - - /** - * The following event Listener handles the add-btn and the inspect-btn - * onclick events via bubbleing. - */ - resultsList.queryResultsTable.addEventListener('click', (event) => { - let dataIndex; - if (event.target.classList.contains('inspect-btn')) { - dataIndex = parseInt(event.target.closest('tr').dataset.index); - resultsList.inspect(client, results, [dataIndex], 'inspect'); - } else if (event.target.classList.contains('add-btn')) { - dataIndex = parseInt(event.target.closest('tr').dataset.index); - resultsList.addToSubResults(dataIndex, client); - } - }) - - /** - * Following event listeners handle the change of Context size per match and - * the number of matches shown per page. - */ - resultsList.displayOptionsFormResultsPerPage.onchange = (event) => { - resultsList.changeHitsPerPage(client, results); - }; - resultsList.displayOptionsFormResultContext.onchange = (event) => { - resultsList.changeContext(); - }; - - /** - * The following event listener handles the show metadata button and its - * functionality. - */ - resultsList.showMetaData.onclick = () => { - resultsList.metaDataModalContent.textContent = ''; - let table = resultsList.createMetaDataForModal(results.metaData); - resultsList.metaDataModalContent.insertAdjacentHTML('afterbegin', table); - resultsList.metaDataModal.open(); - let collapsibles = resultsList.metaDataModalContent.querySelectorAll(".text-metadata"); - for (let collapsible of collapsibles) { - collapsible.onclick = () => { - let elems = resultsList.metaDataModalContent.querySelectorAll('.collapsible'); - let instances = M.Collapsible.init(elems, {accordion: false}); - resultsList.createTextDetails(results.metaData); - } - } - }; + // Call the vanilla event listeners listening for clicks etc. from the user. + pageNavigation(resultsList, results, client); + expertModeSwitch(resultsList, results); + actionButtons(resultsList, results, client); + displayOptions(resultsList, results, client); + showMetaData(resultsList, results); // Enable scroll to Top functionality. scrollToTop('#headline', '#menu-scroll-to-top-div'); });