New condition section token builder

This commit is contained in:
Inga Kirschnick
2023-10-19 10:21:12 +02:00
parent d3cfd2cfaf
commit 8997d3ad67
6 changed files with 343 additions and 413 deletions

View File

@ -34,7 +34,6 @@ class ConcordanceQueryBuilder {
{
onOpenStart: () => {
this.tokenAttributeBuilderFunctions.preparePositionalAttrModal();
this.tokenAttributeBuilderFunctions.optionToggleHandler();
},
onCloseStart: () => {
this.tokenAttributeBuilderFunctions.resetPositionalAttrModal();

View File

@ -19,17 +19,13 @@ class ElementReferencesQueryBuilder {
// Token Attribute Builder Elements
this.positionalAttrModal = M.Modal.getInstance(document.querySelector('#corpus-analysis-concordance-positional-attr-modal'));
this.positionalAttrSelection = document.querySelector('#corpus-analysis-concordance-positional-attr-selection');
this.tokenBuilderContent = document.querySelector('#corpus-analysis-concordance-token-builder-content');
this.tokenQuery = document.querySelector('#corpus-analysis-concordance-token-query');
this.tokenQueryTemplate = document.querySelector('#corpus-analysis-concordance-token-query-template');
this.tokenSubmitButton = document.querySelector('#corpus-analysis-concordance-token-submit');
this.noValueMessage = document.querySelector('#corpus-analysis-concordance-no-value-message');
this.isTokenQueryInvalid = false;
this.wordInput = document.querySelector('#corpus-analysis-concordance-word-input');
this.lemmaInput = document.querySelector('#corpus-analysis-concordance-lemma-input');
this.englishPosSelection = document.querySelector('#corpus-analysis-concordance-english-pos-selection');
this.germanPosSelection = document.querySelector('#corpus-analysis-concordance-german-pos-selection');
this.simplePosSelection = document.querySelector('#corpus-analysis-concordance-simple-pos-selection');
this.ignoreCaseCheckbox = document.querySelector('#corpus-analysis-concordance-ignore-case-checkbox');
}
}

View File

@ -34,7 +34,9 @@ class GeneralFunctionsQueryBuilder {
resetMaterializeSelection(selectionElements, value = "default") {
selectionElements.forEach(selectionElement => {
selectionElement.querySelector(`option[value=${value}]`).selected = true;
if (selectionElement.querySelector(`option[value=${value}]`) !== null) {
selectionElement.querySelector(`option[value=${value}]`).selected = true;
}
let instance = M.FormSelect.getInstance(selectionElement);
instance.destroy();
M.FormSelect.init(selectionElement);

View File

@ -12,13 +12,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
button.addEventListener('click', () => {this.actionButtonInOptionSectionHandler(button.dataset.optionsAction);});
});
// 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();});
this.elements.englishPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
this.elements.germanPosSelection.addEventListener('change', () => {this.optionToggleHandler();});
this.elements.simplePosSelection.addEventListener('change', () => {this.optionToggleHandler();});
}
resetPositionalAttrModal() {
@ -28,32 +22,38 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
<option value="lemma" >lemma</option>
<option value="english-pos">english pos</option>
<option value="german-pos">german pos</option>
<option value="simple-pos">simple_pos</option>
<option value="simple_pos">simple_pos</option>
<option value="empty-token">empty token</option>
`;
this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
this.elements.tokenQuery.innerHTML = '';
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
this.toggleClass(['word', 'input-field-options'], 'hide', 'remove');
this.elements.tokenBuilderContent.innerHTML = '';
this.toggleClass(['input-field-options'], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
document.querySelector('#corpus-analysis-concordance-positional-attr-selection option[value="word"]').selected = true;
this.elements.wordInput.value = '';
this.elements.lemmaInput.value = '';
this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
this.resetMaterializeSelection([this.elements.positionalAttrSelection], "word");
this.elements.ignoreCaseCheckbox.checked = false;
this.elements.editingModusOn = false;
this.elements.editedQueryChipElementIndex = undefined;
}
preparePositionalAttrModal() {
let selection = this.elements.positionalAttrSelection.value;
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
if (selection !== 'empty-token') {
this.toggleClass([selection], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
let selectionTemplate = document.querySelector(`.token-builder-section[data-token-builder-section="${selection}"]`);
let selectionTemplateClone = selectionTemplate.content.cloneNode(true);
this.elements.tokenBuilderContent.innerHTML = '';
this.elements.tokenBuilderContent.appendChild(selectionTemplateClone);
if (this.elements.tokenBuilderContent.querySelector('select') !== null) {
let selectElement = this.elements.tokenBuilderContent.querySelector('select');
M.FormSelect.init(selectElement);
selectElement.addEventListener('change', () => {this.optionToggleHandler();});
} else {
this.elements.tokenBuilderContent.querySelector('input').addEventListener('input', () => {this.optionToggleHandler();});
}
}
this.optionToggleHandler();
if (selection === 'word' || selection === 'lemma') {
this.toggleClass(['input-field-options'], 'hide', 'remove');
} else if (selection === 'empty-token'){
@ -63,35 +63,22 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
}
}
tokenInputCheck() {
let input;
if (!document.querySelector('[data-toggle-area="word"]').classList.contains('hide')) {
input = this.elements.wordInput;
} else if (!document.querySelector('[data-toggle-area="lemma"]').classList.contains('hide')){
input = this.elements.lemmaInput;
} else if (!document.querySelector('[data-toggle-area="english-pos"]').classList.contains('hide')){
input = this.elements.englishPosSelection;
} else if (!document.querySelector('[data-toggle-area="german-pos"]').classList.contains('hide')){
input = this.elements.germanPosSelection;
} else if (!document.querySelector('[data-toggle-area="simple-pos"]').classList.contains('hide')){
input = this.elements.simplePosSelection;
}
return input;
tokenInputCheck(elem) {
return elem.querySelector('select') !== null ? elem.querySelector('select') : elem.querySelector('input');
}
optionToggleHandler() {
let input = this.tokenInputCheck();
let input = this.tokenInputCheck(this.elements.tokenBuilderContent);
if ((input.value === '' || input.value === 'default') && this.elements.editingModusOn === false) {
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
} else if (this.elements.positionalAttrSelection.querySelectorAll('option').length === 1) {
this.toggleClass(['and'], 'disabled', 'add');
} else {
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'remove');
}
}
disableTokenSubmit() {
this.elements.isTokenQueryInvalid = true;
this.elements.tokenSubmitButton.classList.add('red');
this.elements.noValueMessage.classList.remove('hide');
setTimeout(() => {
@ -102,93 +89,52 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
}, 3000);
}
tokenChipFactory(prettyQueryText, tokenText) {
tokenText = encodeURI(tokenText);
let builderElement;
let queryChipElement;
builderElement = document.createElement('div');
builderElement.innerHTML = `
<div class='chip col s2 l2' style='margin-top:20px;' data-tokentext='${tokenText}'>
${prettyQueryText}
<i class='material-icons close'>close</i>
</div>`;
queryChipElement = builderElement.firstElementChild;
this.elements.tokenQuery.appendChild(queryChipElement);
}
addTokenToQuery() {
let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
let tokenQueryPrettyText = '';
let tokenQueryCQLText = '';
this.elements.isTokenQueryInvalid = false;
this.elements.tokenQuery.childNodes.forEach(element => {
tokenQueryPrettyText += ' ' + element.firstChild.data + ' ';
tokenQueryCQLText += decodeURI(element.dataset.tokentext);
let input;
let kindOfToken = this.kindOfTokenCheck(this.elements.positionalAttrSelection.value);
// Takes all rows of the token query (if there is a query concatenation).
// Adds their contents to tokenQueryPrettyText and tokenQueryCQLText, which will later be expanded with the current input field.
let tokenQueryRows = this.elements.tokenQuery.querySelectorAll('.row');
tokenQueryRows.forEach(row => {
let ignoreCaseCheckbox = row.querySelector('input[type="checkbox"]');
let c = ignoreCaseCheckbox !== null && ignoreCaseCheckbox.checked ? ' %c' : '';
let tokenQueryRowInput = this.tokenInputCheck(row.querySelector('.token-query-template-content'));
let tokenQueryKindOfToken = this.kindOfTokenCheck(tokenQueryRowInput.closest('.input-field').dataset.kindOfToken);
let tokenConditionPrettyText = row.querySelector('[data-condition-pretty-text]').dataset.conditionPrettyText;
let tokenConditionCQLText = row.querySelector('[data-condition-cql-text]').dataset.conditionCqlText;
tokenQueryPrettyText += `${tokenQueryKindOfToken}=${tokenQueryRowInput.value}${c} ${tokenConditionPrettyText} `;
tokenQueryCQLText += `${tokenQueryKindOfToken}="${tokenQueryRowInput.value}"${c} ${tokenConditionCQLText}`;
});
switch (this.elements.positionalAttrSelection.value) {
case 'word':
if (this.elements.wordInput.value === '') {
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `word=${this.elements.wordInput.value}${c}`;
tokenQueryCQLText += `word="${this.elements.wordInput.value}"${c}`;
this.elements.wordInput.value = '';
}
break;
case 'lemma':
if (this.elements.lemmaInput.value === '') {
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `lemma=${this.elements.lemmaInput.value}${c}`;
tokenQueryCQLText += `lemma="${this.elements.lemmaInput.value}"${c}`;
this.elements.lemmaInput.value = '';
}
break;
case 'english-pos':
if (this.elements.englishPosSelection.value === 'default') {
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `pos=${this.elements.englishPosSelection.value}`;
tokenQueryCQLText += `pos="${this.elements.englishPosSelection.value}"`;
this.elements.englishPosSelection.value = '';
}
break;
case 'german-pos':
if (this.elements.germanPosSelection.value === 'default') {
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `pos=${this.elements.germanPosSelection.value}`;
tokenQueryCQLText += `pos="${this.elements.germanPosSelection.value}"`;
this.elements.germanPosSelection.value = '';
}
break;
case 'simple-pos':
if (this.elements.simplePosSelection.value === 'default') {
this.disableTokenSubmit();
} else {
tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
tokenQueryCQLText += `simple_pos="${this.elements.simplePosSelection.value}"`;
this.elements.simplePosSelection.value = '';
}
break;
case 'empty-token':
tokenQueryPrettyText += 'empty token';
default:
break;
if (kindOfToken === 'empty-token') {
tokenQueryPrettyText += 'empty token';
} else {
let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
input = this.tokenInputCheck(this.elements.tokenBuilderContent);
tokenQueryPrettyText += `${kindOfToken}=${input.value}${c}`;
tokenQueryCQLText += `${kindOfToken}="${input.value}"${c}`;
}
// isTokenQueryInvalid looks if a valid value is passed. If the input fields/dropdowns are empty (isTokenQueryInvalid === true), no token is added.
if (this.elements.isTokenQueryInvalid === false) {
tokenQueryCQLText = '[' + tokenQueryCQLText + ']';
if ((input.value === '' || input.value === 'default') && this.elements.positionalAttrSelection.value !== 'empty-token') {
this.disableTokenSubmit();
} else {
tokenQueryCQLText = `[${tokenQueryCQLText}]`;
this.submitQueryChipElement('token', tokenQueryPrettyText, tokenQueryCQLText, null, false, true);
this.elements.positionalAttrModal.close();
}
}
kindOfTokenCheck(kindOfToken) {
return kindOfToken === 'english-pos' || kindOfToken === 'german-pos' ? 'pos' : kindOfToken;
}
actionButtonInOptionSectionHandler(elem) {
let input = this.tokenInputCheck();
let input = this.tokenInputCheck(this.elements.tokenBuilderContent);
switch (elem) {
case 'option-group':
input.value += '(option1|option2)';
@ -201,10 +147,10 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
input.value += '.';
break;
case 'and':
this.conditionHandler('and', " & ");
this.conditionHandler('and');
break;
case 'or':
this.conditionHandler('or', " | ");
this.conditionHandler('or');
break;
default:
break;
@ -213,32 +159,8 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
}
characterIncidenceModifierHandler(elem) {
// For word and lemma, the incidence modifiers are inserted in the input field. For the others, one or two chips are created which contain the respective value of the token and the incidence modifier.
switch (this.elements.positionalAttrSelection.value) {
case 'empty-token':
this.tokenChipFactory(elem.innerText, elem.dataset.token);
break;
case 'english-pos':
this.tokenChipFactory(`pos=${this.elements.englishPosSelection.value}`, `pos="${this.elements.englishPosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token);
break;
case 'german-pos':
this.tokenChipFactory(`pos=${this.elements.germanPosSelection.value}`, `pos="${this.elements.germanPosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token);
break;
case 'simple-pos':
this.tokenChipFactory(`simple_pos=${this.elements.simplePosSelection.value}`, `simple_pos="${this.elements.simplePosSelection.value}"`);
this.tokenChipFactory(elem.innerText, elem.dataset.token);
break;
default:
let input = this.tokenInputCheck();
input.value += elem.dataset.token;
break;
}
if (this.elements.positionalAttrSelection.value !== "word" && this.elements.positionalAttrSelection.value !== "lemma") {
this.toggleClass([this.elements.positionalAttrSelection.value], "hide", "add");
}
let input = this.tokenInputCheck(this.elements.tokenBuilderContent);
input.value += elem.dataset.token;
}
characterNMSubmitHandler(modalId) {
@ -250,89 +172,96 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
let instance = M.Modal.getInstance(modal);
instance.close();
switch (this.elements.positionalAttrSelection.value) {
case 'word':
this.elements.wordInput.value += '{' + input + '}';
break;
case 'lemma':
this.elements.lemmaInput.value += '{' + input + '}';
break;
default:
break;
}
let tokenInput = this.tokenInputCheck(this.elements.tokenBuilderContent);
tokenInput.value += '{' + input + '}';
}
conditionHandler(conditionText, conditionQueryContent) {
let tokenQueryPrettyText;
let tokenQueryCQLText;
let c = this.elements.ignoreCaseCheckbox.checked ? ' %c' : '';
switch (this.elements.positionalAttrSelection.value) {
case 'word':
tokenQueryPrettyText = `word=${this.elements.wordInput.value}${c}`;
tokenQueryCQLText = `word="${this.elements.wordInput.value}"${c}`;
this.elements.wordInput.value = '';
break;
case 'lemma':
tokenQueryPrettyText = `lemma=${this.elements.lemmaInput.value}${c}`;
tokenQueryCQLText = `lemma="${this.elements.lemmaInput.value}"${c}`;
this.elements.lemmaInput.value = '';
break;
case 'english-pos':
tokenQueryPrettyText = `pos=${this.elements.englishPosSelection.value}`;
tokenQueryCQLText = `pos="${this.elements.englishPosSelection.value}"`;
this.elements.englishPosSelection.value = '';
break;
case 'german-pos':
tokenQueryPrettyText = `pos=${this.elements.germanPosSelection.value}`;
tokenQueryCQLText = `pos="${this.elements.germanPosSelection.value}"`;
this.elements.germanPosSelection.value = '';
break;
case 'simple-pos':
tokenQueryPrettyText = `simple_pos=${this.elements.simplePosSelection.value}`;
tokenQueryCQLText = `simple_pos="${this.elements.simplePosSelection.value}"`;
this.elements.simplePosSelection.value = '';
break;
default:
break;
}
conditionHandler(conditionText) {
let tokenQueryTemplateClone = this.elements.tokenQueryTemplate.content.cloneNode(true);
tokenQueryTemplateClone.querySelector('.token-query-template-content').appendChild(this.elements.tokenBuilderContent.firstElementChild);
let notSelectedButton = tokenQueryTemplateClone.querySelector(`[data-condition-pretty-text]:not([data-condition-pretty-text="${conditionText}"])`);
let deleteButton = tokenQueryTemplateClone.querySelector(`[data-token-query-content-action="delete"]`);
deleteButton.addEventListener('click', (event) => {
this.deleteTokenQueryRow(event.target);
});
notSelectedButton.parentNode.removeChild(notSelectedButton);
this.elements.tokenQuery.appendChild(tokenQueryTemplateClone);
// Deleting the options which do not make sense in the context of the condition like "word" AND "word". Also sets selection default.
let selectionDefault = "word";
let optionDeleteList = ['empty-token'];
if (conditionText === 'and') {
if (this.elements.positionalAttrSelection.value === 'word' || this.elements.positionalAttrSelection.value === 'lemma') {
selectionDefault = "english-pos";
optionDeleteList.push('word', 'lemma');
} else if (this.elements.positionalAttrSelection.value === 'english-pos' || this.elements.positionalAttrSelection.value === 'german-pos') {
optionDeleteList.push('english-pos', 'german-pos');
} else {
optionDeleteList.push('simple-pos');
switch (this.elements.positionalAttrSelection.value) {
case 'english-pos' || 'german-pos':
optionDeleteList.push('english-pos', 'german-pos');
break;
default:
optionDeleteList.push(this.elements.positionalAttrSelection.value);
break;
}
} else {
let originalSelectionList =
`
<option value="word" selected>word</option>
<option value="lemma" >lemma</option>
<option value="english-pos">english pos</option>
<option value="german-pos">german pos</option>
<option value="simple_pos">simple_pos</option>
`;
this.elements.positionalAttrSelection.innerHTML = originalSelectionList;
M.FormSelect.init(this.elements.positionalAttrSelection);
}
this.resetMaterializeSelection([this.elements.englishPosSelection, this.elements.germanPosSelection, this.elements.simplePosSelection]);
this.tokenChipFactory(tokenQueryPrettyText, tokenQueryCQLText);
this.tokenChipFactory(conditionText, conditionQueryContent);
let lastTokenQueryRow = this.elements.tokenQuery.lastElementChild;
if(lastTokenQueryRow.querySelector('[data-kind-of-token="word"]') || lastTokenQueryRow.querySelector('[data-kind-of-token="lemma"]')) {
this.appendIgnoreCaseCheckbox(lastTokenQueryRow.querySelector('.token-query-template-content'), this.elements.ignoreCaseCheckbox.checked);
}
this.elements.ignoreCaseCheckbox.checked = false;
this.setTokenSelection(selectionDefault, optionDeleteList);
}
deleteTokenQueryRow(deleteButton) {
let deletedRow = deleteButton.closest('.row');
let condition = deletedRow.querySelector('[data-condition-pretty-text]').dataset.conditionPrettyText;
if (condition === 'and') {
let kindOfToken = deletedRow.querySelector('[data-kind-of-token]').dataset.kindOfToken;
switch (kindOfToken) {
case 'english-pos' || 'german-pos':
this.createOptionElementForPosAttrSelection('english-pos');
this.createOptionElementForPosAttrSelection('german-pos');
break;
default:
this.createOptionElementForPosAttrSelection(kindOfToken);
break;
}
M.FormSelect.init(this.elements.positionalAttrSelection);
}
deletedRow.remove();
}
createOptionElementForPosAttrSelection(kindOfToken) {
let option = document.createElement('option');
option.value = kindOfToken;
option.text = kindOfToken;
this.elements.positionalAttrSelection.appendChild(option);
}
appendIgnoreCaseCheckbox(parentElement, checked = false) {
let ignoreCaseCheckboxClone = document.querySelector('#ignore-case-checkbox-template').content.cloneNode(true);
parentElement.appendChild(ignoreCaseCheckboxClone);
M.Tooltip.init(parentElement.querySelectorAll('.tooltipped'));
if (checked) {
parentElement.querySelector('input[type="checkbox"]').checked = true;
}
}
setTokenSelection(selection, optionDeleteList) {
optionDeleteList.forEach(option => {
this.elements.positionalAttrSelection.querySelector(`option[value=${option}]`).remove();
if (this.elements.positionalAttrSelection.querySelector(`option[value=${option}]`) !== null) {
this.elements.positionalAttrSelection.querySelector(`option[value=${option}]`).remove();
}
});
this.resetMaterializeSelection([this.elements.positionalAttrSelection], selection);
this.toggleClass(['word', 'lemma', 'english-pos', 'german-pos', 'simple-pos'], 'hide', 'add');
this.toggleClass([selection], 'hide', 'remove');
this.toggleClass(['incidence-modifiers', 'or', 'and'], 'disabled', 'add');
if (selection === "word" || selection === "lemma") {
this.toggleClass(['input-field-options'], 'hide', 'remove');
} else {
this.toggleClass(['input-field-options'], 'hide', 'add');
}
this.preparePositionalAttrModal();
}
}