show correct field when validating

This commit is contained in:
sua yoo 2024-07-15 11:02:10 -07:00
parent bdd279c4f8
commit 6f031f1059
No known key found for this signature in database
GPG Key ID: 5AD1B4C02D4F0567
2 changed files with 42 additions and 11 deletions

View File

@ -3,7 +3,7 @@ import { Task, TaskStatus } from "@lit/task";
import type { SlInput } from "@shoelace-style/shoelace";
import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
import { html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { customElement, property, query } from "lit/decorators.js";
import slugify from "slugify";
import { TailwindElement } from "@/classes/TailwindElement";
@ -43,6 +43,9 @@ export class OrgForm extends TailwindElement {
@property({ type: String })
slug = "";
@query("#orgForm")
private readonly form?: HTMLFormElement | null;
readonly _api = new APIController(this);
readonly _notify = new NotifyController(this);
@ -151,21 +154,34 @@ export class OrgForm extends TailwindElement {
} catch (e) {
console.debug(e);
if (isApiError(e)) {
let error: Error | null = null;
let fieldName = "";
if (e.details === "duplicate_org_name") {
throw new Error(
msg("This org name is already taken, try another one."),
fieldName = "orgName";
error = new Error(
msg(str`The org name "${name}" is already taken, try another one.`),
);
} else if (e.details === "duplicate_org_slug") {
throw new Error(
msg("This org URL is already taken, try another one."),
fieldName = "orgSlug";
error = new Error(
msg(str`The org URL "${slug}" is already taken, try another one.`),
);
} else if (e.details === "invalid_slug") {
throw new Error(
fieldName = "orgSlug";
error = new Error(
msg(
"This org URL is invalid. Please use alphanumeric characters and dashes (-) only.",
str`The org URL "${slug}" is not a valid URL. Please use alphanumeric characters and dashes (-) only`,
),
);
}
if (error) {
if (fieldName) {
this.highlightErrorField(fieldName, error);
}
throw error;
}
}
this._notify.toast({
@ -178,6 +194,20 @@ export class OrgForm extends TailwindElement {
}
}
private highlightErrorField(fieldName: string, error: Error) {
const input = this.form?.querySelector<SlInput>(`[name="${fieldName}"]`);
if (input) {
input.setCustomValidity(error.message);
const onOneInput = () => {
input.setCustomValidity("");
input.removeEventListener("sl-input", onOneInput);
};
input.addEventListener("sl-input", onOneInput);
}
}
private async checkFormValidity(formEl: HTMLFormElement) {
await this.updateComplete;
return !formEl.querySelector("[data-invalid]");

View File

@ -166,14 +166,15 @@
box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-color-danger-100);
}
[data-user-invalid]:not([disabled])::part(form-control-label):after {
/* Required asterisk color */
color: var(--sl-color-danger-500);
[data-user-invalid]:not([disabled])::part(form-control-label),
/* Required asterisk color */
[data-user-invalid]:not([disabled])::part(form-control-label)::after {
color: var(--sl-color-danger-700);
}
[data-user-invalid]:not([disabled])::part(form-control-help-text),
[data-user-invalid]:not([disabled]) .form-help-text {
color: var(--sl-color-danger-500);
color: var(--sl-color-danger-700);
}
/* TODO tailwind sets border-width: 0, see if this can be fixed in tw */