diff --git a/app/static/css/queryBuilder.css b/app/static/css/queryBuilder.css
index 6cc4a5a1..08bbb778 100644
--- a/app/static/css/queryBuilder.css
+++ b/app/static/css/queryBuilder.css
@@ -1,3 +1,12 @@
+#corpus-analysis-concordance-query-builder-input-field-container {
+ border-bottom: #9E9E9E 1px solid;
+ height: 60px;
+}
+
+#corpus-analysis-concordance-query-builder-input-field {
+ margin-top: 23px;
+}
+
.modal-content {
overflow-x: hidden;
}
@@ -79,40 +88,20 @@
margin-right: 10px;
}
-#corpus-analysis-concordance-ignore-case-checkbox {
- margin-left: 5px;
+[data-target="corpus-analysis-concordance-character-incidence-modifiers-dropdown"], [data-target="corpus-analysis-concordance-token-incidence-modifiers-dropdown"] {
+ background-color: #2FBBAB !important;
}
-#corpus-analysis-concordance-incidence-modifiers-dropdown a{
- background-color: white;
+#corpus-analysis-concordance-exactly-n-token-modal, #corpus-analysis-concordance-between-nm-token-modal {
+ width: 30%;
}
-[data-target="corpus-analysis-concordance-incidence-modifiers-dropdown"] {
- background-color: #2FBBAB;
+[data-modal-id="corpus-analysis-concordance-exactly-n-token-modal"], [data-modal-id="corpus-analysis-concordance-between-nm-token-modal"] {
+ margin-top: 15px !important;
}
-#corpus-analysis-concordance-or, #corpus-analysis-concordance-and {
- background-color: #fc0;
-}
-
-#corpus-analysis-concordance-betweenNM {
- width: 60%;
-}
-
-#corpus-analysis-concordance-query-builder-tutorial-modal {
- width: 60%;
-}
-
-#corpus-analysis-concordance-query-builder-tutorial-modal ul {
- margin-top: 10px;
-}
-
-#corpus-analysis-concordance-query-builder-tutorial {
- padding:15px;
-}
-
-#corpus-analysis-concordance-scroll-up-button-query-builder-tutorial {
- background-color: #28B3D1;
+[data-options-action="and"], [data-options-action="or"] {
+ background-color: #fc0 !important;
}
[data-type="start-sentence"], [data-type="end-sentence"] {
diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
index 891e12f7..91ce0f68 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
@@ -10,7 +10,8 @@ class CorpusAnalysisConcordance {
container: document.querySelector(`#corpus-analysis-concordance-container`),
error: document.querySelector(`#corpus-analysis-concordance-error`),
userInterfaceForm: document.querySelector(`#corpus-analysis-concordance-user-interface-form`),
- form: document.querySelector(`#corpus-analysis-concordance-form`),
+ expertModeForm: document.querySelector(`#corpus-analysis-concordance-expert-mode-form`),
+ queryBuilderForm: document.querySelector(`#corpus-analysis-concordance-query-builder-form`),
progress: document.querySelector(`#corpus-analysis-concordance-progress`),
subcorpusInfo: document.querySelector(`#corpus-analysis-concordance-subcorpus-info`),
subcorpusActions: document.querySelector(`#corpus-analysis-concordance-subcorpus-actions`),
@@ -30,12 +31,14 @@ class CorpusAnalysisConcordance {
this.app.registerExtension(this);
}
- async submitForm() {
+ async submitForm(queryModeId) {
this.app.disableActionElements();
- // let query = this.elements.form.query.value.trim();
- let query = this.checkQueryInput();
- console.log(query);
- let subcorpusName = this.elements.form['subcorpus-name'].value;
+ let queryBuilderQuery = document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim();
+ let expertModeQuery = this.elements.expertModeForm.query.value.trim();
+ let query = queryModeId === 'corpus-analysis-concordance-expert-mode-form' ? expertModeQuery : queryBuilderQuery;
+ let form = queryModeId === 'corpus-analysis-concordance-expert-mode-form' ? this.elements.expertModeForm : this.elements.queryBuilderForm;
+
+ let subcorpusName = form['subcorpus-name'].value;
this.elements.error.innerText = '';
this.elements.error.classList.add('hide');
this.elements.progress.classList.remove('hide');
@@ -74,9 +77,13 @@ class CorpusAnalysisConcordance {
this.data.corpus = this.app.data.corpus;
this.data.subcorpora = {};
// Add event listeners
- this.elements.form.addEventListener('submit', (event) => {
+ this.elements.expertModeForm.addEventListener('submit', (event) => {
event.preventDefault();
- this.submitForm();
+ this.submitForm(this.elements.expertModeForm.id);
+ });
+ this.elements.queryBuilderForm.addEventListener('submit', (event) => {
+ event.preventDefault();
+ this.submitForm(this.elements.queryBuilderForm.id);
});
this.elements.userInterfaceForm.addEventListener('change', (event) => {
if (event.target === this.elements.userInterfaceForm['context']) {
@@ -98,14 +105,6 @@ class CorpusAnalysisConcordance {
});
}
- checkQueryInput() {
- if (document.querySelector('#corpus-analysis-concordance-expert-mode-display').classList.contains('hide')) {
- return document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim();
- } else {
- return this.elements.form.query.value.trim();
- }
- }
-
clearSubcorpusList() {
this.elements.subcorpusList.innerHTML = '';
this.elements.subcorpusList.classList.add('hide');
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder.js
index 00388622..ad097048 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder.js
@@ -7,51 +7,6 @@ class ConcordanceQueryBuilder {
this.tokenAttributeBuilderFunctions = new TokenAttributeBuilderFunctionsQueryBuilder(this.elements);
this.structuralAttributeBuilderFunctions = new StructuralAttributeBuilderFunctionsQueryBuilder(this.elements);
- // Event listener for structural attribute modal
- document.querySelectorAll('[data-structural-attr-modal-action-button]').forEach(button => {
- button.addEventListener('click', () => {
- this.structuralAttributeBuilderFunctions.actionButtonInStrucAttrModalHandler(button.dataset.structuralAttrModalActionButton);
- });
- });
-
- // Event listener for token attribute modal
- this.elements.positionalAttrSelection.addEventListener('change', (event) => {
- this.generalFunctions.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
- if (event.target.value !== 'empty-token') {
- this.generalFunctions.toggleClass([event.target.value], 'hide', 'remove');
- this.generalFunctions.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
- this.tokenAttributeBuilderFunctions.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
- }
- if (event.target.value === 'word' || event.target.value === 'lemma') {
- this.generalFunctions.toggleClass(['input-field-options'], 'hide', 'remove');
- } else if (event.target.value === 'empty-token'){
- this.tokenAttributeBuilderFunctions.addTokenToQuery();
- } else {
- this.generalFunctions.toggleClass(['input-field-options'], 'hide', 'add');
- }
- });
- // Options for positional attribute selection
- document.querySelectorAll('.positional-attr-options-action-button[data-options-action]').forEach(button => {
- button.addEventListener('click', () => {this.tokenAttributeBuilderFunctions.actionButtonInOptionSectionHandler(button.dataset.optionsAction);});
- });
- document.querySelectorAll('.incidence-modifier-selection[data-incidence-modifier]').forEach(button => {
- button.addEventListener('click', () => {this.tokenAttributeBuilderFunctions.incidenceModifierHandler(button);});
- });
- document.querySelectorAll('.n-m-submit-button').forEach(button => {
- button.addEventListener('click', () => {
- this.tokenAttributeBuilderFunctions.nmSubmitHandler(button.dataset.modalId);
- });
- });
-
- // Initializing and styling the Materialize Chip components
- M.Chips.init(
- this.elements.queryInputField,
- {
- placeholder: 'Add your query here'
- }
- );
- document.querySelector('#corpus-analysis-concordance-form-query-builder input').style.setProperty('width', '150px', 'important');
-
this.elements.positionalAttrModal = M.Modal.init(
document.querySelector('#corpus-analysis-concordance-positional-attr-modal'),
{
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
index f75c3a99..c6dcd257 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
@@ -1,13 +1,11 @@
class ElementReferencesQueryBuilder {
constructor() {
// General Elements
- this.counter = 0;
- this.queryInputField = document.querySelector('#corpus-analysis-concordance-form-query-builder');
- this.queryInputFieldInstance = M.Chips.getInstance(this.queryInputField);
- this.queryInputFieldContent = [];
+ this.queryInputField = document.querySelector('#corpus-analysis-concordance-query-builder-input-field');
+ this.queryChipElements = [];
// Structural Attribute Builder Elements
- this.structuralAttrModalInstance = document.querySelector('#corpus-analysis-concordance-structural-attr-modal');
+ this.structuralAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-structural-attr-modal'));
this.sentenceElement = document.querySelector('[data-structural-attr-modal-action-button="sentence"]');
this.entityElement = document.querySelector('[data-structural-attr-modal-action-button="entity"]');
this.textAnnotationElement = document.querySelector('[data-structural-attr-modal-action-button="text-annotation"]');
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
index 0208442e..70b6115d 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
@@ -9,23 +9,29 @@ class GeneralFunctionsQueryBuilder {
});
}
+ updateChipList() {
+ this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.chip');
+ }
+
queryChipFactory(dataType, prettyQueryText, queryText) {
- this.elements.counter++;
- this.elements.queryInputFieldInstance.addChip({
- tag: prettyQueryText
- });
+ queryText = Utils.escape(queryText);
+ prettyQueryText = Utils.escape(prettyQueryText);
+ let queryChipElement = Utils.HTMLToElement(
+ `
+
+ ${prettyQueryText}
+ close
+
+ `
+ );
- let queryChipElementIndex = this.elements.queryInputFieldInstance.$chips.length - 1;
- let queryChipElement = this.elements.queryInputFieldInstance.$chips[queryChipElementIndex];
- queryChipElement.classList.add('query-component');
- queryChipElement.setAttribute('data-type', dataType);
- queryChipElement.setAttribute('data-query', queryText);
- queryChipElement.setAttribute('draggable', 'true');
-
- queryChipElement.addEventListener('click', () => this.deleteAttr(queryChipElement));
+ queryChipElement.addEventListener('click', () => this.selectChipElement(queryChipElement));
+ queryChipElement.querySelector('i').addEventListener('click', () => this.deleteChipElement(queryChipElement));
+
queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement));
queryChipElement.addEventListener('dragend', this.handleDragEnd);
-
+ this.elements.queryInputField.appendChild(queryChipElement);
+ this.updateChipList();
this.queryPreviewBuilder();
}
@@ -65,45 +71,51 @@ class GeneralFunctionsQueryBuilder {
targetChipClone.addEventListener('drop', (event) => {
let dropzone = event.target;
dropzone.parentElement.replaceChild(queryChipElement, dropzone);
- this.elements.queryInputFieldInstance.$chips = Array.from(this.elements.queryInputField.querySelectorAll('.chip'));
+ this.updateChipList();
this.queryPreviewBuilder();
});
}
queryPreviewBuilder() {
let queryPreview = document.querySelector('#corpus-analysis-concordance-query-preview');
- let queryChipElements = Array.from(Object.values(this.elements.queryInputFieldInstance.$chips));
- if (!isNaN(queryChipElements[queryChipElements.length - 1])) {
- queryChipElements.pop();
- }
- this.elements.queryInputFieldContent = [];
- queryChipElements.forEach(element => {
-
+ let queryInputFieldContent = [];
+ this.elements.queryChipElements.forEach(element => {
let queryElement = element.dataset.query;
if (queryElement !== undefined) {
queryElement = Utils.escape(queryElement);
- this.elements.queryInputFieldContent.push(queryElement);
}
+ queryInputFieldContent.push(queryElement);
});
- let queryString = this.elements.queryInputFieldContent.join(' ');
+ let queryString = queryInputFieldContent.join(' ');
queryString += ';';
queryPreview.innerHTML = queryString;
queryPreview.parentNode.classList.toggle('hide', queryString === ';');
}
- deleteAttr(attr) {
+ deleteChipElement(attr) {
if (attr.dataset.type === "start-sentence") {
this.elements.sentenceElement.innerHTML = 'Sentence';
} else if (attr.dataset.type === "start-entity" || attr.dataset.type === "start-empty-entity") {
this.elements.entityElement.innerHTML = 'Entity';
}
- let queryChipElements = Array.from(Object.values(this.elements.queryInputFieldInstance.$chips));
- queryChipElements.pop();
- this.elements.counter -= 1;
- this.elements.queryInputFieldInstance.deleteChip(queryChipElements.indexOf(attr));
+ this.elements.queryInputField.removeChild(attr);
+ this.updateChipList();
this.queryPreviewBuilder();
}
+
+ selectChipElement(attr) {
+ document.querySelectorAll('.chip.teal').forEach(element => {
+ if (element !== attr) {
+ element.classList.remove('teal', 'lighten-2');
+ this.toggleClass(['token-incidence-modifiers'], 'disabled', 'add');
+ }
+ });
+
+ this.toggleClass(['token-incidence-modifiers'], 'disabled', 'toggle');
+ attr.classList.toggle('teal');
+ attr.classList.toggle('lighten-2');
+}
}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
index 8b65619f..742533de 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
@@ -2,11 +2,32 @@ class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQu
constructor(elements) {
super(elements);
this.elements = elements;
+
+ document.querySelectorAll('[data-structural-attr-modal-action-button]').forEach(button => {
+ button.addEventListener('click', () => {
+ this.actionButtonInStrucAttrModalHandler(button.dataset.structuralAttrModalActionButton);
+ });
+ });
+ document.querySelector('.ent-type-selection-action[data-ent-type="any"]').addEventListener('click', () => {
+ this.queryChipFactory('start-empty-entity', 'Entity Start', '');
+ this.queryChipFactory('end-sentence', 'Sentence End', '');
+ this.elements.structuralAttrModal.close();
break;
case 'entity':
this.toggleClass(['entity-builder'], 'hide', 'toggle');
@@ -20,4 +41,5 @@ class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQu
break;
}
}
+
}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
index bef06116..d887f341 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
@@ -3,6 +3,36 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
super(elements);
this.elements = elements;
+ this.elements.positionalAttrSelection.addEventListener('change', (event) => {
+ this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
+ if (event.target.value !== 'empty-token') {
+ this.toggleClass([event.target.value], 'hide', 'remove');
+ this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
+ this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
+ }
+ if (event.target.value === 'word' || event.target.value === 'lemma') {
+ this.toggleClass(['input-field-options'], 'hide', 'remove');
+ } else if (event.target.value === 'empty-token'){
+ this.addTokenToQuery();
+ } else {
+ this.toggleClass(['input-field-options'], 'hide', 'add');
+ }
+ });
+
+ // Options for positional attribute selection
+ 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();});
this.elements.wordInput.addEventListener('input', () => {this.optionToggleHandler();});
this.elements.lemmaInput.addEventListener('input', () => {this.optionToggleHandler();});
@@ -119,7 +149,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
- tokenQueryCQLText += `simple_pos="${this.elements.simplePosSelection.value}"`;
+ tokenQueryCQLText += `simple_pos='${this.elements.simplePosSelection.value}'`;
this.elements.simplePosSelection.value = '';
}
break;
@@ -149,7 +179,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
input.setSelectionRange(firstIndex, lastIndex);
break;
case 'wildcard-char':
- input.value += '.';
+ input.value += '.';
break;
case 'and':
this.conditionHandler('and', " & ");
@@ -195,7 +225,8 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
nmSubmitHandler(modalId) {
let modal = document.querySelector(`#${modalId}`);
let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value;
- let input_m = modalId === 'corpus-analysis-concordance-between-nm-modal' ? ',' + modal.querySelector('.n-m-input[data-value-type="m"]').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 instance = M.Modal.getInstance(modal);
diff --git a/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2 b/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2
index d6b112eb..f0a1133e 100644
--- a/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2
+++ b/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2
@@ -1,6 +1,6 @@
{% macro card_content(id_prefix) %}