mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	Element Target drag&drop + small improvements
This commit is contained in:
		@@ -3,8 +3,10 @@ nopaque.corpus_analysis.query_builder.ElementReferences = class ElementReference
 | 
				
			|||||||
    // General Elements
 | 
					    // General Elements
 | 
				
			||||||
    this.queryInputField = document.querySelector('#corpus-analysis-concordance-query-builder-input-field');
 | 
					    this.queryInputField = document.querySelector('#corpus-analysis-concordance-query-builder-input-field');
 | 
				
			||||||
    this.queryChipElements = [];
 | 
					    this.queryChipElements = [];
 | 
				
			||||||
 | 
					    this.queryElementTarget = document.querySelector('.query-element-target')
 | 
				
			||||||
    this.editingModusOn = false;
 | 
					    this.editingModusOn = false;
 | 
				
			||||||
    this.editedQueryChipElementIndex = undefined;
 | 
					    this.editedQueryChipElementIndex = undefined;
 | 
				
			||||||
 | 
					    this.deleteQueryButton = document.querySelector('#corpus-analysis-concordance-delete-query-button');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Structural Attribute Builder Elements
 | 
					    // Structural Attribute Builder Elements
 | 
				
			||||||
    this.structuralAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-structural-attr-modal'));
 | 
					    this.structuralAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-structural-attr-modal'));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,25 +2,13 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    this.elements = new nopaque.corpus_analysis.query_builder.ElementReferences();
 | 
					    this.elements = new nopaque.corpus_analysis.query_builder.ElementReferences();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.incidenceModifierEventListeners();
 | 
					    this.addEventListenersToQueryElementTarget();
 | 
				
			||||||
    this.nAndMInputSubmitEventListeners();
 | 
					    this.addEventListenersToIncidenceModifier();
 | 
				
			||||||
 | 
					    this.addEventListenersToNAndMInputSubmit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let queryBuilderDisplay = document.querySelector("#corpus-analysis-concordance-query-builder-display");
 | 
					    this.elements.deleteQueryButton.addEventListener('click', () => {this.resetQueryInputField()});
 | 
				
			||||||
    let expertModeDisplay = document.querySelector("#corpus-analysis-concordance-expert-mode-display");
 | 
					 | 
				
			||||||
    let expertModeSwitch = document.querySelector("#corpus-analysis-concordance-expert-mode-switch");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expertModeSwitch.addEventListener("change", () => {
 | 
					    this.expertModeQueryBuilderSwitchHandler();
 | 
				
			||||||
      const isChecked = expertModeSwitch.checked;
 | 
					 | 
				
			||||||
      if (isChecked) {
 | 
					 | 
				
			||||||
        queryBuilderDisplay.classList.add("hide");
 | 
					 | 
				
			||||||
        expertModeDisplay.classList.remove("hide");
 | 
					 | 
				
			||||||
        this.switchToExpertModeParser();
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        queryBuilderDisplay.classList.remove("hide");
 | 
					 | 
				
			||||||
        expertModeDisplay.classList.add("hide");
 | 
					 | 
				
			||||||
        this.switchToQueryBuilderParser();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.extensions = {
 | 
					    this.extensions = {
 | 
				
			||||||
      structuralAttributeBuilderFunctions: new nopaque.corpus_analysis.query_builder.StructuralAttributeBuilderFunctions(this),
 | 
					      structuralAttributeBuilderFunctions: new nopaque.corpus_analysis.query_builder.StructuralAttributeBuilderFunctions(this),
 | 
				
			||||||
@@ -28,6 +16,38 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  addEventListenersToQueryElementTarget() {
 | 
				
			||||||
 | 
					    this.elements.queryElementTarget.addEventListener('click', () => {
 | 
				
			||||||
 | 
					      this.elements.positionalAttrModal.open();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.elements.queryElementTarget.addEventListener('dragstart', this.handleDragStart.bind(this, this.elements.queryElementTarget));
 | 
				
			||||||
 | 
					    this.elements.queryElementTarget.addEventListener('dragend', this.handleDragEnd);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  addEventListenersToIncidenceModifier() {
 | 
				
			||||||
 | 
					    // Eventlisteners for the incidence modifiers. There are two different types of incidence modifiers: token and character incidence modifiers.
 | 
				
			||||||
 | 
					    document.querySelectorAll('.incidence-modifier-selection').forEach(button => {
 | 
				
			||||||
 | 
					      let dropdownId = button.parentNode.parentNode.id;
 | 
				
			||||||
 | 
					      if (dropdownId === 'corpus-analysis-concordance-token-incidence-modifiers-dropdown') {
 | 
				
			||||||
 | 
					        button.addEventListener('click', () => this.tokenIncidenceModifierHandler(button.dataset.token, button.innerHTML));
 | 
				
			||||||
 | 
					      } else if (dropdownId === 'corpus-analysis-concordance-character-incidence-modifiers-dropdown') {
 | 
				
			||||||
 | 
					        button.addEventListener('click', () => this.extensions.tokenAttributeBuilderFunctions.characterIncidenceModifierHandler(button));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  addEventListenersToNAndMInputSubmit() {
 | 
				
			||||||
 | 
					    // Eventlisteners for the submit of n- and m-values of the incidence modifier modal for "exactly n" or "between n and m".
 | 
				
			||||||
 | 
					    document.querySelectorAll('.n-m-submit-button').forEach(button => {
 | 
				
			||||||
 | 
					      let modalId = button.dataset.modalId;
 | 
				
			||||||
 | 
					      if (modalId === 'corpus-analysis-concordance-exactly-n-token-modal' || modalId === 'corpus-analysis-concordance-between-nm-token-modal') {
 | 
				
			||||||
 | 
					        button.addEventListener('click', () => this.tokenNMSubmitHandler(modalId));
 | 
				
			||||||
 | 
					      } else if (modalId === 'corpus-analysis-concordance-exactly-n-character-modal' || modalId === 'corpus-analysis-concordance-between-nm-character-modal') {
 | 
				
			||||||
 | 
					        button.addEventListener('click', () => this.extensions.tokenAttributeBuilderFunctions.characterNMSubmitHandler(modalId));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  toggleClass(elements, className, action) {
 | 
					  toggleClass(elements, className, action) {
 | 
				
			||||||
    elements.forEach(element => {
 | 
					    elements.forEach(element => {
 | 
				
			||||||
      document.querySelector(`[data-toggle-area="${element}"]`).classList[action](className);
 | 
					      document.querySelector(`[data-toggle-area="${element}"]`).classList[action](className);
 | 
				
			||||||
@@ -36,27 +56,28 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  resetQueryInputField() {
 | 
					  resetQueryInputField() {
 | 
				
			||||||
    this.elements.queryInputField.innerHTML = '';
 | 
					    this.elements.queryInputField.innerHTML = '';
 | 
				
			||||||
    this.addPlaceholder();
 | 
					    this.addQueryElementTarget();
 | 
				
			||||||
    this.updateChipList();
 | 
					    this.updateChipList();
 | 
				
			||||||
    this.queryPreviewBuilder();
 | 
					    this.queryPreviewBuilder();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  addQueryElementTarget() {
 | 
				
			||||||
 | 
					    let queryElementTarget = nopaque.Utils.HTMLToElement(
 | 
				
			||||||
 | 
					      `
 | 
				
			||||||
 | 
					      <a class="query-element-target btn-floating btn-small blue-grey lighten-4 waves-effect waves-light tooltipped" style="margin-bottom:10px; margin-right:5px;" draggable="true" data-position="bottom" data-tooltip="Add an Element to your query">
 | 
				
			||||||
 | 
					        <i class="material-icons">add</i>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					      `
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    this.elements.queryInputField.appendChild(queryElementTarget);
 | 
				
			||||||
 | 
					    this.elements.queryElementTarget = queryElementTarget;
 | 
				
			||||||
 | 
					    this.addEventListenersToQueryElementTarget();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateChipList() {
 | 
					  updateChipList() {
 | 
				
			||||||
    this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.query-component');
 | 
					    this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.query-component');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  removePlaceholder() {
 | 
					 | 
				
			||||||
    let placeholder = this.elements.queryInputField.querySelector('#corpus-analysis-concordance-query-builder-input-field-placeholder');
 | 
					 | 
				
			||||||
    if (placeholder && this.elements.queryInputField !== undefined) {
 | 
					 | 
				
			||||||
      this.elements.queryInputField.innerHTML = '';
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  addPlaceholder() {
 | 
					 | 
				
			||||||
    let placeholder = nopaque.Utils.HTMLToElement('<span id="corpus-analysis-concordance-query-builder-input-field-placeholder">Click on a button to add a query component</span>');
 | 
					 | 
				
			||||||
    this.elements.queryInputField.appendChild(placeholder);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  resetMaterializeSelection(selectionElements, value = "default") {
 | 
					  resetMaterializeSelection(selectionElements, value = "default") {
 | 
				
			||||||
    selectionElements.forEach(selectionElement => {
 | 
					    selectionElements.forEach(selectionElement => {
 | 
				
			||||||
      if (selectionElement.querySelector(`option[value=${value}]`) !== null) {
 | 
					      if (selectionElement.querySelector(`option[value=${value}]`) !== null) {
 | 
				
			||||||
@@ -89,32 +110,32 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
      `
 | 
					      `
 | 
				
			||||||
        <span class="chip query-component" data-type="${dataType}" data-query="${queryText}" draggable="true" data-closing-tag="${isClosingTag}">
 | 
					        <span class="chip query-component" data-type="${dataType}" data-query="${queryText}" draggable="true" data-closing-tag="${isClosingTag}">
 | 
				
			||||||
          ${prettyQueryText}${isEditable ? '<i class="material-icons chip-action-button" data-chip-action="edit" style="padding-left:5px; font-size:18px; cursor:pointer;">edit</i>': ''}
 | 
					          ${prettyQueryText}${isEditable ? '<i class="material-icons chip-action-button" data-chip-action="edit" style="padding-left:5px; font-size:18px; cursor:pointer;">edit</i>': ''}
 | 
				
			||||||
          ${isClosingTag ? '<i class="material-icons chip-action-button" data-chip-action="lock" style="padding-top:5px; font-size:20px; cursor:pointer;">lock_open</i>' : '<i class="material-icons close chip-action-button" data-chip-action="delete">close</i>'}
 | 
					          ${isClosingTag ? '' : '<i class="material-icons close chip-action-button" data-chip-action="delete">close</i>'}
 | 
				
			||||||
        </span>
 | 
					        </span>
 | 
				
			||||||
      `
 | 
					      `
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    this.addActionListeners(queryChipElement);
 | 
					    this.addActionListeners(queryChipElement);
 | 
				
			||||||
    queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement));
 | 
					    queryChipElement.addEventListener('dragstart', this.handleDragStart.bind(this, queryChipElement));
 | 
				
			||||||
    queryChipElement.addEventListener('dragend', this.handleDragEnd);
 | 
					    queryChipElement.addEventListener('dragend', this.handleDragEnd);
 | 
				
			||||||
 | 
					    // If an index is given, inserts the query chip after the given index (only relevant for Incidence Modifier) and if there is a closing tag, inserts the query chip before the closing tag.
 | 
				
			||||||
    // Ensures that metadata is always at the end of the query and if an index is given, inserts the query chip at the given index and if there is a closing tag, inserts the query chip before the closing tag.
 | 
					    if (index !== null) {
 | 
				
			||||||
    this.removePlaceholder();
 | 
					      this.updateChipList();
 | 
				
			||||||
    if (!index) {
 | 
					      this.elements.queryChipElements[index].after(queryChipElement);
 | 
				
			||||||
      let closingTagElement = this.elements.queryInputField.querySelector('[data-closing-tag="true"]');
 | 
					 | 
				
			||||||
      if (closingTagElement) {
 | 
					 | 
				
			||||||
        index = Array.from(this.elements.queryInputField.children).indexOf(closingTagElement);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (index) {
 | 
					 | 
				
			||||||
      this.elements.queryInputField.insertBefore(queryChipElement, this.elements.queryChipElements[index]);
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.elements.queryInputField.appendChild(queryChipElement);
 | 
					      this.elements.queryInputField.insertBefore(queryChipElement, this.elements.queryElementTarget);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (isClosingTag) {
 | 
				
			||||||
 | 
					      this.moveQueryElementTarget(queryChipElement);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.updateChipList();
 | 
					    this.updateChipList();
 | 
				
			||||||
    this.queryPreviewBuilder();
 | 
					    this.queryPreviewBuilder();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  moveQueryElementTarget(element) {
 | 
				
			||||||
 | 
					    this.elements.queryInputField.insertBefore(this.elements.queryElementTarget, element);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addActionListeners(queryChipElement) {
 | 
					  addActionListeners(queryChipElement) {
 | 
				
			||||||
    let notQuantifiableDataTypes = ['start-sentence', 'end-sentence', 'start-entity', 'start-empty-entity', 'end-entity', 'token-incidence-modifier'];
 | 
					    let notQuantifiableDataTypes = ['start-sentence', 'end-sentence', 'start-entity', 'start-empty-entity', 'end-entity', 'token-incidence-modifier'];
 | 
				
			||||||
    queryChipElement.addEventListener('click', (event) => {
 | 
					    queryChipElement.addEventListener('click', (event) => {
 | 
				
			||||||
@@ -154,20 +175,13 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  lockClosingChipElement(queryChipElement) {
 | 
					 | 
				
			||||||
    queryChipElement.dataset.closingTag = 'false';
 | 
					 | 
				
			||||||
    let lockIcon = queryChipElement.querySelector('[data-chip-action="lock"]');
 | 
					 | 
				
			||||||
    lockIcon.textContent = 'lock';
 | 
					 | 
				
			||||||
    // TODO: Write unlock-Function?
 | 
					 | 
				
			||||||
    lockIcon.dataset.chipAction = 'unlock';
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  deleteChipElement(attr) {
 | 
					  deleteChipElement(attr) {
 | 
				
			||||||
    let elementIndex = Array.from(this.elements.queryInputField.children).indexOf(attr);
 | 
					    let elementIndex = Array.from(this.elements.queryInputField.children).indexOf(attr);
 | 
				
			||||||
    switch (attr.dataset.type) {
 | 
					    switch (attr.dataset.type) {
 | 
				
			||||||
      case 'start-sentence':
 | 
					      case 'start-sentence':
 | 
				
			||||||
        this.deleteClosingTagHandler(elementIndex, 'end-sentence');
 | 
					        this.deleteClosingTagHandler(elementIndex, 'end-sentence');
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					      case 'start-empty-entity':
 | 
				
			||||||
      case 'start-entity':
 | 
					      case 'start-entity':
 | 
				
			||||||
        this.deleteClosingTagHandler(elementIndex, 'end-entity');
 | 
					        this.deleteClosingTagHandler(elementIndex, 'end-entity');
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@@ -180,9 +194,6 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.elements.queryInputField.removeChild(attr);
 | 
					    this.elements.queryInputField.removeChild(attr);
 | 
				
			||||||
    if (this.elements.queryInputField.children.length === 0) {
 | 
					 | 
				
			||||||
      this.addPlaceholder();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    this.updateChipList();
 | 
					    this.updateChipList();
 | 
				
			||||||
    this.queryPreviewBuilder();
 | 
					    this.queryPreviewBuilder();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -217,13 +228,17 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let targetChipClone = targetChipElement.cloneNode(true);
 | 
					        let targetChipClone = targetChipElement.cloneNode(true);
 | 
				
			||||||
        element.insertAdjacentElement('afterend', targetChipClone);
 | 
					        element.insertAdjacentElement('afterend', targetChipClone);
 | 
				
			||||||
 | 
					        //TODO: Change to two different functions for drag and drop
 | 
				
			||||||
        this.addDragDropListeners(targetChipClone, queryChipElement);
 | 
					        this.addDragDropListeners(targetChipClone, queryChipElement);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }, 0);
 | 
					    }, 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleDragEnd() {
 | 
					  handleDragEnd(event) {
 | 
				
			||||||
 | 
					    // is called when a query chip is dropped. It removes the dropzones and initializes the tooltips if the dragged element is the query element target.
 | 
				
			||||||
 | 
					    if (event.target.classList.contains('query-element-target')) {
 | 
				
			||||||
 | 
					      M.Tooltip.init(event.target);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    document.querySelectorAll('.drop-target').forEach(target => target.remove());
 | 
					    document.querySelectorAll('.drop-target').forEach(target => target.remove());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -292,8 +307,8 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
  tokenIncidenceModifierHandler(incidenceModifier, incidenceModifierPretty) {
 | 
					  tokenIncidenceModifierHandler(incidenceModifier, incidenceModifierPretty) {
 | 
				
			||||||
    // Adds a token incidence modifier to the query input field.
 | 
					    // Adds a token incidence modifier to the query input field.
 | 
				
			||||||
    let selectedChip = this.elements.queryInputField.querySelector('.chip.teal');
 | 
					    let selectedChip = this.elements.queryInputField.querySelector('.chip.teal');
 | 
				
			||||||
    let selectedChipIndex = Array.from(this.elements.queryInputField.children).indexOf(selectedChip);
 | 
					    let selectedChipIndex = Array.from(this.elements.queryChipElements).indexOf(selectedChip);
 | 
				
			||||||
    this.submitQueryChipElement('token-incidence-modifier', incidenceModifierPretty, incidenceModifier, selectedChipIndex+1);
 | 
					    this.submitQueryChipElement('token-incidence-modifier', incidenceModifierPretty, incidenceModifier, selectedChipIndex);
 | 
				
			||||||
    this.selectChipElement(selectedChip);
 | 
					    this.selectChipElement(selectedChip);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -315,26 +330,27 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
    this.tokenIncidenceModifierHandler(input, pretty_input);
 | 
					    this.tokenIncidenceModifierHandler(input, pretty_input);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  incidenceModifierEventListeners() {
 | 
					  expertModeQueryBuilderSwitchHandler() {
 | 
				
			||||||
    // Eventlisteners for the incidence modifiers. There are two different types of incidence modifiers: token and character incidence modifiers.
 | 
					    let queryBuilderDisplay = document.querySelector("#corpus-analysis-concordance-query-builder-display");
 | 
				
			||||||
    document.querySelectorAll('.incidence-modifier-selection').forEach(button => {
 | 
					    let expertModeDisplay = document.querySelector("#corpus-analysis-concordance-expert-mode-display");
 | 
				
			||||||
      let dropdownId = button.parentNode.parentNode.id;
 | 
					    let expertModeSwitch = document.querySelector("#corpus-analysis-concordance-expert-mode-switch");
 | 
				
			||||||
      if (dropdownId === 'corpus-analysis-concordance-token-incidence-modifiers-dropdown') {
 | 
					    let submitModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-switch-to-query-builder-submit-modal'));
 | 
				
			||||||
        button.addEventListener('click', () => this.tokenIncidenceModifierHandler(button.dataset.token, button.innerHTML));
 | 
					 | 
				
			||||||
      } else if (dropdownId === 'corpus-analysis-concordance-character-incidence-modifiers-dropdown') {
 | 
					 | 
				
			||||||
        button.addEventListener('click', () => this.extensions.tokenAttributeBuilderFunctions.characterIncidenceModifierHandler(button));
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  nAndMInputSubmitEventListeners() {
 | 
					    let confirmSwitchToQueryBuilderButton = document.querySelector('.switch-action[data-switch-action="confirm"]');
 | 
				
			||||||
    // Eventlisteners for the submit of n- and m-values of the incidence modifier modal for "exactly n" or "between n and m".
 | 
					    confirmSwitchToQueryBuilderButton.addEventListener("click", () => {
 | 
				
			||||||
    document.querySelectorAll('.n-m-submit-button').forEach(button => {
 | 
					      queryBuilderDisplay.classList.remove("hide");
 | 
				
			||||||
      let modalId = button.dataset.modalId;
 | 
					      expertModeDisplay.classList.add("hide");
 | 
				
			||||||
      if (modalId === 'corpus-analysis-concordance-exactly-n-token-modal' || modalId === 'corpus-analysis-concordance-between-nm-token-modal') {
 | 
					      this.switchToQueryBuilderParser();
 | 
				
			||||||
        button.addEventListener('click', () => this.tokenNMSubmitHandler(modalId));
 | 
					    });
 | 
				
			||||||
      } else if (modalId === 'corpus-analysis-concordance-exactly-n-character-modal' || modalId === 'corpus-analysis-concordance-between-nm-character-modal') {
 | 
					
 | 
				
			||||||
        button.addEventListener('click', () => this.extensions.tokenAttributeBuilderFunctions.characterNMSubmitHandler(modalId));
 | 
					    expertModeSwitch.addEventListener("change", () => {
 | 
				
			||||||
 | 
					      const isChecked = expertModeSwitch.checked;
 | 
				
			||||||
 | 
					      if (isChecked) {
 | 
				
			||||||
 | 
					        queryBuilderDisplay.classList.add("hide");
 | 
				
			||||||
 | 
					        expertModeDisplay.classList.remove("hide");
 | 
				
			||||||
 | 
					        this.switchToExpertModeParser();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        submitModal.open();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -361,9 +377,6 @@ nopaque.corpus_analysis.query_builder.QueryBuilder = class QueryBuilder {
 | 
				
			|||||||
        isEditable = false;
 | 
					        isEditable = false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.submitQueryChipElement(chipElement['type'], chipElement['pretty'], chipElement['query'], null, isClosingTag, isEditable);
 | 
					      this.submitQueryChipElement(chipElement['type'], chipElement['pretty'], chipElement['query'], null, isClosingTag, isEditable);
 | 
				
			||||||
      if (isClosingTag) {
 | 
					 | 
				
			||||||
        this.lockClosingChipElement(this.elements.queryChipElements[this.elements.queryChipElements.length-1]);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,4 +23,15 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </form>
 | 
					  </form>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div id="corpus-analysis-concordance-switch-to-query-builder-submit-modal" class="modal">
 | 
				
			||||||
 | 
					  <div class="modal-content">
 | 
				
			||||||
 | 
					    <h4>Switch to Query Builder</h4>
 | 
				
			||||||
 | 
					    <p>Switching back to the query builder can cause elements the query builder does not recognize to become lost. Continue?</p>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <div class="modal-footer">
 | 
				
			||||||
 | 
					    <a class="btn modal-close waves-effect waves-light">Cancel</a>
 | 
				
			||||||
 | 
					    <a class="btn modal-close red waves-effect waves-light switch-action" data-switch-action="confirm">Switch to Query Builder</a>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
{% endmacro %}
 | 
					{% endmacro %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,18 @@
 | 
				
			|||||||
{% macro card_content(id_prefix) %}
 | 
					{% macro card_content(id_prefix) %}
 | 
				
			||||||
<form id="corpus-analysis-concordance-query-builder-form">
 | 
					<form id="corpus-analysis-concordance-query-builder-form">
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col s9" id="corpus-analysis-concordance-query-builder-input-field-container">
 | 
					    <div class="col s8" id="corpus-analysis-concordance-query-builder-input-field-container">
 | 
				
			||||||
      <div id="corpus-analysis-concordance-query-builder-input-field">
 | 
					      <div id="corpus-analysis-concordance-query-builder-input-field">
 | 
				
			||||||
        <p id="corpus-analysis-concordance-query-builder-input-field-placeholder">Click on the buttons below to build your query.</p>
 | 
					        <a class="query-element-target btn-floating btn-small blue-grey lighten-4 waves-effect waves-light tooltipped" style="margin-bottom:10px; margin-right:5px;" draggable="true" data-position="bottom" data-tooltip="Add a token to your query">
 | 
				
			||||||
 | 
					          <i class="material-icons">add</i>
 | 
				
			||||||
 | 
					        </a>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="col s1 center-align">
 | 
				
			||||||
 | 
					      <a class="btn-floating btn waves-effect waves-light red" id="corpus-analysis-concordance-delete-query-button" style="margin-top:18px;">
 | 
				
			||||||
 | 
					        <i class="material-icons">delete</i>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <div class="input-field col s3">
 | 
					    <div class="input-field col s3">
 | 
				
			||||||
      <i class="material-icons prefix">arrow_forward</i>
 | 
					      <i class="material-icons prefix">arrow_forward</i>
 | 
				
			||||||
      <input class="validate corpus-analysis-action" id="corpus-analysis-concordance-form-subcorpus-name" name="subcorpus-name" type="text" required pattern="^[A-Z][a-z0-9\-]*" value="Last"></input>
 | 
					      <input class="validate corpus-analysis-action" id="corpus-analysis-concordance-form-subcorpus-name" name="subcorpus-name" type="text" required pattern="^[A-Z][a-z0-9\-]*" value="Last"></input>
 | 
				
			||||||
@@ -30,9 +37,9 @@
 | 
				
			|||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
    <div class="col s12">
 | 
					    <div class="col s12">
 | 
				
			||||||
      <p></p>
 | 
					      <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-small 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-small 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>
 | 
					      <a class="btn-small 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>
 | 
					  </div>
 | 
				
			||||||
  <div class="row">
 | 
					  <div class="row">
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user