diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
index 6af78603..485daeb9 100644
--- a/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
+++ b/app/static/js/CorpusAnalysis/CorpusAnalysisConcordance.js
@@ -10,6 +10,7 @@ class CorpusAnalysisConcordance {
// TODO: Prefix elements with "corpus-analysis-app-"
container: document.querySelector('#concordance-extension-container'),
error: document.querySelector('#concordance-extension-error'),
+ UIForm: document.querySelector('#concordance-extension-ui-form'),
form: document.querySelector('#concordance-extension-form'),
progress: document.querySelector('#concordance-extension-progress'),
subcorpusInfo: document.querySelector('#concordance-extension-subcorpus-info'),
@@ -20,12 +21,13 @@ class CorpusAnalysisConcordance {
};
this.settings = {
- context: parseInt(this.elements.form['context'].value),
- perPage: parseInt(this.elements.form['per-page'].value),
+ context: parseInt(this.elements.UIForm['context'].value),
+ perPage: parseInt(this.elements.UIForm['per-page'].value),
selectedSubcorpus: undefined,
- textStyle: parseInt(this.elements.form['text-style'].value),
- tokenRepresentation: this.elements.form['token-representation'].value
+ textStyle: parseInt(this.elements.UIForm['text-style'].value),
+ tokenRepresentation: this.elements.UIForm['token-representation'].value
};
+ console.log(this.settings);
this.app.registerExtension(this);
}
@@ -76,21 +78,24 @@ class CorpusAnalysisConcordance {
event.preventDefault();
this.submitForm();
});
- this.elements.form.addEventListener('change', (event) => {
- if (event.target === this.elements.form['context']) {
- this.settings.context = parseInt(this.elements.form['context'].value);
+ this.elements.UIForm.addEventListener('change', (event) => {
+ if (event.target === this.elements.UIForm['context']) {
+ console.log(this.settings.context);
+ console.log(parseInt(this.elements.UIForm['context'].value));
+ this.settings.context = parseInt(this.elements.UIForm['context'].value);
+ console.log(this.settings.context);
this.submitForm();
}
- if (event.target === this.elements.form['per-page']) {
- this.settings.perPage = parseInt(this.elements.form['per-page'].value);
+ if (event.target === this.elements.UIForm['per-page']) {
+ this.settings.perPage = parseInt(this.elements.UIForm['per-page'].value);
this.submitForm();
}
- if (event.target === this.elements.form['text-style']) {
- this.settings.textStyle = parseInt(this.elements.form['text-style'].value);
+ if (event.target === this.elements.UIForm['text-style']) {
+ this.settings.textStyle = parseInt(this.elements.UIForm['text-style'].value);
this.setTextStyle();
}
- if (event.target === this.elements.form['token-representation']) {
- this.settings.tokenRepresentation = this.elements.form['token-representation'].value;
+ if (event.target === this.elements.UIForm['token-representation']) {
+ this.settings.tokenRepresentation = this.elements.UIForm['token-representation'].value;
this.setTokenRepresentation();
}
});
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder.js
index 9163b4bc..b8567b35 100644
--- a/app/static/js/CorpusAnalysis/QueryBuilder.js
+++ b/app/static/js/CorpusAnalysis/QueryBuilder.js
@@ -1,166 +1,54 @@
class ConcordanceQueryBuilder {
constructor() {
-
-
- this.elements = {
-
- counter: 0,
- yourQueryContent: [],
- queryContent:[],
- concordanceQueryBuilder: document.querySelector('#concordance-query-builder'),
- concordanceQueryBuilderButton: document.querySelector('#concordance-query-builder-button'),
- closeQueryBuilder: document.querySelector('#close-query-builder'),
- queryBuilderTutorialModal: document.querySelector('#query-builder-tutorial-modal'),
- valueValidator: true,
-
-
- //#region QueryBuilder Elements
-
- positionalAttrButton: document.querySelector('#positional-attr-button'),
- positionalAttrArea: document.querySelector('#positional-attr'),
- positionalAttr: document.querySelector('#token-attr'),
- structuralAttrButton: document.querySelector('#structural-attr-button'),
- structuralAttrArea: document.querySelector('#structural-attr'),
- queryContainer: document.querySelector('#query-container'),
- buttonPreparer: document.querySelector('#button-preparer'),
- yourQuery: document.querySelector('#your-query'),
- insertQueryButton: document.querySelector('#insert-query-button'),
- queryPreview: document.querySelector('#query-preview'),
- tokenQuery: document.querySelector('#token-query'),
- tokenBuilderContent: document.querySelector('#token-builder-content'),
- tokenSubmitButton: document.querySelector('#token-submit'),
- extFormQuery: document.querySelector('#concordance-extension-form-query'),
- dropButton: '',
-
- queryBuilderTutorialInfoIcon: document.querySelector('#query-builder-tutorial-info-icon'),
- tokenTutorialInfoIcon: document.querySelector('#token-tutorial-info-icon'),
- editTokenTutorialInfoIcon: document.querySelector('#edit-options-tutorial-info-icon'),
- structuralAttributeTutorialInfoIcon: document.querySelector('#add-structural-attribute-tutorial-info-icon'),
- generalOptionsQueryBuilderTutorialInfoIcon: document.querySelector('#general-options-query-builder-tutorial-info-icon'),
-
-
- //#endregion QueryBuilder Elements
-
- //#region Strucutral Attributes
-
- sentence:document.querySelector('#sentence'),
- entity: document.querySelector('#entity'),
- textAnnotation: document.querySelector('#text-annotation'),
-
- entityBuilder: document.querySelector('#entity-builder'),
- englishEntType: document.querySelector('#english-ent-type'),
- germanEntType: document.querySelector('#german-ent-type'),
- emptyEntity: document.querySelector('#empty-entity'),
- entityAnyType: false,
-
- textAnnotationBuilder: document.querySelector('#text-annotation-builder'),
- textAnnotationOptions: document.querySelector('#text-annotation-options'),
- textAnnotationInput: document.querySelector('#text-annotation-input'),
- textAnnotationSubmit: document.querySelector('#text-annotation-submit'),
- noValueMetadataMessage: document.querySelector('#no-value-metadata-message'),
- //#endregion Structural Attributes
-
- //#region Token Attributes
- tokenQueryFilled: false,
-
- lemma: document.querySelector('#lemma'),
- emptyToken: document.querySelector('#empty-token'),
- word: document.querySelector('#word'),
- lemma: document.querySelector('#lemma'),
- pos: document.querySelector('#pos'),
- simplePosButton: document.querySelector('#simple-pos-button'),
- incidenceModifiers: document.querySelector('[data-target="incidence-modifiers"]'),
- or: document.querySelector('#or'),
- and: document.querySelector('#and'),
-
- //#region Word and Lemma Elements
- wordBuilder: document.querySelector('#word-builder'),
- lemmaBuilder: document.querySelector('#lemma-builder'),
- inputOptions: document.querySelector('#input-options'),
- incidenceModifiersButton: document.querySelector('#incidence-modifiers-button'),
- conditionContainer: document.querySelector('#condition-container'),
- wordInput: document.querySelector('#word-input'),
- lemmaInput: document.querySelector('#lemma-input'),
- ignoreCaseCheckbox : document.querySelector('#ignore-case-checkbox'),
- ignoreCase: document.querySelector('input[type="checkbox"]'),
- wildcardChar: document.querySelector('#wildcard-char'),
- optionGroup: document.querySelector('#option-group'),
- //#endregion Word and Lemma Elements
-
- //#region posBuilder Elements
- englishPosBuilder: document.querySelector('#english-pos-builder'),
- englishPos: document.querySelector('#english-pos'),
- germanPosBuilder: document.querySelector('#german-pos-builder'),
- germanPos: document.querySelector('#german-pos'),
- //#endregion posBuilder Elements
-
- //#region simple_posBuilder Elements
- simplePosBuilder: document.querySelector('#simplepos-builder'),
- simplePos: document.querySelector('#simple-pos'),
- //#endregion simple_posBuilder Elements
-
- //#region incidence modifiers
- oneOrMore: document.querySelector('#one-or-more'),
- zeroOrMore: document.querySelector('#zero-or-more'),
- zeroOrOne: document.querySelector('#zero-or-one'),
- exactlyN: document.querySelector('#exactlyN'),
- betweenNM: document.querySelector('#betweenNM'),
- nInput: document.querySelector('#n-input'),
- nSubmit: document.querySelector('#n-submit'),
- nmInput: document.querySelector('#n-m-input'),
- mInput: document.querySelector('#m-input'),
- nmSubmit: document.querySelector('#n-m-submit'),
- //#endregion incidence modifiers
-
- cancelBool: false,
- noValueMessage: document.querySelector('#no-value-message'),
- //#endregion Token Attributes
- }
+ this.elements = new ElementReferencesQueryBuilder();
+ this.generalFunctions = new GeneralFunctionsQueryBuilder(this.elements);
+ this.tokenAttributeBuilder = new TokenAttributeBuilderFunctionsQueryBuilder(this.elements);
+ this.structuralAttributeBuilder = new StructuralAttributeBuilderFunctionsQueryBuilder(this.elements);
- this.elements.closeQueryBuilder.addEventListener('click', () => {this.closeQueryBuilderModal(this.elements.concordanceQueryBuilder);});
- this.elements.concordanceQueryBuilderButton.addEventListener('click', () => {this.clearAll();});
- this.elements.insertQueryButton.addEventListener('click', () => {this.insertQuery();});
- this.elements.positionalAttrButton.addEventListener('click', () => {this.showPositionalAttrArea();});
- this.elements.structuralAttrButton.addEventListener('click', () => {this.showStructuralAttrArea();});
+ this.elements.closeQueryBuilder.addEventListener('click', () => {this.generalFunctions.closeQueryBuilderModal(this.elements.concordanceQueryBuilder);});
+ this.elements.concordanceQueryBuilderButton.addEventListener('click', () => {this.generalFunctions.clearAll();});
+ this.elements.insertQueryButton.addEventListener('click', () => {this.generalFunctions.insertQuery();});
+ this.elements.positionalAttrButton.addEventListener('click', () => {this.generalFunctions.showPositionalAttrArea();});
+ this.elements.structuralAttrButton.addEventListener('click', () => {this.generalFunctions.showStructuralAttrArea();});
//#region Structural Attribute Event Listeners
- this.elements.sentence.addEventListener('click', () => {this.addSentence();});
- this.elements.entity.addEventListener('click', () => {this.addEntity();});
- this.elements.textAnnotation.addEventListener('click', () => {this.addTextAnnotation();});
+ this.elements.sentence.addEventListener('click', () => {this.structuralAttributeBuilder.addSentence();});
+ this.elements.entity.addEventListener('click', () => {this.structuralAttributeBuilder.addEntity();});
+ this.elements.textAnnotation.addEventListener('click', () => {this.structuralAttributeBuilder.addTextAnnotation();});
- this.elements.englishEntType.addEventListener('change', () => {this.englishEntTypeHandler();});
- this.elements.germanEntType.addEventListener('change', () => {this.germanEntTypeHandler();});
- this.elements.emptyEntity.addEventListener('click', () => {this.emptyEntityButton();});
+ this.elements.englishEntType.addEventListener('change', () => {this.structuralAttributeBuilder.englishEntTypeHandler();});
+ this.elements.germanEntType.addEventListener('change', () => {this.structuralAttributeBuilder.germanEntTypeHandler();});
+ this.elements.emptyEntity.addEventListener('click', () => {this.structuralAttributeBuilder.emptyEntityButton();});
- this.elements.textAnnotationSubmit.addEventListener('click', () => {this.textAnnotationSubmitHandler();});
+ this.elements.textAnnotationSubmit.addEventListener('click', () => {this.structuralAttributeBuilder.textAnnotationSubmitHandler();});
//#endregion
//#region Token Attribute Event Listeners
- this.elements.queryBuilderTutorialInfoIcon.addEventListener('click', () => {this.tutorialIconHandler('#query-builder-tutorial-start');});
- this.elements.tokenTutorialInfoIcon.addEventListener('click', () => {this.tutorialIconHandler('#add-new-token-tutorial');});
- this.elements.editTokenTutorialInfoIcon.addEventListener('click', () => {this.tutorialIconHandler('#edit-options-tutorial');});
- this.elements.structuralAttributeTutorialInfoIcon.addEventListener('click', () => {this.tutorialIconHandler('#add-structural-attribute-tutorial');});
- this.elements.generalOptionsQueryBuilderTutorialInfoIcon.addEventListener('click', () => {this.tutorialIconHandler('#general-options-query-builder');});
+ this.elements.queryBuilderTutorialInfoIcon.addEventListener('click', () => {this.tokenAttributeBuilder.tutorialIconHandler('#query-builder-tutorial-start');});
+ this.elements.tokenTutorialInfoIcon.addEventListener('click', () => {this.tokenAttributeBuilder.tutorialIconHandler('#add-new-token-tutorial');});
+ this.elements.editTokenTutorialInfoIcon.addEventListener('click', () => {this.tokenAttributeBuilder.tutorialIconHandler('#edit-options-tutorial');});
+ this.elements.structuralAttributeTutorialInfoIcon.addEventListener('click', () => {this.tokenAttributeBuilder.tutorialIconHandler('#add-structural-attribute-tutorial');});
+ this.elements.generalOptionsQueryBuilderTutorialInfoIcon.addEventListener('click', () => {this.tokenAttributeBuilder.tutorialIconHandler('#general-options-query-builder');});
- this.elements.positionalAttr.addEventListener('change', () => {this.tokenTypeSelector();});
- this.elements.tokenSubmitButton.addEventListener('click', () => {this.addTokenToQuery();});
+ this.elements.positionalAttr.addEventListener('change', () => {this.tokenAttributeBuilder.tokenTypeSelector();});
+ this.elements.tokenSubmitButton.addEventListener('click', () => {this.tokenAttributeBuilder.addTokenToQuery();});
- this.elements.wordInput.addEventListener('input', () => {this.inputFieldHandler();});
- this.elements.lemmaInput.addEventListener('input', () => {this.inputFieldHandler();});
- this.elements.ignoreCase.addEventListener('change', () => {this.inputOptionHandler(this.elements.ignoreCase);});
- this.elements.wildcardChar.addEventListener('click', () => {this.inputOptionHandler(this.elements.wildcardChar);});
- this.elements.optionGroup.addEventListener('click', () => {this.inputOptionHandler(this.elements.optionGroup);});
+ this.elements.wordInput.addEventListener('input', () => {this.tokenAttributeBuilder.inputFieldHandler();});
+ this.elements.lemmaInput.addEventListener('input', () => {this.tokenAttributeBuilder.inputFieldHandler();});
+ this.elements.ignoreCase.addEventListener('change', () => {this.tokenAttributeBuilder.inputOptionHandler(this.elements.ignoreCase);});
+ this.elements.wildcardChar.addEventListener('click', () => {this.tokenAttributeBuilder.inputOptionHandler(this.elements.wildcardChar);});
+ this.elements.optionGroup.addEventListener('click', () => {this.tokenAttributeBuilder.inputOptionHandler(this.elements.optionGroup);});
- this.elements.oneOrMore.addEventListener('click', () => {this.incidenceModifiersHandler(this.elements.oneOrMore);});
- this.elements.zeroOrMore.addEventListener('click', () => {this.incidenceModifiersHandler(this.elements.zeroOrMore);});
- this.elements.zeroOrOne.addEventListener('click', () => {this.incidenceModifiersHandler(this.elements.zeroOrOne);});
- this.elements.nSubmit.addEventListener('click', () => {this.nSubmitHandler();});
- this.elements.nmSubmit.addEventListener('click', () => {this.nmSubmitHandler();});
+ this.elements.oneOrMore.addEventListener('click', () => {this.tokenAttributeBuilder.incidenceModifiersHandler(this.elements.oneOrMore);});
+ this.elements.zeroOrMore.addEventListener('click', () => {this.tokenAttributeBuilder.incidenceModifiersHandler(this.elements.zeroOrMore);});
+ this.elements.zeroOrOne.addEventListener('click', () => {this.tokenAttributeBuilder.incidenceModifiersHandler(this.elements.zeroOrOne);});
+ this.elements.nSubmit.addEventListener('click', () => {this.tokenAttributeBuilder.nSubmitHandler();});
+ this.elements.nmSubmit.addEventListener('click', () => {this.tokenAttributeBuilder.nmSubmitHandler();});
- this.elements.or.addEventListener('click', () => {this.orHandler();});
- this.elements.and.addEventListener('click', () => {this.andHandler();});
+ this.elements.or.addEventListener('click', () => {this.tokenAttributeBuilder.orHandler();});
+ this.elements.and.addEventListener('click', () => {this.tokenAttributeBuilder.andHandler();});
//#endregion Token Attribute Event Listeners
let selectInstances = this.elements.concordanceQueryBuilder.querySelectorAll('select');
@@ -178,830 +66,4 @@ class ConcordanceQueryBuilder {
dropdownContent.style.paddingBottom = '15px';
});
}
-
-
- // ##########################################################################
- // #################### General Functions ###################################
- // ##########################################################################
-
- //#region General Functions
-
- closeQueryBuilderModal(closeInstance) {
- let instance = M.Modal.getInstance(closeInstance);
- instance.close();
-
- }
-
- showPositionalAttrArea() {
- this.elements.positionalAttrArea.classList.remove('hide');
- this.elements.structuralAttrArea.classList.add('hide');
- this.wordBuilder();
-
- this.elements.tokenQueryFilled = false;
-
- window.location.href = '#token-builder-content';
- }
-
- showStructuralAttrArea() {
- this.elements.positionalAttrArea.classList.add('hide');
- this.elements.structuralAttrArea.classList.remove('hide');
- }
-
- queryChipFactory(dataType, prettyQueryText, queryText) {
- this.elements.counter++;
- window.location.href = '#query-container';
- queryText = Utils.escape(queryText);
- prettyQueryText = Utils.escape(prettyQueryText);
- let queryChipElement = Utils.HTMLToElement(
- `
-
- ${prettyQueryText}
- close
-
- `
- );
- queryChipElement.addEventListener('click', () => {this.deleteAttr(queryChipElement);});
- queryChipElement.addEventListener('dragstart', (event) => {
- // selects all nodes without target class
- let queryChips = this.elements.yourQuery.querySelectorAll('.query-component');
-
- // Adds a target chip in front of all draggable childnodes
- setTimeout(() => {
- let targetChipElement = Utils.HTMLToElement('Drop here ');
- for (let element of queryChips) {
- if (element === queryChipElement.nextSibling) {continue;}
- let targetChipClone = targetChipElement.cloneNode(true);
- if (element === queryChipElement) {
- // If the dragged element is not at the very end, a target chip is also inserted at the end
- if (queryChips[queryChips.length - 1] !== element) {
- queryChips[queryChips.length - 1].insertAdjacentElement('afterend', targetChipClone);
- }
- } else {
- element.insertAdjacentElement('beforebegin', targetChipClone);
- }
- targetChipClone.addEventListener('dragover', (event) => {
- event.preventDefault();
- });
- targetChipClone.addEventListener('dragenter', (event) => {
- event.preventDefault();
- event.target.style.borderStyle = 'solid dotted';
- });
- targetChipClone.addEventListener('dragleave', (event) => {
- event.preventDefault();
- event.target.style.borderStyle = 'hidden';
- });
- targetChipClone.addEventListener('drop', (event) => {
- let dropzone = event.target;
- dropzone.parentElement.replaceChild(queryChipElement, dropzone);
- this.queryPreviewBuilder();
- });
- }
- }, 0);
- });
-
- queryChipElement.addEventListener('dragend', (event) => {
- let targets = document.querySelectorAll('.drop-target');
- for (let target of targets) {
- target.remove();
- }
- });
-
- // Ensures that metadata is always at the end of the query:
- const lastChild = this.elements.yourQuery.lastChild;
- const isLastChildTextAnnotation = lastChild && lastChild.dataset.type === 'text-annotation';
-
- if (!isLastChildTextAnnotation) {
- this.elements.yourQuery.appendChild(queryChipElement);
- } else {
- this.elements.yourQuery.insertBefore(queryChipElement, lastChild);
- }
-
- this.elements.queryContainer.classList.remove('hide');
- this.queryPreviewBuilder();
-
- // Shows a hint about possible functions for editing the query at the first added element in the query
- if (this.elements.yourQuery.childNodes.length === 1) {
- app.flash('You can edit your query by deleting individual elements or moving them via drag and drop.');
- }
- }
-
- queryPreviewBuilder() {
- this.elements.yourQueryContent = [];
- for (let element of this.elements.yourQuery.childNodes) {
- let queryElement = element.dataset.query;
- if (queryElement !== undefined) {
- queryElement = Utils.escape(queryElement);
- this.elements.yourQueryContent.push(queryElement);
- }
- }
-
- let queryString = this.elements.yourQueryContent.join(' ');
- queryString += ';';
- this.elements.queryPreview.innerHTML = queryString;
- }
-
-
- deleteAttr(attr) {
- this.elements.yourQuery.removeChild(attr);
- if (attr.dataset.type === "start-sentence") {
- this.elements.sentence.innerHTML = 'Sentence';
- } else if (attr.dataset.type === "start-entity" || attr.dataset.type === "start-empty-entity") {
- this.elements.entity.innerHTML = 'Entity';
- }
- this.elements.counter -= 1;
- if (this.elements.counter === 0) {
- this.elements.queryContainer.classList.add('hide');
- }
- this.queryPreviewBuilder();
- }
-
- insertQuery() {
- this.elements.yourQueryContent = [];
- this.validateValue();
- if (this.elements.valueValidator) {
- for (let element of this.elements.yourQuery.childNodes) {
- let queryElement = element.dataset.query;
- if (queryElement !== 'undefined') {
- this.elements.yourQueryContent.push(queryElement);
- }
- }
-
- let queryString = this.elements.yourQueryContent.join(' ');
- queryString += ';';
-
- this.elements.concordanceQueryBuilder.classList.add('modal-close');
- this.elements.extFormQuery.value = queryString;
- }
- }
-
- validateValue() {
- this.elements.valueValidator = true;
- let sentenceCounter = 0;
- let sentenceEndCounter = 0;
- let entityCounter = 0;
- let entityEndCounter = 0;
- for (let element of this.elements.yourQuery.childNodes) {
- if (element.dataset.type === 'start-sentence') {
- sentenceCounter += 1;
- }else if (element.dataset.type === 'end-sentence') {
- sentenceEndCounter += 1;
- }else if (element.dataset.type === 'start-entity' || element.dataset.type === 'start-empty-entity') {
- entityCounter += 1;
- }else if (element.dataset.type === 'end-entity') {
- entityEndCounter += 1;
- }
- }
- // Checks if the same number of opening and closing tags (entity and sentence) are present. Depending on what is missing, the corresponding error message is ejected
- if (sentenceCounter > sentenceEndCounter) {
- app.flash('Please add the closing sentence tag', 'error');
- this.elements.valueValidator = false;
- } else if (sentenceCounter < sentenceEndCounter) {
- app.flash('Please remove the closing sentence tag', 'error');
- this.elements.valueValidator = false;
- }
- if (entityCounter > entityEndCounter) {
- app.flash('Please add the closing entity tag', 'error');
- this.elements.valueValidator = false;
- } else if (entityCounter < entityEndCounter) {
- app.flash('Please remove the closing entity tag', 'error');
- this.elements.valueValidator = false;
- }
- }
-
- clearAll() {
- // Everything is reset.
- let instance = M.Tooltip.getInstance(this.elements.queryBuilderTutorialInfoIcon);
-
- this.hideEverything();
- this.elements.counter = 0;
- this.elements.concordanceQueryBuilder.classList.remove('modal-close');
- this.elements.positionalAttrArea.classList.add('hide');
- this.elements.structuralAttrArea.classList.add('hide');
- this.elements.yourQuery.innerHTML = '';
- this.elements.queryContainer.classList.add('hide');
- this.elements.entity.innerHTML = 'Entity';
- this.elements.sentence.innerHTML = 'Sentence';
-
- // If the Modal is open after 5 seconds for 5 seconds (with 'instance'), a message is displayed indicating that further information can be obtained via the question mark icon
- instance.tooltipEl.style.background = '#98ACD2';
- instance.tooltipEl.style.borderTop = 'solid 4px #0064A3';
- instance.tooltipEl.style.padding = '10px';
- instance.tooltipEl.style.color = 'black';
-
- setTimeout(() => {
- let modalInstance = M.Modal.getInstance(this.elements.concordanceQueryBuilder);
- if (modalInstance.isOpen) {
- instance.open();
- setTimeout(() => {
- instance.close();
- }, 5000);
- }
- }, 5000);
-
- }
-
- tutorialIconHandler(id) {
- setTimeout(() => {
- window.location.href= id;
- }, 0);
-
- }
-
- //#endregion General Functions
-
-
- // ##########################################################################
- // ############## Token Attribute Builder Functions #########################
- // ##########################################################################
-
- //#region Token Attribute Builder Functions
-
- //#region General functions of the Token Builder
- tokenTypeSelector() {
- this.hideEverything();
- switch (this.elements.positionalAttr.value) {
- case 'word':
- this.wordBuilder();
- break;
- case 'lemma':
- this.lemmaBuilder();
- break;
- case 'english-pos':
- this.englishPosHandler();
- break;
- case 'german-pos':
- this.germanPosHandler();
- break;
- case 'simple-pos-button':
- this.simplePosBuilder();
- break;
- case 'empty-token':
- this.emptyTokenHandler();
- break;
- default:
- this.wordBuilder();
- break;
- }
- }
-
- hideEverything() {
-
- this.elements.wordBuilder.classList.add('hide');
- this.elements.lemmaBuilder.classList.add('hide');
- this.elements.ignoreCaseCheckbox.classList.add('hide');
- this.elements.inputOptions.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- this.elements.conditionContainer.classList.add('hide');
- this.elements.englishPosBuilder.classList.add('hide');
- this.elements.germanPosBuilder.classList.add('hide');
- this.elements.simplePosBuilder.classList.add('hide');
- this.elements.entityBuilder.classList.add('hide');
- this.elements.textAnnotationBuilder.classList.add('hide');
-
- }
-
- tokenChipFactory(prettyQueryText, tokenText) {
- tokenText = encodeURI(tokenText);
- let builderElement;
- let queryChipElement;
- builderElement = document.createElement('div');
- builderElement.innerHTML = `
-
- ${prettyQueryText}
- close
-
`;
- queryChipElement = builderElement.firstElementChild;
- queryChipElement.addEventListener('click', () => {this.deleteTokenAttr(queryChipElement);});
- this.elements.tokenQuery.appendChild(queryChipElement);
- }
-
- deleteTokenAttr(attr) {
- if (this.elements.tokenQuery.childNodes.length < 2) {
- this.elements.tokenQuery.removeChild(attr);
- this.wordBuilder();
- } else {
- this.elements.tokenQuery.removeChild(attr);
- }
-
- }
-
- addTokenToQuery() {
- let c;
- let tokenQueryContent = ''; //for ButtonFactory(prettyQueryText)
- let tokenQueryText = ''; //for ButtonFactory(queryText)
- this.elements.cancelBool = false;
- let tokenIsEmpty = false;
-
- if (this.elements.ignoreCase.checked) {
- c = ' %c';
- } else {
- c = '';
- }
-
- for (let element of this.elements.tokenQuery.childNodes) {
- tokenQueryContent += ' ' + element.firstChild.data + ' ';
- tokenQueryText += decodeURI(element.dataset.tokentext);
- if (element.innerText.indexOf('empty token') !== -1) {
- tokenIsEmpty = true;
- }
- }
-
- if (this.elements.tokenQueryFilled === false) {
- switch (this.elements.positionalAttr.value) {
- case 'word':
- if (this.elements.wordInput.value === '') {
- this.disableTokenSubmit();
- } else {
- tokenQueryContent += `word=${this.elements.wordInput.value}${c}`;
- tokenQueryText += `word="${this.elements.wordInput.value}"${c}`;
- this.elements.wordInput.value = '';
- }
- break;
- case 'lemma':
- if (this.elements.lemmaInput.value === '') {
- this.disableTokenSubmit();
- } else {
- tokenQueryContent += `lemma=${this.elements.lemmaInput.value}${c}`;
- tokenQueryText += `lemma="${this.elements.lemmaInput.value}"${c}`;
- this.elements.lemmaInput.value = '';
- }
- break;
- case 'english-pos':
- if (this.elements.englishPos.value === 'default') {
- this.disableTokenSubmit();
- } else {
- tokenQueryContent += `pos=${this.elements.englishPos.value}`;
- tokenQueryText += `pos="${this.elements.englishPos.value}"`;
- this.elements.englishPos.value = '';
- }
- break;
- case 'german-pos':
- if (this.elements.germanPos.value === 'default') {
- this.disableTokenSubmit();
- } else {
- tokenQueryContent += `pos=${this.elements.germanPos.value}`;
- tokenQueryText += `pos="${this.elements.germanPos.value}"`;
- this.elements.germanPos.value = '';
- }
- break;
- case 'simple-pos-button':
- if (this.elements.simplePos.value === 'default') {
- this.disableTokenSubmit();
- } else {
- tokenQueryContent += `simple_pos=${this.elements.simplePos.value}`;
- tokenQueryText += `simple_pos="${this.elements.simplePos.value}"`;
- this.elements.simplePos.value = '';
- }
- break;
- default:
- this.wordBuilder();
- break;
- }
- }
-
- // cancelBool looks in disableTokenSubmit() whether a value is passed. If the input fields/dropdowns are empty (cancelBool === true), no token is added.
- if (this.elements.cancelBool === false) {
- // Square brackets are added only if it is not an empty token (where they are already present).
- if (tokenIsEmpty === false) {
- tokenQueryText = '[' + tokenQueryText + ']';
- }
- this.queryChipFactory('token', tokenQueryContent, tokenQueryText);
- this.hideEverything();
- this.elements.positionalAttrArea.classList.add('hide');
- this.elements.tokenQuery.innerHTML = '';
- }
-
- }
-
- disableTokenSubmit() {
- this.elements.cancelBool = true;
- this.elements.tokenSubmitButton.classList.add('red');
- this.elements.noValueMessage.classList.remove('hide');
- setTimeout(() => {
- this.elements.tokenSubmitButton.classList.remove('red');
- }, 500);
- setTimeout(() => {
- this.elements.noValueMessage.classList.add('hide');
- }, 3000);
- }
-
- inputFieldHandler() {
- let input;
-
- if (this.elements.wordBuilder.classList.contains('hide') === false) {
- input = this.elements.wordInput;
- } else {
- input = this.elements.lemmaInput;
- }
-
- if (input.value === '') {
- this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
- this.elements.or.classList.add('disabled');
- this.elements.and.classList.add('disabled');
- } else {
- this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
- this.elements.or.classList.remove('disabled');
- this.elements.and.classList.remove('disabled');
- }
- }
-
- //#endregion General functions of the Token Builder
-
- //#region Dropdown Select Handler
- wordBuilder() {
- this.hideEverything();
- this.elements.wordInput.value = '';
- this.elements.wordBuilder.classList.remove('hide');
- this.elements.inputOptions.classList.remove('hide');
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.conditionContainer.classList.remove('hide');
- this.elements.ignoreCaseCheckbox.classList.remove('hide');
-
- this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
- this.elements.or.classList.add('disabled');
- this.elements.and.classList.add('disabled');
-
- // Resets materialize select field to default value
- let SelectInstance = M.FormSelect.getInstance(this.elements.positionalAttr);
- SelectInstance.input.value = 'word';
- this.elements.positionalAttr.value = 'word';
-
- }
-
- lemmaBuilder() {
- this.hideEverything();
- this.elements.lemmaInput.value = '';
- this.elements.lemmaBuilder.classList.remove('hide');
- this.elements.inputOptions.classList.remove('hide');
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
- this.elements.conditionContainer.classList.remove('hide');
- this.elements.ignoreCaseCheckbox.classList.remove('hide');
-
- this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
- this.elements.or.classList.add('disabled');
- this.elements.and.classList.add('disabled');
- }
-
- englishPosHandler() {
- this.hideEverything();
- this.elements.englishPosBuilder.classList.remove('hide');
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.conditionContainer.classList.remove('hide');
- this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
- this.elements.or.classList.remove('disabled');
- this.elements.and.classList.remove('disabled');
-
- // Resets materialize select dropdown
- let selectInstance = M.FormSelect.getInstance(this.elements.englishPos);
- selectInstance.input.value = 'English pos tagset';
- this.elements.englishPos.value = 'default';
- }
-
- germanPosHandler() {
- this.hideEverything();
- this.elements.germanPosBuilder.classList.remove('hide');
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.conditionContainer.classList.remove('hide');
- this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
- this.elements.or.classList.remove('disabled');
- this.elements.and.classList.remove('disabled');
-
- // Resets materialize select dropdown
- let selectInstance = M.FormSelect.getInstance(this.elements.germanPos);
- selectInstance.input.value = 'German pos tagset';
- this.elements.germanPos.value = 'default';
- }
-
- simplePosBuilder() {
- this.hideEverything();
- this.elements.simplePosBuilder.classList.remove('hide');
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.conditionContainer.classList.remove('hide');
- this.elements.simplePos.selectedIndex = 0;
- this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
- this.elements.or.classList.remove('disabled');
- this.elements.and.classList.remove('disabled');
-
- // Resets materialize select dropdown
- let selectInstance = M.FormSelect.getInstance(this.elements.simplePos);
- selectInstance.input.value = 'simple_pos tagset';
- this.elements.simplePos.value = 'default';
- M.FormSelect.init(
- selectInstance,
- {
- dropdownOptions: {
- direction: 'bottom',
- coverTrigger: false
- }
- }
- )
-
- }
-
- emptyTokenHandler() {
- this.tokenChipFactory('empty token', '[]');
- this.elements.tokenQueryFilled = true;
- this.hideEverything();
- this.elements.incidenceModifiersButton.classList.remove('hide');
- this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
-
- }
- //#endregion Dropdown Select Handler
-
- //#region Options to edit your token - Wildcard Charakter, Option Group, Incidence Modifiers, Ignore Case, 'and', 'or'
-
- inputOptionHandler(elem) {
- let input;
-
- if (this.elements.wordBuilder.classList.contains('hide') === false) {
- input = this.elements.wordInput;
- } else {
- input = this.elements.lemmaInput;
- }
-
- if (elem === this.elements.optionGroup) {
- input.value += '(option1|option2)';
- let firstIndex = input.value.indexOf('option1');
- let lastIndex = firstIndex + 'option1'.length;
- input.focus();
- input.setSelectionRange(firstIndex, lastIndex);
- } else if (elem === this.elements.wildcardChar) {
- input.value += '.';
- }
- this.inputFieldHandler();
- }
-
- nSubmitHandler() {
- let instance = M.Modal.getInstance(this.elements.exactlyN);
- instance.close();
-
- switch (this.elements.positionalAttr.value) {
- case 'word':
- this.elements.wordInput.value += ' {' + this.elements.nInput.value + '}';
- break;
- case 'lemma':
- this.elements.lemmaInput.value += ' {' + this.elements.nInput.value + '}';
- break;
- case 'english-pos':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
- this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
- this.elements.englishPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'german-pos':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
- this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
- this.elements.germanPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'simple-pos-button':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
- this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
- this.elements.simplePosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'empty-token':
- this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
- break;
- default:
- break;
- }
-
- }
-
- nmSubmitHandler() {
- let instance = M.Modal.getInstance(this.elements.betweenNM);
- instance.close();
-
- switch (this.elements.positionalAttr.value) {
- case 'word':
- this.elements.wordInput.value += `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`;
- break;
- case 'lemma':
- this.elements.lemmaInput.value += `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`;
- break;
- case 'english-pos':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
- this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
- this.elements.englishPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'german-pos':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
- this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
- this.elements.germanPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'simple-pos-button':
- this.elements.tokenQueryFilled = true;
- this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
- this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
- this.elements.simplePosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- break;
- case 'empty-token':
- this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
- break;
- default:
- break;
- }
- }
-
- incidenceModifiersHandler(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.
- if (this.elements.positionalAttr.value === 'empty-token') {
- this.tokenChipFactory(elem.innerText, elem.dataset.token);
- } else if (this.elements.positionalAttr.value === 'english-pos') {
- this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
- this.tokenChipFactory(elem.innerText, elem.dataset.token);
- this.elements.englishPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- this.elements.tokenQueryFilled = true;
- } else if (this.elements.positionalAttr.value === 'german-pos') {
- this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
- this.tokenChipFactory(elem.innerText, elem.dataset.token);
- this.elements.germanPosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- this.elements.tokenQueryFilled = true;
- } else if (this.elements.positionalAttr.value === 'simple-pos-button') {
- this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
- this.tokenChipFactory(elem.innerText, elem.dataset.token);
- this.elements.simplePosBuilder.classList.add('hide');
- this.elements.incidenceModifiersButton.classList.add('hide');
- this.elements.tokenQueryFilled = true;
- } else {
- let input;
-
- if (this.elements.wordBuilder.classList.contains('hide') === false) {
- input = this.elements.wordInput;
- } else {
- input = this.elements.lemmaInput;
- }
- input.value += elem.dataset.token;
- }
-
- }
-
- orHandler() {
- this.conditionHandler('or', ' | ');
- }
-
- andHandler() {
- this.conditionHandler('and', ' & ');
- }
-
- conditionHandler(conditionText, conditionQueryContent) {
- this.hideEverything();
- let tokenQueryContent;
- let tokenQueryText;
- let c;
-
- if (this.elements.ignoreCase.checked) {
- c = ' %c';
- } else {
- c = '';
- }
-
- switch (this.elements.positionalAttr.value) {
- case 'word':
- tokenQueryContent = `word=${this.elements.wordInput.value}${c}`;
- tokenQueryText = `word="${this.elements.wordInput.value}"${c}`;
- this.elements.wordInput.value = '';
- break;
- case 'lemma':
- tokenQueryContent = `lemma=${this.elements.lemmaInput.value}${c}`;
- tokenQueryText = `lemma="${this.elements.lemmaInput.value}"${c}`;
- this.elements.lemmaInput.value = '';
- break;
- case 'english-pos':
- tokenQueryContent = `pos=${this.elements.englishPos.value}`;
- tokenQueryText = `pos="${this.elements.englishPos.value}"`;
- this.elements.englishPos.value = '';
- break;
- case 'german-pos':
- tokenQueryContent = `pos=${this.elements.germanPos.value}`;
- tokenQueryText = `pos="${this.elements.germanPos.value}"`;
- this.elements.germanPos.value = '';
- break;
- case 'simple-pos-button':
- tokenQueryContent = `simple_pos=${this.elements.simplePos.value}`;
- tokenQueryText = `simple_pos="${this.elements.simplePos.value}"`;
- this.elements.simplePos.value = '';
- break;
- default:
- this.wordBuilder();
- break;
- }
-
- this.tokenChipFactory(tokenQueryContent, tokenQueryText);
- this.tokenChipFactory(conditionText, conditionQueryContent);
- this.wordBuilder();
- }
-
- //#endregion Options to edit your token - Wildcard Charakter, Option Group, Incidence Modifiers, Ignore Case, 'and', 'or'
-
- //#endregion Token Attribute Builder Functions
-
-
- // ##########################################################################
- // ############ Structural Attribute Builder Functions ######################
- // ##########################################################################
-
- //#region Structural Attribute Builder Functions
- addSentence() {
- this.hideEverything();
- if (this.elements.sentence.text === 'End Sentence') {
- this.queryChipFactory('end-sentence', 'Sentence End', '');
- this.elements.sentence.innerHTML = 'Sentence';
- } else {
- this.queryChipFactory('start-sentence', 'Sentence Start', '');
- this.elements.queryContent.push('sentence');
- this.elements.sentence.innerHTML = 'End Sentence';
- }
- }
-
- addEntity() {
- if (this.elements.entity.text === 'End Entity') {
- let queryText;
- if (this.elements.entityAnyType === false) {
- queryText = '';
- } else {
- queryText = '';
- }
- this.queryChipFactory('end-entity', 'Entity End', queryText);
- this.elements.entity.innerHTML = 'Entity';
- } else {
- this.hideEverything();
- this.elements.entityBuilder.classList.remove('hide');
- window.location.href = '#entity-builder';
- }
- }
-
- englishEntTypeHandler() {
- this.queryChipFactory('start-entity', 'Entity Type=' + this.elements.englishEntType.value, '');
- this.elements.entity.innerHTML = 'End Entity';
- this.hideEverything();
- this.elements.entityAnyType = false;
-
- // Resets materialize select dropdown
- let SelectInstance = M.FormSelect.getInstance(this.elements.englishEntType);
- SelectInstance.input.value = 'English ent_type';
- this.elements.englishEntType.value = 'default';
- }
-
- germanEntTypeHandler() {
- this.queryChipFactory('start-entity', 'Entity Type=' + this.elements.germanEntType.value, '');
- this.elements.entity.innerHTML = 'End Entity';
- this.hideEverything();
- this.elements.entityAnyType = false;
-
- // Resets materialize select dropdown
- let SelectInstance = M.FormSelect.getInstance(this.elements.germanEntType);
- SelectInstance.input.value = 'German ent_type';
- this.elements.germanEntType.value = 'default';
- }
-
- emptyEntityButton() {
- this.queryChipFactory('start-empty-entity', 'Entity Start', '');
- this.elements.entity.innerHTML = 'End Entity';
- this.hideEverything();
- this.elements.entityAnyType = true;
- }
-
- addTextAnnotation() {
- this.hideEverything();
- this.elements.textAnnotationBuilder.classList.remove('hide');
- window.location.href = '#text-annotation-builder';
-
- // Resets materialize select dropdown
- let SelectInstance = M.FormSelect.getInstance(this.elements.textAnnotationOptions);
- SelectInstance.input.value = 'address';
- this.elements.textAnnotationOptions.value = 'address';
- this.elements.textAnnotationInput.value= '';
- }
-
- textAnnotationSubmitHandler() {
- if (this.elements.textAnnotationInput.value === '') {
- this.elements.textAnnotationSubmit.classList.add('red');
- this.elements.noValueMetadataMessage.classList.remove('hide');
- setTimeout(() => {
- this.elements.textAnnotationSubmit.classList.remove('red');
- }, 500);
- setTimeout(() => {
- this.elements.noValueMetadataMessage.classList.add('hide');
- }, 3000);
- } else {
- let queryText = `:: match.text_${this.elements.textAnnotationOptions.value}="${this.elements.textAnnotationInput.value}"`;
- this.queryChipFactory('text-annotation', `${this.elements.textAnnotationOptions.value}=${this.elements.textAnnotationInput.value}`, queryText);
- this.hideEverything();
- }
- }
- //#endregion Structural Attribute Builder Functions
-
}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
new file mode 100644
index 00000000..2446585b
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js
@@ -0,0 +1,90 @@
+class ElementReferencesQueryBuilder {
+ constructor() {
+
+ this.counter = 0;
+ this.yourQueryContent = [];
+ this.concordanceQueryBuilder = document.querySelector('#concordance-query-builder');
+ this.concordanceQueryBuilderButton = document.querySelector('#concordance-query-builder-button'); //nur Eventlistener
+ this.closeQueryBuilder = document.querySelector('#close-query-builder'); //nur Eventlistener
+ this.valueValidator = true;
+
+
+ //#region QueryBuilder Elements
+ this.positionalAttrButton = document.querySelector('#positional-attr-button'); //nur Eventlistener
+ this.positionalAttrArea = document.querySelector('#positional-attr');
+ this.positionalAttr = document.querySelector('#token-attr');
+ this.structuralAttrButton = document.querySelector('#structural-attr-button'); //nur Eventlistener
+ this.structuralAttrArea = document.querySelector('#structural-attr');
+ this.queryContainer = document.querySelector('#query-container');
+ this.yourQuery = document.querySelector('#your-query');
+ this.insertQueryButton = document.querySelector('#insert-query-button'); //nur Eventlistener
+ this.tokenQuery = document.querySelector('#token-query');
+ this.tokenBuilderContent = document.querySelector('#token-builder-content');
+ this.tokenSubmitButton = document.querySelector('#token-submit');
+ // this.dropButton = '';
+
+ this.queryBuilderTutorialInfoIcon = document.querySelector('#query-builder-tutorial-info-icon');
+ this.tokenTutorialInfoIcon = document.querySelector('#token-tutorial-info-icon'); // nur Eventlistener
+ this.editTokenTutorialInfoIcon = document.querySelector('#edit-options-tutorial-info-icon'); // nur Eventlistener
+ this.structuralAttributeTutorialInfoIcon = document.querySelector('#add-structural-attribute-tutorial-info-icon'); // nur Eventlistener
+ this.generalOptionsQueryBuilderTutorialInfoIcon = document.querySelector('#general-options-query-builder-tutorial-info-icon'); // nur Eventlistener
+ //#endregion QueryBuilder Elements
+
+ //#region Strucutral Attributes
+ this.sentence = document.querySelector('#sentence');
+ this.entity = document.querySelector('#entity');
+ this.textAnnotation = document.querySelector('#text-annotation');
+
+ this.entityBuilder = document.querySelector('#entity-builder');
+ this.englishEntType = document.querySelector('#english-ent-type');
+ this.germanEntType = document.querySelector('#german-ent-type');
+ this.emptyEntity = document.querySelector('#empty-entity'); //nur Eventlistener
+ this.entityAnyType = false;
+
+ this.textAnnotationBuilder = document.querySelector('#text-annotation-builder');
+ this.textAnnotationOptions = document.querySelector('#text-annotation-options');
+ this.textAnnotationInput = document.querySelector('#text-annotation-input');
+ this.textAnnotationSubmit = document.querySelector('#text-annotation-submit');
+ //#endregion Structural Attributes
+
+ //#region Token Attributes
+ this.tokenQueryFilled = false;
+ this.or = document.querySelector('#or');
+ this.and = document.querySelector('#and');
+
+ this.wordBuilder = document.querySelector('#word-builder'); //nur hide/show
+ this.lemmaBuilder = document.querySelector('#lemma-builder'); //nur hide/show
+ this.inputOptions = document.querySelector('#input-options'); //nur hide/show
+ this.incidenceModifiersButton = document.querySelector('#incidence-modifiers-button'); //nur hide/show
+ this.conditionContainer = document.querySelector('#condition-container'); //nur hide/show
+ this.wordInput = document.querySelector('#word-input');
+ this.lemmaInput = document.querySelector('#lemma-input');
+ this.ignoreCaseCheckbox = document.querySelector('#ignore-case-checkbox'); // nur hide/show
+ this.ignoreCase = document.querySelector('input[type="checkbox"]');
+ this.wildcardChar = document.querySelector('#wildcard-char');
+ this.optionGroup = document.querySelector('#option-group');
+
+ this.englishPosBuilder = document.querySelector('#english-pos-builder'); //nur hide/show
+ this.englishPos = document.querySelector('#english-pos');
+ this.germanPosBuilder = document.querySelector('#german-pos-builder'); //nur hide/show
+ this.germanPos = document.querySelector('#german-pos');
+
+ this.simplePosBuilder = document.querySelector('#simplepos-builder'); //nur hide/show
+ this.simplePos = document.querySelector('#simple-pos');
+
+ this.oneOrMore = document.querySelector('#one-or-more');
+ this.zeroOrMore = document.querySelector('#zero-or-more');
+ this.zeroOrOne = document.querySelector('#zero-or-one'); // die Incidence-Modifier evtl mit data-attributes abfragen?
+ this.exactlyN = document.querySelector('#exactlyN');
+ this.betweenNM = document.querySelector('#betweenNM');
+ this.nInput = document.querySelector('#n-input');
+ this.nSubmit = document.querySelector('#n-submit'); //nur Eventlistener
+ this.nmInput = document.querySelector('#n-m-input');
+ this.mInput = document.querySelector('#m-input');
+ this.nmSubmit = document.querySelector('#n-m-submit'); //nur Eventlistener
+
+ this.cancelBool = false; //nur true/false
+ this.noValueMessage = document.querySelector('#no-value-message'); //nur hide/show
+ //#endregion Token Attributes
+ }
+}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
new file mode 100644
index 00000000..8c045086
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js
@@ -0,0 +1,262 @@
+class GeneralFunctionsQueryBuilder {
+ constructor(elements) {
+ this.elements = elements;
+ }
+
+ toggleClass(elements, className, action){
+ elements.forEach(element => {
+ element.classList[action](className);
+ });
+ }
+
+ closeQueryBuilderModal(closeInstance) {
+ let instance = M.Modal.getInstance(closeInstance);
+ instance.close();
+ }
+
+ showPositionalAttrArea() {
+ // this.elements.positionalAttrArea.classList.remove('hide');
+ // this.elements.structuralAttrArea.classList.add('hide');
+ this.toggleClass([this.elements.positionalAttrArea], 'hide', 'remove');
+ this.toggleClass([this.elements.structuralAttrArea], 'hide', 'add');
+ this.wordBuilder();
+
+ this.elements.tokenQueryFilled = false;
+
+ window.location.href = '#token-builder-content';
+ }
+
+ showStructuralAttrArea() {
+ this.elements.positionalAttrArea.classList.add('hide');
+ this.elements.structuralAttrArea.classList.remove('hide');
+ }
+
+ wordBuilder() {
+ this.hideEverything();
+ this.elements.wordInput.value = '';
+ this.elements.wordBuilder.classList.remove('hide');
+ this.elements.inputOptions.classList.remove('hide');
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.conditionContainer.classList.remove('hide');
+ this.elements.ignoreCaseCheckbox.classList.remove('hide');
+
+ this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
+ this.elements.or.classList.add('disabled');
+ this.elements.and.classList.add('disabled');
+
+ // Resets materialize select field to default value
+ let SelectInstance = M.FormSelect.getInstance(this.elements.positionalAttr);
+ SelectInstance.input.value = 'word';
+ this.elements.positionalAttr.value = 'word';
+
+ }
+
+ queryChipFactory(dataType, prettyQueryText, queryText) {
+ this.elements.counter++;
+ window.location.href = '#query-container';
+ queryText = Utils.escape(queryText);
+ prettyQueryText = Utils.escape(prettyQueryText);
+ let queryChipElement = Utils.HTMLToElement(
+ `
+
+ ${prettyQueryText}
+ close
+
+ `
+ );
+ queryChipElement.addEventListener('click', () => {this.deleteAttr(queryChipElement);});
+ queryChipElement.addEventListener('dragstart', (event) => {
+ // selects all nodes without target class
+ let queryChips = this.elements.yourQuery.querySelectorAll('.query-component');
+
+ // Adds a target chip in front of all draggable childnodes
+ setTimeout(() => {
+ let targetChipElement = Utils.HTMLToElement('Drop here ');
+ for (let element of queryChips) {
+ if (element === queryChipElement.nextSibling) {continue;}
+ let targetChipClone = targetChipElement.cloneNode(true);
+ if (element === queryChipElement) {
+ // If the dragged element is not at the very end, a target chip is also inserted at the end
+ if (queryChips[queryChips.length - 1] !== element) {
+ queryChips[queryChips.length - 1].insertAdjacentElement('afterend', targetChipClone);
+ }
+ } else {
+ element.insertAdjacentElement('beforebegin', targetChipClone);
+ }
+ targetChipClone.addEventListener('dragover', (event) => {
+ event.preventDefault();
+ });
+ targetChipClone.addEventListener('dragenter', (event) => {
+ event.preventDefault();
+ event.target.style.borderStyle = 'solid dotted';
+ });
+ targetChipClone.addEventListener('dragleave', (event) => {
+ event.preventDefault();
+ event.target.style.borderStyle = 'hidden';
+ });
+ targetChipClone.addEventListener('drop', (event) => {
+ let dropzone = event.target;
+ dropzone.parentElement.replaceChild(queryChipElement, dropzone);
+ this.queryPreviewBuilder();
+ });
+ }
+ }, 0);
+ });
+
+ queryChipElement.addEventListener('dragend', (event) => {
+ let targets = document.querySelectorAll('.drop-target');
+ for (let target of targets) {
+ target.remove();
+ }
+ });
+
+ // Ensures that metadata is always at the end of the query:
+ const lastChild = this.elements.yourQuery.lastChild;
+ const isLastChildTextAnnotation = lastChild && lastChild.dataset.type === 'text-annotation';
+
+ if (!isLastChildTextAnnotation) {
+ this.elements.yourQuery.appendChild(queryChipElement);
+ } else {
+ this.elements.yourQuery.insertBefore(queryChipElement, lastChild);
+ }
+
+ this.elements.queryContainer.classList.remove('hide');
+ this.queryPreviewBuilder();
+
+ // Shows a hint about possible functions for editing the query at the first added element in the query
+ if (this.elements.yourQuery.childNodes.length === 1) {
+ app.flash('You can edit your query by deleting individual elements or moving them via drag and drop.');
+ }
+ }
+
+ queryPreviewBuilder() {
+ let queryPreview = document.querySelector('#query-preview');
+ this.elements.yourQueryContent = [];
+ for (let element of this.elements.yourQuery.childNodes) {
+ let queryElement = element.dataset.query;
+ if (queryElement !== undefined) {
+ queryElement = Utils.escape(queryElement);
+ this.elements.yourQueryContent.push(queryElement);
+ }
+ }
+
+ let queryString = this.elements.yourQueryContent.join(' ');
+ queryString += ';';
+
+ queryPreview.innerHTML = queryString;
+ }
+
+
+ deleteAttr(attr) {
+ this.elements.yourQuery.removeChild(attr);
+ if (attr.dataset.type === "start-sentence") {
+ this.elements.sentence.innerHTML = 'Sentence';
+ } else if (attr.dataset.type === "start-entity" || attr.dataset.type === "start-empty-entity") {
+ this.elements.entity.innerHTML = 'Entity';
+ }
+ this.elements.counter -= 1;
+ if (this.elements.counter === 0) {
+ this.elements.queryContainer.classList.add('hide');
+ }
+ this.queryPreviewBuilder();
+ }
+
+ insertQuery() {
+ let extFormQuery= document.querySelector('#concordance-extension-form-query');
+ this.elements.yourQueryContent = [];
+ this.validateValue();
+ if (this.elements.valueValidator) {
+ for (let element of this.elements.yourQuery.childNodes) {
+ let queryElement = element.dataset.query;
+ if (queryElement !== 'undefined') {
+ this.elements.yourQueryContent.push(queryElement);
+ }
+ }
+
+ let queryString = this.elements.yourQueryContent.join(' ');
+ queryString += ';';
+
+ this.elements.concordanceQueryBuilder.classList.add('modal-close');
+ extFormQuery.value = queryString;
+ }
+ }
+
+ validateValue() {
+ this.elements.valueValidator = true;
+ let sentenceCounter = 0;
+ let sentenceEndCounter = 0;
+ let entityCounter = 0;
+ let entityEndCounter = 0;
+ for (let element of this.elements.yourQuery.childNodes) {
+ if (element.dataset.type === 'start-sentence') {
+ sentenceCounter += 1;
+ }else if (element.dataset.type === 'end-sentence') {
+ sentenceEndCounter += 1;
+ }else if (element.dataset.type === 'start-entity' || element.dataset.type === 'start-empty-entity') {
+ entityCounter += 1;
+ }else if (element.dataset.type === 'end-entity') {
+ entityEndCounter += 1;
+ }
+ }
+ // Checks if the same number of opening and closing tags (entity and sentence) are present. Depending on what is missing, the corresponding error message is ejected
+ if (sentenceCounter > sentenceEndCounter) {
+ app.flash('Please add the closing sentence tag', 'error');
+ this.elements.valueValidator = false;
+ } else if (sentenceCounter < sentenceEndCounter) {
+ app.flash('Please remove the closing sentence tag', 'error');
+ this.elements.valueValidator = false;
+ }
+ if (entityCounter > entityEndCounter) {
+ app.flash('Please add the closing entity tag', 'error');
+ this.elements.valueValidator = false;
+ } else if (entityCounter < entityEndCounter) {
+ app.flash('Please remove the closing entity tag', 'error');
+ this.elements.valueValidator = false;
+ }
+ }
+
+ clearAll() {
+ // Everything is reset.
+ let instance = M.Tooltip.getInstance(this.elements.queryBuilderTutorialInfoIcon);
+
+ this.hideEverything();
+ this.elements.counter = 0;
+ this.elements.concordanceQueryBuilder.classList.remove('modal-close');
+ this.elements.positionalAttrArea.classList.add('hide');
+ this.elements.structuralAttrArea.classList.add('hide');
+ this.elements.yourQuery.innerHTML = '';
+ this.elements.queryContainer.classList.add('hide');
+ this.elements.entity.innerHTML = 'Entity';
+ this.elements.sentence.innerHTML = 'Sentence';
+
+ // If the Modal is open after 5 seconds for 5 seconds (with 'instance'), a message is displayed indicating that further information can be obtained via the question mark icon
+ instance.tooltipEl.style.background = '#98ACD2';
+ instance.tooltipEl.style.borderTop = 'solid 4px #0064A3';
+ instance.tooltipEl.style.padding = '10px';
+ instance.tooltipEl.style.color = 'black';
+
+ setTimeout(() => {
+ let modalInstance = M.Modal.getInstance(this.elements.concordanceQueryBuilder);
+ if (modalInstance.isOpen) {
+ instance.open();
+ setTimeout(() => {
+ instance.close();
+ }, 5000);
+ }
+ }, 5000);
+ }
+
+
+ hideEverything() {
+ let elementsToHide = ['wordBuilder', 'lemmaBuilder', 'ignoreCaseCheckbox', 'inputOptions', 'incidenceModifiersButton', 'conditionContainer', 'englishPosBuilder', 'germanPosBuilder', 'simplePosBuilder', 'entityBuilder', 'textAnnotationBuilder'];
+ elementsToHide = elementsToHide.map(element => this.elements[element]);
+ this.toggleClass(elementsToHide, 'hide', 'add');
+ }
+
+ tutorialIconHandler(id) {
+ setTimeout(() => {
+ window.location.href= id;
+ }, 0);
+
+ }
+}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
new file mode 100644
index 00000000..c53494d4
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js
@@ -0,0 +1,95 @@
+class StructuralAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBuilder {
+ constructor(elements) {
+ super(elements);
+ this.elements = elements;
+ }
+
+ addSentence() {
+ this.hideEverything();
+ if (this.elements.sentence.text === 'End Sentence') {
+ this.queryChipFactory('end-sentence', 'Sentence End', ' ');
+ this.elements.sentence.innerHTML = 'Sentence';
+ } else {
+ this.queryChipFactory('start-sentence', 'Sentence Start', '');
+ this.elements.sentence.innerHTML = 'End Sentence';
+ }
+ }
+
+ addEntity() {
+ if (this.elements.entity.text === 'End Entity') {
+ let queryText;
+ if (this.elements.entityAnyType === false) {
+ queryText = '';
+ } else {
+ queryText = '';
+ }
+ this.queryChipFactory('end-entity', 'Entity End', queryText);
+ this.elements.entity.innerHTML = 'Entity';
+ } else {
+ this.hideEverything();
+ this.elements.entityBuilder.classList.remove('hide');
+ window.location.href = '#entity-builder';
+ }
+ }
+
+ englishEntTypeHandler() {
+ this.queryChipFactory('start-entity', 'Entity Type=' + this.elements.englishEntType.value, '');
+ this.elements.entity.innerHTML = 'End Entity';
+ this.hideEverything();
+ this.elements.entityAnyType = false;
+
+ // Resets materialize select dropdown
+ let SelectInstance = M.FormSelect.getInstance(this.elements.englishEntType);
+ SelectInstance.input.value = 'English ent_type';
+ this.elements.englishEntType.value = 'default';
+ }
+
+ germanEntTypeHandler() {
+ this.queryChipFactory('start-entity', 'Entity Type=' + this.elements.germanEntType.value, '');
+ this.elements.entity.innerHTML = 'End Entity';
+ this.hideEverything();
+ this.elements.entityAnyType = false;
+
+ // Resets materialize select dropdown
+ let SelectInstance = M.FormSelect.getInstance(this.elements.germanEntType);
+ SelectInstance.input.value = 'German ent_type';
+ this.elements.germanEntType.value = 'default';
+ }
+
+ emptyEntityButton() {
+ this.queryChipFactory('start-empty-entity', 'Entity Start', '');
+ this.elements.entity.innerHTML = 'End Entity';
+ this.hideEverything();
+ this.elements.entityAnyType = true;
+ }
+
+ addTextAnnotation() {
+ this.hideEverything();
+ this.elements.textAnnotationBuilder.classList.remove('hide');
+ window.location.href = '#text-annotation-builder';
+
+ // Resets materialize select dropdown
+ let SelectInstance = M.FormSelect.getInstance(this.elements.textAnnotationOptions);
+ SelectInstance.input.value = 'address';
+ this.elements.textAnnotationOptions.value = 'address';
+ this.elements.textAnnotationInput.value= '';
+ }
+
+ textAnnotationSubmitHandler() {
+ let noValueMetadataMessage = document.querySelector('#no-value-metadata-message');
+ if (this.elements.textAnnotationInput.value === '') {
+ this.elements.textAnnotationSubmit.classList.add('red');
+ noValueMetadataMessage.classList.remove('hide');
+ setTimeout(() => {
+ this.elements.textAnnotationSubmit.classList.remove('red');
+ }, 500);
+ setTimeout(() => {
+ noValueMetadataMessage.classList.add('hide');
+ }, 3000);
+ } else {
+ let queryText = `:: match.text_${this.elements.textAnnotationOptions.value}="${this.elements.textAnnotationInput.value}"`;
+ this.queryChipFactory('text-annotation', `${this.elements.textAnnotationOptions.value}=${this.elements.textAnnotationInput.value}`, queryText);
+ this.hideEverything();
+ }
+ }
+}
diff --git a/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
new file mode 100644
index 00000000..6ebc5e3c
--- /dev/null
+++ b/app/static/js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js
@@ -0,0 +1,461 @@
+class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBuilder {
+ constructor(elements) {
+ super(elements);
+ this.elements = elements;
+ }
+
+ //#region General functions of the Token Builder
+ tokenTypeSelector() {
+ this.hideEverything();
+ switch (this.elements.positionalAttr.value) {
+ case 'word':
+ this.wordBuilder();
+ break;
+ case 'lemma':
+ this.lemmaBuilder();
+ break;
+ case 'english-pos':
+ this.englishPosHandler();
+ break;
+ case 'german-pos':
+ this.germanPosHandler();
+ break;
+ case 'simple-pos-button':
+ this.simplePosBuilder();
+ break;
+ case 'empty-token':
+ this.emptyTokenHandler();
+ break;
+ default:
+ this.wordBuilder();
+ break;
+ }
+ }
+
+ tokenChipFactory(prettyQueryText, tokenText) {
+ tokenText = encodeURI(tokenText);
+ let builderElement;
+ let queryChipElement;
+ builderElement = document.createElement('div');
+ builderElement.innerHTML = `
+
+ ${prettyQueryText}
+ close
+
`;
+ queryChipElement = builderElement.firstElementChild;
+ queryChipElement.addEventListener('click', () => {this.deleteTokenAttr(queryChipElement);});
+ this.elements.tokenQuery.appendChild(queryChipElement);
+ }
+
+ deleteTokenAttr(attr) {
+ if (this.elements.tokenQuery.childNodes.length < 2) {
+ this.elements.tokenQuery.removeChild(attr);
+ this.wordBuilder();
+ } else {
+ this.elements.tokenQuery.removeChild(attr);
+ }
+
+ }
+
+ addTokenToQuery() {
+ let c;
+ let tokenQueryContent = ''; //for ButtonFactory(prettyQueryText)
+ let tokenQueryText = ''; //for ButtonFactory(queryText)
+ this.elements.cancelBool = false;
+ let tokenIsEmpty = false;
+
+ if (this.elements.ignoreCase.checked) {
+ c = ' %c';
+ } else {
+ c = '';
+ }
+
+ for (let element of this.elements.tokenQuery.childNodes) {
+ tokenQueryContent += ' ' + element.firstChild.data + ' ';
+ tokenQueryText += decodeURI(element.dataset.tokentext);
+ if (element.innerText.indexOf('empty token') !== -1) {
+ tokenIsEmpty = true;
+ }
+ }
+
+ if (this.elements.tokenQueryFilled === false) {
+ switch (this.elements.positionalAttr.value) {
+ case 'word':
+ if (this.elements.wordInput.value === '') {
+ this.disableTokenSubmit();
+ } else {
+ tokenQueryContent += `word=${this.elements.wordInput.value}${c}`;
+ tokenQueryText += `word="${this.elements.wordInput.value}"${c}`;
+ this.elements.wordInput.value = '';
+ }
+ break;
+ case 'lemma':
+ if (this.elements.lemmaInput.value === '') {
+ this.disableTokenSubmit();
+ } else {
+ tokenQueryContent += `lemma=${this.elements.lemmaInput.value}${c}`;
+ tokenQueryText += `lemma="${this.elements.lemmaInput.value}"${c}`;
+ this.elements.lemmaInput.value = '';
+ }
+ break;
+ case 'english-pos':
+ if (this.elements.englishPos.value === 'default') {
+ this.disableTokenSubmit();
+ } else {
+ tokenQueryContent += `pos=${this.elements.englishPos.value}`;
+ tokenQueryText += `pos="${this.elements.englishPos.value}"`;
+ this.elements.englishPos.value = '';
+ }
+ break;
+ case 'german-pos':
+ if (this.elements.germanPos.value === 'default') {
+ this.disableTokenSubmit();
+ } else {
+ tokenQueryContent += `pos=${this.elements.germanPos.value}`;
+ tokenQueryText += `pos="${this.elements.germanPos.value}"`;
+ this.elements.germanPos.value = '';
+ }
+ break;
+ case 'simple-pos-button':
+ if (this.elements.simplePos.value === 'default') {
+ this.disableTokenSubmit();
+ } else {
+ tokenQueryContent += `simple_pos=${this.elements.simplePos.value}`;
+ tokenQueryText += `simple_pos="${this.elements.simplePos.value}"`;
+ this.elements.simplePos.value = '';
+ }
+ break;
+ default:
+ this.wordBuilder();
+ break;
+ }
+ }
+
+ // cancelBool looks in disableTokenSubmit() whether a value is passed. If the input fields/dropdowns are empty (cancelBool === true), no token is added.
+ if (this.elements.cancelBool === false) {
+ // Square brackets are added only if it is not an empty token (where they are already present).
+ if (tokenIsEmpty === false) {
+ tokenQueryText = '[' + tokenQueryText + ']';
+ }
+ this.queryChipFactory('token', tokenQueryContent, tokenQueryText);
+ this.hideEverything();
+ this.elements.positionalAttrArea.classList.add('hide');
+ this.elements.tokenQuery.innerHTML = '';
+ }
+
+ }
+
+ disableTokenSubmit() {
+ this.elements.cancelBool = true;
+ this.elements.tokenSubmitButton.classList.add('red');
+ this.elements.noValueMessage.classList.remove('hide');
+ setTimeout(() => {
+ this.elements.tokenSubmitButton.classList.remove('red');
+ }, 500);
+ setTimeout(() => {
+ this.elements.noValueMessage.classList.add('hide');
+ }, 3000);
+ }
+
+ inputFieldHandler() {
+ let input;
+
+ if (this.elements.wordBuilder.classList.contains('hide') === false) {
+ input = this.elements.wordInput;
+ } else {
+ input = this.elements.lemmaInput;
+ }
+
+ if (input.value === '') {
+ this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
+ this.elements.or.classList.add('disabled');
+ this.elements.and.classList.add('disabled');
+ } else {
+ this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
+ this.elements.or.classList.remove('disabled');
+ this.elements.and.classList.remove('disabled');
+ }
+ }
+
+ //#endregion General functions of the Token Builder
+
+ //#region Dropdown Select Handler
+
+ lemmaBuilder() {
+ this.hideEverything();
+ this.elements.lemmaInput.value = '';
+ this.elements.lemmaBuilder.classList.remove('hide');
+ this.elements.inputOptions.classList.remove('hide');
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
+ this.elements.conditionContainer.classList.remove('hide');
+ this.elements.ignoreCaseCheckbox.classList.remove('hide');
+
+ this.elements.incidenceModifiersButton.firstElementChild.classList.add('disabled');
+ this.elements.or.classList.add('disabled');
+ this.elements.and.classList.add('disabled');
+ }
+
+ englishPosHandler() {
+ this.hideEverything();
+ this.elements.englishPosBuilder.classList.remove('hide');
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.conditionContainer.classList.remove('hide');
+ this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
+ this.elements.or.classList.remove('disabled');
+ this.elements.and.classList.remove('disabled');
+
+ // Resets materialize select dropdown
+ let selectInstance = M.FormSelect.getInstance(this.elements.englishPos);
+ selectInstance.input.value = 'English pos tagset';
+ this.elements.englishPos.value = 'default';
+ }
+
+ germanPosHandler() {
+ this.hideEverything();
+ this.elements.germanPosBuilder.classList.remove('hide');
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.conditionContainer.classList.remove('hide');
+ this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
+ this.elements.or.classList.remove('disabled');
+ this.elements.and.classList.remove('disabled');
+
+ // Resets materialize select dropdown
+ let selectInstance = M.FormSelect.getInstance(this.elements.germanPos);
+ selectInstance.input.value = 'German pos tagset';
+ this.elements.germanPos.value = 'default';
+ }
+
+ simplePosBuilder() {
+ this.hideEverything();
+ this.elements.simplePosBuilder.classList.remove('hide');
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.conditionContainer.classList.remove('hide');
+ this.elements.simplePos.selectedIndex = 0;
+ this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
+ this.elements.or.classList.remove('disabled');
+ this.elements.and.classList.remove('disabled');
+
+ // Resets materialize select dropdown
+ let selectInstance = M.FormSelect.getInstance(this.elements.simplePos);
+ selectInstance.input.value = 'simple_pos tagset';
+ this.elements.simplePos.value = 'default';
+ M.FormSelect.init(
+ selectInstance,
+ {
+ dropdownOptions: {
+ direction: 'bottom',
+ coverTrigger: false
+ }
+ }
+ )
+
+ }
+
+ emptyTokenHandler() {
+ this.tokenChipFactory('empty token', '[]');
+ this.elements.tokenQueryFilled = true;
+ this.hideEverything();
+ this.elements.incidenceModifiersButton.classList.remove('hide');
+ this.elements.incidenceModifiersButton.firstElementChild.classList.remove('disabled');
+
+ }
+ //#endregion Dropdown Select Handler
+
+ //#region Options to edit your token - Wildcard Charakter, Option Group, Incidence Modifiers, Ignore Case, 'and', 'or'
+
+ inputOptionHandler(elem) {
+ let input;
+
+ if (this.elements.wordBuilder.classList.contains('hide') === false) {
+ input = this.elements.wordInput;
+ } else {
+ input = this.elements.lemmaInput;
+ }
+
+ if (elem === this.elements.optionGroup) {
+ input.value += '(option1|option2)';
+ let firstIndex = input.value.indexOf('option1');
+ let lastIndex = firstIndex + 'option1'.length;
+ input.focus();
+ input.setSelectionRange(firstIndex, lastIndex);
+ } else if (elem === this.elements.wildcardChar) {
+ input.value += '.';
+ }
+ this.inputFieldHandler();
+ }
+
+ nSubmitHandler() {
+ let instance = M.Modal.getInstance(this.elements.exactlyN);
+ instance.close();
+
+ switch (this.elements.positionalAttr.value) {
+ case 'word':
+ this.elements.wordInput.value += ' {' + this.elements.nInput.value + '}';
+ break;
+ case 'lemma':
+ this.elements.lemmaInput.value += ' {' + this.elements.nInput.value + '}';
+ break;
+ case 'english-pos':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
+ this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
+ this.elements.englishPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'german-pos':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
+ this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
+ this.elements.germanPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'simple-pos-button':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
+ this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
+ this.elements.simplePosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'empty-token':
+ this.tokenChipFactory('{' + this.elements.nInput.value + '}', '{' + this.elements.nInput.value + '}');
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ nmSubmitHandler() {
+ let instance = M.Modal.getInstance(this.elements.betweenNM);
+ instance.close();
+
+ switch (this.elements.positionalAttr.value) {
+ case 'word':
+ this.elements.wordInput.value += `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`;
+ break;
+ case 'lemma':
+ this.elements.lemmaInput.value += `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`;
+ break;
+ case 'english-pos':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
+ this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
+ this.elements.englishPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'german-pos':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
+ this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
+ this.elements.germanPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'simple-pos-button':
+ this.elements.tokenQueryFilled = true;
+ this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
+ this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
+ this.elements.simplePosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ break;
+ case 'empty-token':
+ this.tokenChipFactory(`{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`, `{${this.elements.nmInput.value}, ${this.elements.mInput.value}}`);
+ break;
+ default:
+ break;
+ }
+ }
+
+ incidenceModifiersHandler(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.
+ if (this.elements.positionalAttr.value === 'empty-token') {
+ this.tokenChipFactory(elem.innerText, elem.dataset.token);
+ } else if (this.elements.positionalAttr.value === 'english-pos') {
+ this.tokenChipFactory(`pos=${this.elements.englishPos.value}`, `pos="${this.elements.englishPos.value}"`);
+ this.tokenChipFactory(elem.innerText, elem.dataset.token);
+ this.elements.englishPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ this.elements.tokenQueryFilled = true;
+ } else if (this.elements.positionalAttr.value === 'german-pos') {
+ this.tokenChipFactory(`pos=${this.elements.germanPos.value}`, `pos="${this.elements.germanPos.value}"`);
+ this.tokenChipFactory(elem.innerText, elem.dataset.token);
+ this.elements.germanPosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ this.elements.tokenQueryFilled = true;
+ } else if (this.elements.positionalAttr.value === 'simple-pos-button') {
+ this.tokenChipFactory(`simple_pos=${this.elements.simplePos.value}`, `simple_pos="${this.elements.simplePos.value}"`);
+ this.tokenChipFactory(elem.innerText, elem.dataset.token);
+ this.elements.simplePosBuilder.classList.add('hide');
+ this.elements.incidenceModifiersButton.classList.add('hide');
+ this.elements.tokenQueryFilled = true;
+ } else {
+ let input;
+
+ if (this.elements.wordBuilder.classList.contains('hide') === false) {
+ input = this.elements.wordInput;
+ } else {
+ input = this.elements.lemmaInput;
+ }
+ input.value += elem.dataset.token;
+ }
+
+ }
+
+ orHandler() {
+ this.conditionHandler('or', ' | ');
+ }
+
+ andHandler() {
+ this.conditionHandler('and', ' & ');
+ }
+
+ conditionHandler(conditionText, conditionQueryContent) {
+ this.hideEverything();
+ let tokenQueryContent;
+ let tokenQueryText;
+ let c;
+
+ if (this.elements.ignoreCase.checked) {
+ c = ' %c';
+ } else {
+ c = '';
+ }
+
+ switch (this.elements.positionalAttr.value) {
+ case 'word':
+ tokenQueryContent = `word=${this.elements.wordInput.value}${c}`;
+ tokenQueryText = `word="${this.elements.wordInput.value}"${c}`;
+ this.elements.wordInput.value = '';
+ break;
+ case 'lemma':
+ tokenQueryContent = `lemma=${this.elements.lemmaInput.value}${c}`;
+ tokenQueryText = `lemma="${this.elements.lemmaInput.value}"${c}`;
+ this.elements.lemmaInput.value = '';
+ break;
+ case 'english-pos':
+ tokenQueryContent = `pos=${this.elements.englishPos.value}`;
+ tokenQueryText = `pos="${this.elements.englishPos.value}"`;
+ this.elements.englishPos.value = '';
+ break;
+ case 'german-pos':
+ tokenQueryContent = `pos=${this.elements.germanPos.value}`;
+ tokenQueryText = `pos="${this.elements.germanPos.value}"`;
+ this.elements.germanPos.value = '';
+ break;
+ case 'simple-pos-button':
+ tokenQueryContent = `simple_pos=${this.elements.simplePos.value}`;
+ tokenQueryText = `simple_pos="${this.elements.simplePos.value}"`;
+ this.elements.simplePos.value = '';
+ break;
+ default:
+ this.wordBuilder();
+ break;
+ }
+
+ this.tokenChipFactory(tokenQueryContent, tokenQueryText);
+ this.tokenChipFactory(conditionText, conditionQueryContent);
+ this.wordBuilder();
+ }
+
+ //#endregion Options to edit your token - Wildcard Charakter, Option Group, Incidence Modifiers, Ignore Case, 'and', 'or'
+}
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index c68b6146..15bfb8db 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -31,6 +31,10 @@
'js/CorpusAnalysis/CorpusAnalysisReader.js',
'js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js',
'js/CorpusAnalysis/QueryBuilder.js',
+ 'js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js',
+ 'js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js',
+ 'js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js',
+ 'js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js',
'js/XMLtoObject.js'
%}
diff --git a/app/templates/corpora/_analysis/_query_builderOLD.html.j2 b/app/templates/corpora/_analysis/_query_builderOLD.html.j2
new file mode 100644
index 00000000..e0283353
--- /dev/null
+++ b/app/templates/corpora/_analysis/_query_builderOLD.html.j2
@@ -0,0 +1,403 @@
+
+
+
+
+
+
+
+
+
+
Use the following options to build your query. If you need help, click on the question mark in the upper right corner!
+
+
Add new token to your query
+
Add structural attributes to your query
+
+
+
+
Which structural attribute do you want to add to your query?help_outline
+
+
+
+
+
+
+
+
+
Add Entity of any type
+
+
+
+ English ent_type
+ CARDINAL
+ DATE
+ EVENT
+ FAC
+ GPE
+ LANGUAGE
+ LAW
+ LOC
+ MONEY
+ NORP
+ ORDINAL
+ ORG
+ PERCENT
+ PERSON
+ PRODUCT
+ QUANTITY
+ TIME
+ WORK_OF_ART
+
+ Entity Type
+
+
+
+ German ent_type
+ LOC
+ MISC
+ ORG
+ PER
+
+
+
+
+
+
+
+
+
+
+
+
+ address
+ author
+ booktitle
+ chapter
+ editor
+ institution
+ journal
+ pages
+ publisher
+ publishing year
+ school
+ title
+
+ Meta data
+
+
+ mode_edit
+
+
+
+
No value entered!
+
+
+
+
+
+
+
+
+
+
+ word
+ lemma
+ english pos
+ german pos
+ simple_pos
+ empty token
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ English pos tagset
+ email
+ affix
+ conjunction, coordinating
+ cardinal number
+ determiner
+ existential there
+ foreign word
+ punctuation mark, hyphen
+ conjunction, subordinating or preposition
+ adjective
+ adjective, comparative
+ adjective, superlative
+ list item marker
+ verb, modal auxillary
+ superfluous punctuation
+ noun, singular or mass
+ noun, proper singular
+ noun, proper plural
+ noun, plural
+ predeterminer
+ possessive ending
+ pronoun, personal
+ pronoun, possessive
+ adverb, comparative
+ adverb, superlative
+ adverb, particle
+ symbol
+ infinitival to
+ interjection
+ verb, base form
+ verb, past tense
+ verb, gerund or present participle
+ verb, past participle
+ verb, non-3rd person singular present
+ verb, 3rd person singular present
+ wh-determiner
+ wh-pronoun, personal
+ wh-pronoun, possessive
+ wh-adverb
+ unknown
+ opening quotation mark
+ symbol, currency
+ closing quotation mark
+ left round bracket
+ right round bracket
+ punctuation mark, sentence closer
+ punctuation mark, colon or ellipsis
+
+ Part-of-speech tags
+
+
+
+
+
+
+
+
+
+
+ German pos tagset
+ adjective, attributive
+ adjective, adverbial or predicative
+ adverb
+ postposition
+ preposition; circumposition left
+ preposition with article
+ circumposition right
+ definite or indefinite article
+ cardinal number
+ foreign word
+ interjection
+ comparative conjunction
+ coordinating conjunction
+ subordinating conjunction with "zu" and infinitive
+ subordinating conjunction with sentence
+ proper noun
+ noun, singular or mass
+ proper noun
+ attributive demonstrative pronoun
+ substituting demonstrative pronoun
+ attributive indefinite pronoun without determiner
+ substituting indefinite pronoun
+ non-reflexive personal pronoun
+ attributive possessive pronoun
+ substituting possessive pronoun
+ attributive relative pronoun
+ substituting relative pronoun
+ reflexive personal pronoun
+ pronominal adverb
+ particle with adjective or adverb
+ answer particle
+ negative particle
+ separable verbal particle
+ "zu" before infinitive
+ attributive interrogative pronoun
+ adverbial interrogative or relative pronoun
+ substituting interrogative pronoun
+ word remnant
+ finite verb, auxiliary
+ imperative, auxiliary
+ infinitive, auxiliary
+ perfect participle, auxiliary
+ finite verb, modal
+ infinitive, modal
+ perfect participle, modal
+ finite verb, full
+ imperative, full
+ infinitive, full
+ infinitive with "zu", full
+ perfect participle, full
+ non-word containing non-letter
+ other sentence-internal punctuation mark
+ comma
+ sentence-final punctuation mark
+
+ Part-of-speech tags
+
+
+
+
+
+
+
+
+
+
+ simple_pos tagset
+ adjective
+ adposition
+ adverb
+ auxiliary verb
+ coordinating conjunction
+ determiner
+ interjection
+ noun
+ numeral
+ particle
+ pronoun
+ proper noun
+ punctuation
+ subordinating conjunction
+ symbol
+ verb
+ other
+
+ Simple part-of-speech tags
+
+
+
+
+
+
No value entered!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ignore Case
+
+
+
+
+
+
+
+
+
+
+
+
+ mode_edit
+
+
+
+ mode_edit
+
+
+
+
+
+
+
+
diff --git a/app/templates/corpora/_analysis/concordance.html.j2 b/app/templates/corpora/_analysis/concordance.html.j2
index 3faf20c0..7fe1c6a6 100644
--- a/app/templates/corpora/_analysis/concordance.html.j2
+++ b/app/templates/corpora/_analysis/concordance.html.j2
@@ -1,3 +1,7 @@
+{% import 'corpora/_analysis/query_builder/_expert_mode.html.j2' as expert_mode with context %}
+{% import 'corpora/_analysis/query_builder/_query_builder.html.j2' as query_builder with context %}
+
+
{% set name = 'Concordance' %}
{% set description %}
@@ -15,24 +19,80 @@ Query your corpus with the CQP query language utilizing a KWIC view.
+
+
+
+
+
+
+
Results
+
+
+
+
-
-
- arrow_forward
-
- Subcorpus name
-
@@ -77,31 +137,8 @@ Query your corpus with the CQP query language utilizing a KWIC view.
-
-
-
-
-
-
-
-
-
-
-
@@ -127,442 +164,38 @@ Query your corpus with the CQP query language utilizing a KWIC view.
{% endset %}
{% set modals %}
-
+
+
Which structural attribute do you want to add to your query?help_outline
+
-
Examples
-
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
- tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero
- eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
- takimata sanctus est Lorem ipsum dolor sit amet.
-
-
-
-
-
-
-
-
-
-
-
-
-
Use the following options to build your query. If you need help, click on the question mark in the upper right corner!
-
-
Add new token to your query
-
Add structural attributes to your query
-
-
-
-
Which structural attribute do you want to add to your query?help_outline
-
-
-
-
-
-
-
-
-
Add Entity of any type
-
-
-
- English ent_type
- CARDINAL
- DATE
- EVENT
- FAC
- GPE
- LANGUAGE
- LAW
- LOC
- MONEY
- NORP
- ORDINAL
- ORG
- PERCENT
- PERSON
- PRODUCT
- QUANTITY
- TIME
- WORK_OF_ART
-
- Entity Type
-
-
-
- German ent_type
- LOC
- MISC
- ORG
- PER
-
-
-
-
-
-
-
-
-
-
-
-
- address
- author
- booktitle
- chapter
- editor
- institution
- journal
- pages
- publisher
- publishing year
- school
- title
-
- Meta data
-
-
- mode_edit
-
-
-
-
No value entered!
-
-
-
-
-
-
-
-
-
-
- word
- lemma
- english pos
- german pos
- simple_pos
- empty token
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- English pos tagset
- email
- affix
- conjunction, coordinating
- cardinal number
- determiner
- existential there
- foreign word
- punctuation mark, hyphen
- conjunction, subordinating or preposition
- adjective
- adjective, comparative
- adjective, superlative
- list item marker
- verb, modal auxillary
- superfluous punctuation
- noun, singular or mass
- noun, proper singular
- noun, proper plural
- noun, plural
- predeterminer
- possessive ending
- pronoun, personal
- pronoun, possessive
- adverb, comparative
- adverb, superlative
- adverb, particle
- symbol
- infinitival to
- interjection
- verb, base form
- verb, past tense
- verb, gerund or present participle
- verb, past participle
- verb, non-3rd person singular present
- verb, 3rd person singular present
- wh-determiner
- wh-pronoun, personal
- wh-pronoun, possessive
- wh-adverb
- unknown
- opening quotation mark
- symbol, currency
- closing quotation mark
- left round bracket
- right round bracket
- punctuation mark, sentence closer
- punctuation mark, colon or ellipsis
-
- Part-of-speech tags
-
-
-
-
-
-
-
-
-
-
- German pos tagset
- adjective, attributive
- adjective, adverbial or predicative
- adverb
- postposition
- preposition; circumposition left
- preposition with article
- circumposition right
- definite or indefinite article
- cardinal number
- foreign word
- interjection
- comparative conjunction
- coordinating conjunction
- subordinating conjunction with "zu" and infinitive
- subordinating conjunction with sentence
- proper noun
- noun, singular or mass
- proper noun
- attributive demonstrative pronoun
- substituting demonstrative pronoun
- attributive indefinite pronoun without determiner
- substituting indefinite pronoun
- non-reflexive personal pronoun
- attributive possessive pronoun
- substituting possessive pronoun
- attributive relative pronoun
- substituting relative pronoun
- reflexive personal pronoun
- pronominal adverb
- particle with adjective or adverb
- answer particle
- negative particle
- separable verbal particle
- "zu" before infinitive
- attributive interrogative pronoun
- adverbial interrogative or relative pronoun
- substituting interrogative pronoun
- word remnant
- finite verb, auxiliary
- imperative, auxiliary
- infinitive, auxiliary
- perfect participle, auxiliary
- finite verb, modal
- infinitive, modal
- perfect participle, modal
- finite verb, full
- imperative, full
- infinitive, full
- infinitive with "zu", full
- perfect participle, full
- non-word containing non-letter
- other sentence-internal punctuation mark
- comma
- sentence-final punctuation mark
-
- Part-of-speech tags
-
-
-
-
-
-
-
-
-
-
- simple_pos tagset
- adjective
- adposition
- adverb
- auxiliary verb
- coordinating conjunction
- determiner
- interjection
- noun
- numeral
- particle
- pronoun
- proper noun
- punctuation
- subordinating conjunction
- symbol
- verb
- other
-
- Simple part-of-speech tags
-
-
-
-
-
-
No value entered!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ignore Case
-
-
-
-
-
-
-
-
-
-
-
-
- mode_edit
-
-
-
- mode_edit
-
-
-
-
-
-
-
-
-
{% endset %}
{% set scripts %}
{% endset %}
diff --git a/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2 b/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2
new file mode 100644
index 00000000..21443d4e
--- /dev/null
+++ b/app/templates/corpora/_analysis/query_builder/_expert_mode.html.j2
@@ -0,0 +1,26 @@
+{% macro card_content(id_prefix) %}
+
+
+
+
+ arrow_forward
+
+ Subcorpus name
+
+
+
+
+{% endmacro %}
diff --git a/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2
new file mode 100644
index 00000000..5ddedac9
--- /dev/null
+++ b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2
@@ -0,0 +1,39 @@
+{% macro card_content(id_prefix) %}
+
+
+
+
+ arrow_forward
+
+ Subcorpus name
+
+
+
+
+
+
+{% endmacro %}