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 type { SlInput } from "@shoelace-style/shoelace";
import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js"; import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
import { html } from "lit"; import { html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, query } from "lit/decorators.js";
import slugify from "slugify"; import slugify from "slugify";
import { TailwindElement } from "@/classes/TailwindElement"; import { TailwindElement } from "@/classes/TailwindElement";
@ -43,6 +43,9 @@ export class OrgForm extends TailwindElement {
@property({ type: String }) @property({ type: String })
slug = ""; slug = "";
@query("#orgForm")
private readonly form?: HTMLFormElement | null;
readonly _api = new APIController(this); readonly _api = new APIController(this);
readonly _notify = new NotifyController(this); readonly _notify = new NotifyController(this);
@ -151,21 +154,34 @@ export class OrgForm extends TailwindElement {
} catch (e) { } catch (e) {
console.debug(e); console.debug(e);
if (isApiError(e)) { if (isApiError(e)) {
let error: Error | null = null;
let fieldName = "";
if (e.details === "duplicate_org_name") { if (e.details === "duplicate_org_name") {
throw new Error( fieldName = "orgName";
msg("This org name is already taken, try another one."), error = new Error(
msg(str`The org name "${name}" is already taken, try another one.`),
); );
} else if (e.details === "duplicate_org_slug") { } else if (e.details === "duplicate_org_slug") {
throw new Error( fieldName = "orgSlug";
msg("This org URL is already taken, try another one."), error = new Error(
msg(str`The org URL "${slug}" is already taken, try another one.`),
); );
} else if (e.details === "invalid_slug") { } else if (e.details === "invalid_slug") {
throw new Error( fieldName = "orgSlug";
error = new Error(
msg( 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({ 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) { private async checkFormValidity(formEl: HTMLFormElement) {
await this.updateComplete; await this.updateComplete;
return !formEl.querySelector("[data-invalid]"); 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); 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 { [data-user-invalid]:not([disabled])::part(form-control-label),
/* Required asterisk color */ /* Required asterisk color */
color: var(--sl-color-danger-500); [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])::part(form-control-help-text),
[data-user-invalid]:not([disabled]) .form-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 */ /* TODO tailwind sets border-width: 0, see if this can be fixed in tw */