diff --git a/asset/js/widget/BaseInput.js b/asset/js/widget/BaseInput.js index 82d42e28..cd7d6a47 100644 --- a/asset/js/widget/BaseInput.js +++ b/asset/js/widget/BaseInput.js @@ -164,6 +164,7 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } this.registerTerm(this.decodeTerm(termData), label.dataset.index); + this.validate(label.firstChild); }); } @@ -317,7 +318,41 @@ define(["../notjQuery", "Completer"], function ($, Completer) { return this.termsToQueryString(this.usedTerms); } + checkValidity(input) { + if (input.pattern && ! input.checkValidity()) { + if (! input.value.match(input.pattern)) { + if (input.dataset.invalidMsg) { + input.setCustomValidity(input.dataset.invalidMsg); + } + + return false; + } + + input.setCustomValidity(''); + } + + return input.checkValidity(); + } + + reportValidity(element) { + setTimeout(() => element.reportValidity(), 0); + } + + validate(element) { + if (! this.checkValidity(element)) { + this.reportValidity(element); + + return false; + } + + return true; + } + saveTerm(input, updateDOM = true, force = false) { + if (! this.checkValidity(input)) { + return false; + } + let termIndex = input.parentNode.dataset.index; let termData = this.readFullTerm(input, termIndex); @@ -348,6 +383,18 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } else { label.title = ''; } + + if (termData.pattern) { + input.pattern = termData.pattern; + delete termData.pattern; + + if (termData.invalidMsg) { + input.dataset.invalidMsg = termData.invalidMsg; + delete termData.invalidMsg; + } + + this.validate(input); + } } termsToQueryString(terms) { @@ -640,6 +687,8 @@ define(["../notjQuery", "Completer"], function ($, Completer) { this.lastCompletedTerm = termData; this.writePartialTerm(termData.label, input); + this.checkValidity(input); + if (termIndex >= 0) { this.autoSubmit(input, 'save', { [termIndex]: this.saveTerm(input, false, true) }); } else { @@ -660,6 +709,10 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } if (! this.hasSyntaxError(input)) { + if (isTerm && ! this.validate(input)) { + return; + } + this.complete(input, { term: termData }); } @@ -830,6 +883,12 @@ define(["../notjQuery", "Completer"], function ($, Completer) { } onTermFocus(event) { + let input = event.target; + + if (input.parentNode.dataset.index >= 0) { + this.validate(input); + } + if (event.detail.scripted) { // Only request suggestions if the user manually focuses the term return; @@ -837,7 +896,6 @@ define(["../notjQuery", "Completer"], function ($, Completer) { this.deselectTerms(); - let input = event.target; if (! this.hasSyntaxError(input) && ( this.completer === null || ! this.completer.isBeingCompleted(input, false) )) { diff --git a/asset/js/widget/FilterInput.js b/asset/js/widget/FilterInput.js index 3d19a708..3fd37ede 100644 --- a/asset/js/widget/FilterInput.js +++ b/asset/js/widget/FilterInput.js @@ -105,24 +105,6 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { return termIndex; } - updateTermData(termData, input) { - super.updateTermData(termData, input); - - if (termData.pattern) { - input.pattern = termData.pattern; - delete termData.pattern; - - if (termData.invalidMsg) { - input.dataset.invalidMsg = termData.invalidMsg; - delete termData.invalidMsg; - } - - if (! this.checkValidity(input)) { - this.reportValidity(input); - } - } - } - readFullTerm(input, termIndex = null) { let termData = super.readFullTerm(input, termIndex); if (termData === false) { @@ -355,14 +337,6 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { lastTerm.classList.add('last-term'); } - saveTerm(input, updateDOM = true, force = false) { - if (! this.checkValidity(input)) { - return false; - } - - return super.saveTerm(input, updateDOM, force); - } - termsToQueryString(terms) { if (! this.input.form.checkValidity()) { let filtered = []; @@ -386,8 +360,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { let termIndex = Number(label.dataset.index); if (termIndex < this.usedTerms.length - 1) { // It's not the last term - if (! this.checkValidity(label.firstChild, label.dataset.type, termIndex)) { - this.reportValidity(label.firstChild); + if (! this.validate(label.firstChild)) { return false; } } @@ -838,21 +811,13 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { type = input.parentNode.dataset.type; } - if (input.pattern && ! input.checkValidity()) { - if (! input.value.match(input.pattern)) { - if (input.dataset.invalidMsg) { - input.setCustomValidity(input.dataset.invalidMsg); - } - - return false; - } - - input.setCustomValidity(''); + if (! ['operator', 'logical_operator'].includes(type) && ! super.checkValidity(input)) { + return false; } if (! type || type === 'value') { // type is undefined for the main input, values have no special validity rules - return input.checkValidity(); + return true; } if (termIndex === null && input.parentNode.dataset.index >= 0) { @@ -949,10 +914,6 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { return input.checkValidity(); } - reportValidity(element) { - setTimeout(() => element.reportValidity(), 0); - } - renderSuggestions(suggestions) { let itemTemplate = $.render('
'); @@ -1247,22 +1208,19 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { onTermFocus(event) { let input = event.target; + let isTerm = input.parentNode.dataset.index >= 0; let termType = input.parentNode.dataset.type || this.termType; - if (input.parentNode.dataset.index >= 0) { - if ( - ! this.checkValidity(input, termType) - && termType !== 'operator' - && termType !== 'logical_operator' - ) { - this.reportValidity(input); - } - + if (isTerm) { this.highlightTerm(input.parentNode); } let value = this.readPartialTerm(input); if (! value && (termType === 'column' || termType === 'value')) { + if (isTerm) { + this.validate(input); + } + // No automatic suggestions without input return; } @@ -1356,10 +1314,7 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { onCompletion(event) { super.onCompletion(event); - let input = event.target; - this.checkValidity(input); - - if (input.parentNode.dataset.index >= 0) { + if (event.target.parentNode.dataset.index >= 0) { return; } @@ -1505,12 +1460,11 @@ define(["../notjQuery", "BaseInput"], function ($, BaseInput) { // pass } else if (termIndex >= 0) { let value = this.readPartialTerm(input); - if (! this.checkValidity(input)) { - this.reportValidity(input); - // Let inputs also grow upon invalid input - this.updateTermData({ label: value }, input); - return; - } else if (value && ! ['column', 'value'].includes(input.parentNode.dataset.type)) { + if ( + value + && ! ['column', 'value'].includes(input.parentNode.dataset.type) + && this.checkValidity(input) + ) { this.autoSubmit(input, 'save', { [termIndex]: this.saveTerm(input) }); } } else if (this.termType === 'operator' || this.termType === 'logical_operator') {