Bug 1656057, implement form validation and disable form for an invalid event r=mstriemer,sfoster,fluent-reviewers,flod

Disables all elements in the form except for those within the invalid section.
Hides the form until printers become available.

Differential Revision: https://phabricator.services.mozilla.com/D86989
This commit is contained in:
Emma Malysz 2020-08-17 23:10:40 +00:00
parent 8103eaba24
commit f68ef97340
4 changed files with 39 additions and 8 deletions

View file

@ -262,11 +262,18 @@ input[type="text"] {
content: url("chrome://global/content/portrait.svg");
}
select:invalid,
input[type="number"]:invalid {
border: 1px solid #D70022;
box-shadow: 0 0 0 1px #D70022, 0 0 0 4px rgba(215, 0, 34, 0.3);
}
.error-message {
font-size: 12px;
color: #D70022;
margin-top: 4px;
}
#percent-scale {
appearance: textfield;
margin-inline-start: 4px;

View file

@ -54,6 +54,7 @@
autocomplete="off" disabled required>
</span>
</div>
<p id="error-invalid-scale" hidden="true" data-l10n-id="printui-error-invalid-scale" class="error-message"></p>
</div>
</template>

View file

@ -415,6 +415,7 @@ class DestinationPicker extends PrintUIControlMixin(HTMLSelectElement) {
if (e.type == "available-destinations") {
this.setOptions(e.detail);
this.required = true;
}
}
}
@ -509,33 +510,52 @@ customElements.define("copy-count-input", CopiesInput, {
extends: "input",
});
class PrintUIForm extends PrintUIControlMixin(HTMLElement) {
class PrintUIForm extends PrintUIControlMixin(HTMLFormElement) {
initialize() {
super.initialize();
this.addEventListener("submit", this);
this.addEventListener("click", this);
this.addEventListener("input", this);
}
handleEvent(e) {
if (e.target.id == "open-dialog-link") {
this.dispatchEvent(new Event("open-system-dialog", { bubbles: true }));
return;
}
if (e.type == "submit") {
e.preventDefault();
switch (e.submitter.name) {
case "print":
if (!this.checkValidity()) {
return;
}
this.dispatchEvent(new Event("print", { bubbles: true }));
break;
case "cancel":
this.dispatchEvent(new Event("cancel-print", { bubbles: true }));
break;
}
} else if (e.type == "input") {
let isValid = this.checkValidity();
let section = e.target.closest(".section-block");
for (let element of this.elements) {
// If we're valid, enable all inputs.
// Otherwise, disable the valid inputs other than the cancel button and the elements
// in the invalid section.
element.disabled =
element.hasAttribute("disallowed") ||
(!isValid &&
element.validity.valid &&
element.name != "cancel" &&
element.closest(".section-block") != section);
}
}
}
}
customElements.define("print-form", PrintUIForm);
customElements.define("print-form", PrintUIForm, { extends: "form" });
class ScaleInput extends PrintUIControlMixin(HTMLElement) {
get templateId() {
@ -546,10 +566,11 @@ class ScaleInput extends PrintUIControlMixin(HTMLElement) {
super.initialize();
this._percentScale = this.querySelector("#percent-scale");
this._percentScale.addEventListener("input", this);
this._shrinkToFitChoice = this.querySelector("#fit-choice");
this._scaleChoice = this.querySelector("#percent-scale-choice");
this._scaleError = this.querySelector("#error-invalid-scale");
this._percentScale.addEventListener("input", this);
this.addEventListener("input", this);
}
@ -558,6 +579,7 @@ class ScaleInput extends PrintUIControlMixin(HTMLElement) {
this._shrinkToFitChoice.checked = shrinkToFit;
this._scaleChoice.checked = !shrinkToFit;
this._percentScale.disabled = shrinkToFit;
this._percentScale.toggleAttribute("disallowed", shrinkToFit);
// If the user had an invalid input and switches back to "fit to page",
// we repopulate the scale field with the stored, valid scaling value.
@ -568,27 +590,24 @@ class ScaleInput extends PrintUIControlMixin(HTMLElement) {
}
handleEvent(e) {
e.stopPropagation();
if (e.target == this._shrinkToFitChoice || e.target == this._scaleChoice) {
this.dispatchSettingsChange({
shrinkToFit: this._shrinkToFitChoice.checked,
});
this._scaleError.hidden = true;
return;
}
window.clearTimeout(this.invalidTimeoutId);
if (this._percentScale.checkValidity() && e.type == "input") {
// TODO: set the customError element to hidden ( Bug 1656057 )
this.invalidTimeoutId = window.setTimeout(() => {
this.dispatchSettingsChange({
scaling: Number(this._percentScale.value / 100),
});
}, INVALID_INPUT_DELAY_MS);
}
// TODO: populate a customError element with erorMessage contents
this._scaleError.hidden = this._percentScale.validity.valid;
}
}
customElements.define("scale-input", ScaleInput);

View file

@ -54,3 +54,7 @@ printui-primary-button-save = Save
printui-cancel-button = Cancel
printui-loading = Preparing Preview
## Error messages shown when a user has an invalid input
printui-error-invalid-scale = Scale must be a number between 10 and 200.