From fe7f69d5965090f9a5540b2dcee95bfb46c4aa15 Mon Sep 17 00:00:00 2001 From: Inga Kirschnick <inga.kirschnick@uni-bielefeld.de> Date: Mon, 21 Aug 2023 07:26:54 +0200 Subject: [PATCH] QB form update + incidence modifier --- app/static/css/queryBuilder.css | 45 +++----- .../CorpusAnalysisConcordance.js | 31 +++-- app/static/js/CorpusAnalysis/QueryBuilder.js | 45 -------- .../ElementReferencesQueryBuilder.js | 8 +- .../GeneralFunctionsQueryBuilder.js | 68 ++++++----- ...alAttributeBuilderFunctionsQueryBuilder.js | 22 ++++ ...enAttributeBuilderFunctionsQueryBuilder.js | 37 +++++- .../query_builder/_expert_mode.html.j2 | 2 +- .../query_builder/_query_builder.html.j2 | 107 +++++++++++------- 9 files changed, 197 insertions(+), 168 deletions(-) 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; -} - -#corpus-analysis-concordance-incidence-modifiers-dropdown a{ - background-color: white; -} - -[data-target="corpus-analysis-concordance-incidence-modifiers-dropdown"] { - background-color: #2FBBAB; -} - -#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%; +[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-query-builder-tutorial-modal ul { - margin-top: 10px; +#corpus-analysis-concordance-exactly-n-token-modal, #corpus-analysis-concordance-between-nm-token-modal { + width: 30%; } -#corpus-analysis-concordance-query-builder-tutorial { - padding:15px; +[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-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.elements.expertModeForm.id); + }); + this.elements.queryBuilderForm.addEventListener('submit', (event) => { event.preventDefault(); - this.submitForm(); + 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 { }); } - queryChipFactory(dataType, prettyQueryText, queryText) { - this.elements.counter++; - this.elements.queryInputFieldInstance.addChip({ - tag: prettyQueryText - }); + updateChipList() { + this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.chip'); + } - 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'); + queryChipFactory(dataType, prettyQueryText, queryText) { + queryText = Utils.escape(queryText); + prettyQueryText = Utils.escape(prettyQueryText); + let queryChipElement = Utils.HTMLToElement( + ` + <span class="chip query-component" data-type="${dataType}" data-query="${queryText}" draggable="true"> + ${prettyQueryText} + <i class="material-icons close">close</i> + </span> + ` + ); - 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', '<ent>'); + this.queryChipFactory('end-entity', 'Entity End', '</ent>'); + this.elements.structuralAttrModal.close(); + }); + document.querySelector('.ent-type-selection-action[data-ent-type="english"]').addEventListener('change', (event) => { + this.queryChipFactory('start-entity', `Entity Type=${event.target.value}`, `<ent_type="${event.target.value}">`); + this.queryChipFactory('end-entity', 'Entity End', '</ent_type>'); + this.elements.structuralAttrModal.close(); + }); + + } actionButtonInStrucAttrModalHandler(action) { switch (action) { case 'sentence': + this.queryChipFactory('start-sentence', 'Sentence Start', '<s>'); + this.queryChipFactory('end-sentence', 'Sentence End', '</s>'); + 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) %} <div class="row"> - <form id="corpus-analysis-concordance-form"> + <form id="corpus-analysis-concordance-expert-mode-form"> <div class="input-field col s12 m9"> <i class="material-icons prefix">search</i> <input class="validate corpus-analysis-action" id="corpus-analysis-concordance-form-query" name="query" type="text" required pattern=".*\S+.*" placeholder="Type in your query or use the Query Builder on the right"></input> diff --git a/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 index 21a13f0d..d6452358 100644 --- a/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 +++ b/app/templates/corpora/_analysis/query_builder/_query_builder.html.j2 @@ -1,8 +1,8 @@ {% macro card_content(id_prefix) %} -<form id="corpus-analysis-concordance-form"> +<form id="corpus-analysis-concordance-query-builder-form"> <div class="row"> - <div class="col s9"> - <div class="chips" id="corpus-analysis-concordance-form-query-builder"></div> + <div class="col s9" id="corpus-analysis-concordance-query-builder-input-field-container"> + <div id="corpus-analysis-concordance-query-builder-input-field"></div> </div> <div class="input-field col s3"> <i class="material-icons prefix">arrow_forward</i> @@ -30,6 +30,7 @@ <p></p> <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#corpus-analysis-concordance-positional-attr-modal" data-position="bottom" data-tooltip="Search for any token, for example a word, a lemma or a part-of-speech tag">Add new token to your query</a> <a class="btn waves-effect waves-light tooltipped modal-trigger" href="#corpus-analysis-concordance-structural-attr-modal" data-position="bottom" data-tooltip="Structure your query with structural attributes, for example sentences, entities or annotate the text">Add structural attributes to your query</a> + <a class="btn waves-effect waves-light tooltipped dropdown-trigger disabled" data-target="corpus-analysis-concordance-token-incidence-modifiers-dropdown" data-toggle-area="token-incidence-modifiers" data-position="top" data-tooltip="Incidence Modifiers are special characters or patterns, <br>which determine how often a character represented previously should occur.">incidence modifiers</a> </div> </div> <div class="row"> @@ -42,6 +43,14 @@ </div> </div> </form> + +<ul id="corpus-analysis-concordance-token-incidence-modifiers-dropdown" class="dropdown-content"> + {{ incidence_modifiers_dropdown_content("token") }} +</ul> + +{{ exactly_n_modal_content("token") }} +{{ exactly_nm_modal_content("token") }} + {% endmacro %} {% macro structural_attribute_modal(id_prefix) %} @@ -63,10 +72,10 @@ <p></p> <br> <div class="row"> - <a class="btn waves-effect waves-light col s4" id="corpus-analysis-concordance-empty-entity">Add Entity of any type</a> + <a class="btn waves-effect waves-light col ent-type-selection-action" data-ent-type="any">Add Entity of any type</a> <p class="col s1 l1"></p> <div class= "input-field col s3"> - <select name="englishenttype" id="corpus-analysis-concordance-english-ent-type"> + <select name="englishenttype" class="ent-type-selection-action" data-ent-type="english"> <option value="" disabled selected>English ent_type</option> <option value="CARDINAL">CARDINAL</option> <option value="DATE">DATE</option> @@ -90,7 +99,7 @@ <label>Entity Type</label> </div> <div class= "input-field col s3"> - <select name="germanenttype" id="corpus-analysis-concordance-german-ent-type"> + <select name="germanenttype" class="ent-type-selection-action" data-ent-type="german"> <option value="" disabled selected>German ent_type</option> <option value="LOC">LOC</option> <option value="MISC">MISC</option> @@ -347,10 +356,10 @@ </div> <p></p> <div class="row"> - <div class="col s6" data-toggle-area="input-field-options"> + <div class="col s8" data-toggle-area="input-field-options"> <a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-options-action="wildcard-char" data-position="top" data-tooltip="Look for a variable character (also called wildcard character)">Wildcard character</a> <a class="btn-small waves-effect waves-light tooltipped positional-attr-options-action-button" data-options-action="option-group" data-position="top" data-tooltip="Find character sequences from a list of options">Option Group</a> - <a class="dropdown-trigger btn-small waves-effect waves-light disabled" href="#" data-target="corpus-analysis-concordance-incidence-modifiers-dropdown" data-toggle-area="incidence-modifiers" data-position="top" data-tooltip="Incidence Modifiers are special characters or patterns, <br>which determine how often a character represented previously should occur.">incidence modifiers</a> + <a class="dropdown-trigger btn-small waves-effect waves-light disabled" href="#" data-target="corpus-analysis-concordance-character-incidence-modifiers-dropdown" data-toggle-area="incidence-modifiers" data-position="top" data-tooltip="Incidence Modifiers are special characters or patterns, <br>which determine how often a character represented previously should occur.">incidence modifiers</a> <span data-toggle-area="ignore-case-checkbox"> <label> <input type="checkbox" class="filled-in" id="corpus-analysis-concordance-ignore-case-checkbox"/> @@ -363,47 +372,61 @@ <a class="btn-small tooltipped waves-effect waves-light disabled positional-attr-options-action-button" data-options-action="and" data-toggle-area="and" data-position="bottom" data-tooltip="You can add another condition to your token. <br>Both must be fulfilled">and</a> </div> - <ul id="corpus-analysis-concordance-incidence-modifiers-dropdown" class="dropdown-content"> - <li><a class="tooltipped incidence-modifier-selection" data-token="+" data-incidence-modifier="one-or-more" data-position ="top" data-tooltip="...occurrences of the character/token before">one or more (+)</a></li> - <li><a class="tooltipped incidence-modifier-selection" data-token="*" data-incidence-modifier="zero-or-more" data-position ="top" data-tooltip="...occurrences of the character/token before">zero or more (*)</a></li> - <li><a class="tooltipped incidence-modifier-selection" data-token="?" data-incidence-modifier="zero-or-one" data-position ="top" data-tooltip="...occurrences of the character/token before">zero or one (?)</a></li> - <li><a class="modal-trigger tooltipped" href="#corpus-analysis-concordance-exactly-n-modal" data-position ="top" data-tooltip="...occurrences of the character/token before">exactly n ({n})</a></li> - <li><a class="modal-trigger tooltipped" href="#corpus-analysis-concordance-between-nm-modal" data-position ="top" data-tooltip="...occurrences of the character/token before">between n and m ({n,m})</a></li> + <ul id="corpus-analysis-concordance-character-incidence-modifiers-dropdown" class="dropdown-content"> + {{ incidence_modifiers_dropdown_content("character") }} </ul> </div> </div> </div> - <div id="corpus-analysis-concordance-exactly-n-modal" class="modal"> - <div class="row modal-content"> - <div class="input-field col s10"> - <i class="material-icons prefix">mode_edit</i> - <input class="n-m-input" placeholder="type in a number for 'n'" type="text" data-value-type="n"> - </div> - <div class="col s2"> - <p class="btn-floating waves-effect waves-light n-m-submit-button" data-modal-id="corpus-analysis-concordance-exactly-n-modal"> - <i class="material-icons right">send</i> - </p> - </div> - </div> + + {{ exactly_n_modal_content("character") }} + {{ exactly_nm_modal_content("character") }} + </div> + </div> +</div> +{% endmacro %} - <div id="corpus-analysis-concordance-between-nm-modal" class="modal"> - <div class="row modal-content"> - <div class="input-field col s5"> - <i class="material-icons prefix">mode_edit</i> - <input class="n-m-input" placeholder="number for 'n'" type="text" data-value-type="n"> - </div> - <div class="input-field col s5"> - <i class="material-icons prefix">mode_edit</i> - <input class="n-m-input" placeholder="number for 'm'" type="text" data-value-type="m"> - </div> - <div class="col s2"> - <p class="btn-floating waves-effect waves-light n-m-submit-button" data-modal-id="corpus-analysis-concordance-between-nm-modal"> - <i class="material-icons right">send</i> - </p> - </div> - </div> +{% macro incidence_modifiers_dropdown_content(type) %} +<li><a class="incidence-modifier-selection" data-token="+" data-incidence-modifier="one-or-more">one or more (+)</a></li> +<li><a class="incidence-modifier-selection" data-token="*" data-incidence-modifier="zero-or-more">zero or more (*)</a></li> +<li><a class="incidence-modifier-selection" data-token="?" data-incidence-modifier="zero-or-one">zero or one (?)</a></li> +<li><a class="modal-trigger" href="#corpus-analysis-concordance-exactly-n-{{ type }}-modal">exactly n ({n})</a></li> +<li><a class="modal-trigger" href="#corpus-analysis-concordance-between-nm-{{ type }}-modal">between n and m ({n,m})</a></li> +{% endmacro %} + +{% macro exactly_n_modal_content(type) %} +<div id="corpus-analysis-concordance-exactly-n-{{ type }}-modal" class="modal"> + <div class="row modal-content"> + <div class="input-field col s10"> + <i class="material-icons prefix">mode_edit</i> + <input class="n-m-input" placeholder="type in a number for 'n'" type="text" data-value-type="n"> + </div> + <div class="col s2"> + <p class="btn-floating waves-effect waves-light n-m-submit-button" data-modal-id="corpus-analysis-concordance-exactly-n-{{ type }}-modal"> + <i class="material-icons right">send</i> + </p> + </div> + </div> +</div> +{% endmacro %} + +{% macro exactly_nm_modal_content(type) %} +<div id="corpus-analysis-concordance-between-nm-{{ type }}-modal" class="modal"> + <div class="row modal-content"> + <div class="input-field col s5"> + <i class="material-icons prefix">mode_edit</i> + <input class="n-m-input" placeholder="number for 'n'" type="text" data-value-type="n"> + </div> + <div class="input-field col s5"> + <i class="material-icons prefix">mode_edit</i> + <input class="n-m-input" placeholder="number for 'm'" type="text" data-value-type="m"> + </div> + <div class="col s2"> + <p class="btn-floating waves-effect waves-light n-m-submit-button" data-modal-id="corpus-analysis-concordance-between-nm-{{ type }}-modal"> + <i class="material-icons right">send</i> + </p> </div> </div> </div> -- GitLab