From 9ccab8657acf334a961252c7efb3a23cbfe5d16c Mon Sep 17 00:00:00 2001 From: Inga Kirschnick Date: Tue, 29 Aug 2023 17:06:10 +0200 Subject: [PATCH] Query Builder: Incidence Modifier for tokens --- app/static/css/queryBuilder.css | 5 ++ app/static/js/CorpusAnalysis/QueryBuilder.js | 20 ++++++++ .../GeneralFunctionsQueryBuilder.js | 49 +++++++++++++++++-- ...enAttributeBuilderFunctionsQueryBuilder.js | 12 +---- 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/app/static/css/queryBuilder.css b/app/static/css/queryBuilder.css index 08bbb778..4886e9a2 100644 --- a/app/static/css/queryBuilder.css +++ b/app/static/css/queryBuilder.css @@ -119,3 +119,8 @@ [data-type="token"] { background-color: #28B3D1; } + +[data-type="token-incidence-modifier"] { + background-color: #4db6ac; + color: white; +} diff --git a/app/static/js/CorpusAnalysis/QueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder.js index ad097048..51b7653b 100644 --- a/app/static/js/CorpusAnalysis/QueryBuilder.js +++ b/app/static/js/CorpusAnalysis/QueryBuilder.js @@ -7,6 +7,26 @@ class ConcordanceQueryBuilder { this.tokenAttributeBuilderFunctions = new TokenAttributeBuilderFunctionsQueryBuilder(this.elements); this.structuralAttributeBuilderFunctions = new StructuralAttributeBuilderFunctionsQueryBuilder(this.elements); + document.querySelectorAll('.incidence-modifier-selection').forEach(button => { + if (button.parentNode.parentNode.id === 'corpus-analysis-concordance-token-incidence-modifiers-dropdown') { + button.addEventListener('click', () => { + this.generalFunctions.tokenIncidenceModifierHandler(button.dataset.token, button.innerHTML);}); + } else if (button.parentNode.parentNode.id === 'corpus-analysis-concordance-character-incidence-modifiers-dropdown') { + button.addEventListener('click', () => {this.tokenAttributeBuilderFunctions.characterIncidenceModifierHandler(button);}); + } + }); + document.querySelectorAll('.n-m-submit-button').forEach(button => { + if (button.dataset.modalId === 'corpus-analysis-concordance-exactly-n-token-modal' || button.dataset.modalId === 'corpus-analysis-concordance-between-nm-token-modal') { + button.addEventListener('click', () => { + this.generalFunctions.tokenNMSubmitHandler(button.dataset.modalId); + }); + } else if (button.dataset.modalId === 'corpus-analysis-concordance-exactly-n-character-modal' || button.dataset.modalId === 'corpus-analysis-concordance-between-nm-character-modal') { + button.addEventListener('click', () => { + this.generalFunctions.characterNMSubmitHandler(button.dataset.modalId); + }); + } + }); + this.elements.positionalAttrModal = M.Modal.init( document.querySelector('#corpus-analysis-concordance-positional-attr-modal'), { diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js index 70b6115d..e718e811 100644 --- a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js +++ b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js @@ -13,7 +13,7 @@ class GeneralFunctionsQueryBuilder { this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.chip'); } - queryChipFactory(dataType, prettyQueryText, queryText) { + queryChipFactory(dataType, prettyQueryText, queryText, index = null) { queryText = Utils.escape(queryText); prettyQueryText = Utils.escape(prettyQueryText); let queryChipElement = Utils.HTMLToElement( @@ -30,7 +30,11 @@ class GeneralFunctionsQueryBuilder { queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement)); queryChipElement.addEventListener('dragend', this.handleDragEnd); - this.elements.queryInputField.appendChild(queryChipElement); + if (index !== null) { + this.elements.queryInputField.insertBefore(queryChipElement, this.elements.queryChipElements[index]); + } else { + this.elements.queryInputField.appendChild(queryChipElement); + } this.updateChipList(); this.queryPreviewBuilder(); } @@ -88,6 +92,18 @@ class GeneralFunctionsQueryBuilder { }); let queryString = queryInputFieldContent.join(' '); + if (queryString.includes(' +')) { + queryString = queryString.replace(/ \+/g, '+'); + } + if (queryString.includes(' *')) { + queryString = queryString.replace(/ \*/g, '*'); + } + if (queryString.includes(' ?')) { + queryString = queryString.replace(/ \?/g, '?'); + } + if (queryString.includes(' {')) { + queryString = queryString.replace(/ \{/g, '{'); + } queryString += ';'; queryPreview.innerHTML = queryString; @@ -115,7 +131,32 @@ class GeneralFunctionsQueryBuilder { this.toggleClass(['token-incidence-modifiers'], 'disabled', 'toggle'); attr.classList.toggle('teal'); - attr.classList.toggle('lighten-2'); -} + attr.classList.toggle('lighten-5'); + } + + tokenIncidenceModifierHandler(incidenceModifier, incidenceModifierPretty) { + let selectedChip = this.elements.queryInputField.querySelector('.chip.teal'); + let selectedChipIndex = Array.from(this.elements.queryInputField.children).indexOf(selectedChip); + this.queryChipFactory('token-incidence-modifier', incidenceModifierPretty, incidenceModifier, selectedChipIndex+1); + this.selectChipElement(selectedChip); + } + + tokenNMSubmitHandler(modalId) { + let modal = document.querySelector(`#${modalId}`); + let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value; + let input_m = modal.querySelector('.n-m-input[data-value-type="m"]') || undefined; + input_m = input_m !== undefined ? input_m.value : ''; + let input = `{${input_n},${input_m}}`; + let pretty_input = `between ${input_n} and ${input_m} (${input})`; + if (input_m === '') { + pretty_input = `exactly ${input_n} (${input})`; + } + + let instance = M.Modal.getInstance(modal); + instance.close(); + + this.tokenIncidenceModifierHandler(input, pretty_input); + + } } diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js index d887f341..dff14554 100644 --- a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js +++ b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js @@ -23,14 +23,6 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu document.querySelectorAll('.positional-attr-options-action-button[data-options-action]').forEach(button => { button.addEventListener('click', () => {this.actionButtonInOptionSectionHandler(button.dataset.optionsAction);}); }); - document.querySelectorAll('.incidence-modifier-selection[data-incidence-modifier]').forEach(button => { - button.addEventListener('click', () => {this.incidenceModifierHandler(button);}); - }); - document.querySelectorAll('.n-m-submit-button').forEach(button => { - button.addEventListener('click', () => { - this.nmSubmitHandler(button.dataset.modalId); - }); - }); // Eventlistener for kind of token this.elements.tokenSubmitButton.addEventListener('click', () => {this.addTokenToQuery();}); @@ -193,7 +185,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu this.optionToggleHandler(); } - incidenceModifierHandler(elem) { + characterIncidenceModifierHandler(elem) { // For word and lemma, the incidence modifiers are inserted in the input field. For the others, one or two chips are created which contain the respective value of the token and the incidence modifier. switch (this.elements.positionalAttrSelection.value) { case 'empty-token': @@ -222,7 +214,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu } } - nmSubmitHandler(modalId) { + characterNMSubmitHandler(modalId) { let modal = document.querySelector(`#${modalId}`); let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value; let input_m = modal.querySelector('.n-m-input[data-value-type="m"]') || undefined;