diff --git a/asset/js/widget/BaseInput.js b/asset/js/widget/BaseInput.js index 2e0f7f4e..1b84b3a5 100644 --- a/asset/js/widget/BaseInput.js +++ b/asset/js/widget/BaseInput.js @@ -181,7 +181,22 @@ define(["../notjQuery", "Completer"], function ($, Completer) { // Reset the data input, otherwise the value remains and is sent continuously with subsequent requests this.dataInput.value = ''; - for (const termIndex of Object.keys(changedTerms)) { + if (changedTerms === 'bogus') { + return; + } + + let changedIndices = Object.keys(changedTerms); + if (! changedIndices.length) { + // Perform a partial reset. this.reset() empties the termContainer, which isn't desired here + this.usedTerms = []; + this.lastCompletedTerm = null; + + this.registerTerms(); + this.togglePlaceholder(); + this.termInput.value = ''; + } + + for (const termIndex of changedIndices) { let label = this.termContainer.querySelector(`[data-index="${ termIndex }"]`); if (! label) { continue; @@ -562,26 +577,34 @@ define(["../notjQuery", "Completer"], function ($, Completer) { return 'noAutoSubmit' in this.input.dataset; } - autoSubmit(input, changeType, changedTerms) { + autoSubmit(input, changeType, data) { if (this.shouldNotAutoSubmit()) { return; } - if (changeType === 'save') { + if (changeType === 'save' && 'terms' in data) { // Replace old term data with the new one, as required by the backend - for (const termIndex of Object.keys(changedTerms)) { - changedTerms[termIndex] = this.usedTerms[termIndex]; + for (const termIndex of Object.keys(data['terms'])) { + data['terms'][termIndex] = this.usedTerms[termIndex]; } } - if (Object.keys(changedTerms).length) { - this.dataInput.value = JSON.stringify({ - type: changeType, - terms: changedTerms - }); + if (changeType === 'remove' && ! Object.keys(data['terms']).length) { + return; + } - $(this.input.form).trigger('submit', { submittedBy: input }); + this.dataInput.value = JSON.stringify({ + type: changeType, + ...data + }); + + let eventData = { submittedBy: input }; + if (changeType === 'paste') { + // Ensure that what's pasted is also transmitted as value + eventData['terms'] = this.termsToQueryString(data['terms']) + this.separator + data['input']; } + + $(this.input.form).trigger('submit', eventData); } submitTerms(terms) { @@ -690,9 +713,9 @@ define(["../notjQuery", "Completer"], function ($, Completer) { this.checkValidity(input); if (termIndex >= 0) { - this.autoSubmit(input, 'save', { [termIndex]: this.saveTerm(input, false, true) }); + this.autoSubmit(input, 'save', { terms: { [termIndex]: this.saveTerm(input, false, true) } }); } else { - this.autoSubmit(input, 'exchange', this.exchangeTerm()); + this.autoSubmit(input, 'exchange', { terms: this.exchangeTerm() }); this.togglePlaceholder(); } } @@ -717,7 +740,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } if (! isTerm) { - this.autoSubmit(this.input, 'remove', this.clearSelectedTerms()); + this.autoSubmit(this.input, 'remove', { terms: this.clearSelectedTerms() }); this.togglePlaceholder(); } } @@ -773,7 +796,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } this.togglePlaceholder(); - this.autoSubmit(input, 'remove', removedTerms); + this.autoSubmit(input, 'remove', { terms: removedTerms }); break; case 'Delete': removedTerms = this.clearSelectedTerms(); @@ -794,7 +817,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } this.togglePlaceholder(); - this.autoSubmit(input, 'remove', removedTerms); + this.autoSubmit(input, 'remove', { terms: removedTerms }); break; case 'Enter': if (termIndex >= 0) { @@ -846,7 +869,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { break; case 'Delete': - this.autoSubmit(event.target, 'remove', this.clearSelectedTerms()); + this.autoSubmit(event.target, 'remove', { terms: this.clearSelectedTerms() }); this.togglePlaceholder(); break; } @@ -872,10 +895,11 @@ define(["../notjQuery", "Completer"], function ($, Completer) { if (this.readPartialTerm(input)) { let previousTerm = this.saveTerm(input); if (previousTerm !== false) { - this.autoSubmit(input, 'save', { [termIndex]: previousTerm }); + this.autoSubmit(input, 'save', { terms: { [termIndex]: previousTerm } }); } } else { - this.autoSubmit(input, 'remove', { [termIndex]: this.removeTerm(input.parentNode) }); + this.autoSubmit( + input, 'remove', { terms: { [termIndex]: this.removeTerm(input.parentNode) } }); } } }, 0); @@ -922,11 +946,14 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } onPaste(event) { - if (this.shouldNotAutoSubmit() || this.hasTerms() || this.input.value) { + if (this.shouldNotAutoSubmit() || this.input.value) { return; } - this.autoSubmit(this.input, 'paste', [event.clipboardData.getData('text/plain')]); + this.autoSubmit(this.input, 'paste', { + input: event.clipboardData.getData('text/plain'), + terms: this.usedTerms + }); event.preventDefault(); } @@ -952,7 +979,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { if (event.type === 'cut') { this.clearPartialTerm(this.input); - this.autoSubmit(this.input, 'remove', this.clearSelectedTerms()); + this.autoSubmit(this.input, 'remove', { terms: this.clearSelectedTerms() }); this.togglePlaceholder(); } } diff --git a/asset/js/widget/FilterInput.js b/asset/js/widget/FilterInput.js index 3fd37ede..d17c82b5 100644 --- a/asset/js/widget/FilterInput.js +++ b/asset/js/widget/FilterInput.js @@ -970,11 +970,16 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { return label; } - autoSubmit(input, changeType, changedTerms) { + autoSubmit(input, changeType, data) { if (this.shouldNotAutoSubmit()) { return; } + let changedTerms = []; + if ('terms' in data) { + changedTerms = data['terms']; + } + let changedIndices = Object.keys(changedTerms).sort((a, b) => a - b); if (! changedIndices.length) { return; @@ -987,7 +992,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { lastTermAt = changedIndices.pop(); if (changedTerms[lastTermAt].type === 'value') { if (! changedIndices.length) { - changedTerms = { + data['terms'] = { ...{ [lastTermAt - 2]: this.usedTerms[lastTermAt - 2], [lastTermAt - 1]: this.usedTerms[lastTermAt - 1] @@ -1030,7 +1035,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { if (valueAt === updateAt) { if (changedIndices.length === 1) { - changedTerms = { + data['terms'] = { ...{ [valueAt - 2]: this.usedTerms[valueAt - 2], [valueAt - 1]: this.usedTerms[valueAt - 1] @@ -1058,7 +1063,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { return; } - super.autoSubmit(input, changeType, changedTerms); + super.autoSubmit(input, changeType, data); } encodeTerm(termData) { @@ -1307,7 +1312,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { } } - this.autoSubmit(this.input, 'remove', this.removeRange(labels)); + this.autoSubmit(this.input, 'remove', { terms: this.removeRange(labels) }); this.togglePlaceholder(); } @@ -1421,7 +1426,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { if (newTerm !== null) { let label = this.insertTerm(newTerm, termIndex + 1); - this.autoSubmit(label.firstChild, 'insert', { [termIndex + 1]: newTerm }); + this.autoSubmit(label.firstChild, 'insert', { terms: { [termIndex + 1]: newTerm } }); this.complete(label.firstChild, { term: newTerm }); $(label.firstChild).focus({ scripted: true }); event.preventDefault(); @@ -1432,13 +1437,13 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { this.togglePlaceholder(); } else if (operators.exactMatch) { if (termType !== operators[0].type) { - this.autoSubmit(input, 'exchange', this.exchangeTerm()); + this.autoSubmit(input, 'exchange', { terms: this.exchangeTerm() }); } else { this.clearPartialTerm(input); } this.addTerm({ ...operators[0] }); - this.autoSubmit(input, 'add', { [this.usedTerms.length - 1]: operators[0] }); + this.autoSubmit(input, 'add', { terms: { [this.usedTerms.length - 1]: operators[0] } }); this.togglePlaceholder(); event.preventDefault(); } else if (termType === 'operator') { @@ -1465,7 +1470,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { && ! ['column', 'value'].includes(input.parentNode.dataset.type) && this.checkValidity(input) ) { - this.autoSubmit(input, 'save', { [termIndex]: this.saveTerm(input) }); + this.autoSubmit(input, 'save', { terms: { [termIndex]: this.saveTerm(input) } }); } } else if (this.termType === 'operator' || this.termType === 'logical_operator') { let value = this.readPartialTerm(input); diff --git a/asset/js/widget/TermInput.js b/asset/js/widget/TermInput.js index 87539e59..747835cd 100644 --- a/asset/js/widget/TermInput.js +++ b/asset/js/widget/TermInput.js @@ -131,7 +131,7 @@ define(["BaseInput"], function (BaseInput) { if (Object.keys(addedTerms).length) { this.togglePlaceholder(); event.preventDefault(); - this.autoSubmit(this.input, 'exchange', addedTerms); + this.autoSubmit(this.input, 'exchange', { terms: addedTerms }); } } @@ -169,7 +169,7 @@ define(["BaseInput"], function (BaseInput) { if (Object.keys(addedTerms).length) { this.togglePlaceholder(); event.preventDefault(); - this.autoSubmit(this.input, 'exchange', addedTerms); + this.autoSubmit(this.input, 'exchange', { terms: addedTerms }); this.ignoreSpaceUntil = null; return;