Skip to content

Commit

Permalink
setup form submit
Browse files Browse the repository at this point in the history
  • Loading branch information
SalihuDickson committed Jan 27, 2025
1 parent 8033aa1 commit da7b208
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 118 deletions.
6 changes: 3 additions & 3 deletions packages/ecc-utils-design/demo/form/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
@ecc-utils-submit=${async (e) => {
try {
console.log("form - submitted", e.detail);
document.querySelector("ecc-utils-design-form").loading();
document.querySelector("ecc-d-form").loading();
await fetch("https://jsonplaceholder.typicode.com/posts");
document
.querySelector("ecc-utils-design-form")
.querySelector("ecc-d-form")
.success({ message: "Data fetched successfully" });
} catch (error) {
document
.querySelector("ecc-utils-design-form")
.querySelector("ecc-d-form")
.error({ message: "Error fetching data" });
}
}}
Expand Down
6 changes: 3 additions & 3 deletions packages/ecc-utils-design/src/components/form/form.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const styles = css`
.group-content {
padding-top: var(--ecc-spacing-medium);
}
.group-item {
.group {
min-height: var(--ecc-input-height-3xlarge);
}
/* Array Styles */
Expand All @@ -78,12 +78,12 @@ const styles = css`
font-weight: var(--ecc-input-font-weight);
letter-spacing: var(--ecc-input-letter-spacing);
}
.array-item {
.array {
border-style: solid;
border-width: 0px 0px var(--ecc-input-border-width) 0px;
border-color: var(--ecc-input-border-color-disabled);
}
.array-item {
.array {
display: flex;
flex-direction: row;
align-items: center;
Expand Down
61 changes: 22 additions & 39 deletions packages/ecc-utils-design/src/components/form/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default class EccUtilsDesignForm extends LitElement {

@state() private form: object = {};
@state() private formState: "idle" | "loading" | "error" | "success" = "idle";
@state() private canSubmit = false;
@state() private canSubmit = true;
@state() private submitDisabledByUser = false;
@state() private errorMessage = "Something went wrong";
@state() private successMessage = "Form submitted successfully";
Expand Down Expand Up @@ -178,6 +178,7 @@ export default class EccUtilsDesignForm extends LitElement {

private handleSubmit(e: Event) {
e.preventDefault();

const form = this.shadowRoot?.querySelector("form");
const isValid = form?.reportValidity();
if (!isValid) {
Expand All @@ -198,8 +199,26 @@ export default class EccUtilsDesignForm extends LitElement {
}

render() {
// const toggleButtonState = () => {
// if (this.requiredButEmpty.length > 0) {
// this.canSubmit = false;
// } else {
// this.canSubmit = true;
// }

// return "";
// };

if (this.formState === "success") {
return html` ${this.renderSuccessTemplate()} `;
}

if (this.formState === "error") {
return html` ${this.renderErrorTemplate()} `;
}

return html`
<div ecc-form>
<form ecc-form @submit=${this.handleSubmit}>
${repeat(
this.items,
() => _.uniqueId("ecc-form-item-"),
Expand All @@ -218,43 +237,7 @@ export default class EccUtilsDesignForm extends LitElement {
>
Submit
</sl-button>
</div>
</form>
`;
// if (!this.fields || this.fields.length === 0) {
// throw new Error("Fields is required & should not be empty array");
// }
// if (this.formState === "success") {
// return html` ${this.renderSuccessTemplate()} `;
// }

// const toggleButtonState = () => {
// if (this.requiredButEmpty.length > 0) {
// this.canSubmit = false;
// } else {
// this.canSubmit = true;
// }

// return "";
// };

// return html`
// <form data-testid="form" @submit=${this.handleSubmit}>
// ${this.fields.map((field) => this.renderTemplate(field, "data"))}
// ${this.renderErrorTemplate()} ${toggleButtonState()}

// <sl-button
// type="submit"
// data-testid="form-submit"
// variant="primary"
// class="submit-button"
// ?loading=${this.formState === "loading"}
// ?disabled=${this.submitDisabledByUser ||
// !this.canSubmit ||
// this.formState === "loading"}
// >
// Submit
// </sl-button>
// </form>
// `;
}
}
15 changes: 5 additions & 10 deletions packages/ecc-utils-design/src/components/form/formGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ import { LitElement, html, TemplateResult } from "lit";
import { property, state } from "lit/decorators.js";
import { repeat } from "lit/directives/repeat.js";
import * as _ from "lodash-es";
import { noKeyWarning, renderInTooltip, toCamelCase } from "./utils.js";
import { noKeyWarning, renderInTooltip } from "./utils.js";
import "@shoelace-style/shoelace/dist/components/details/details.js";
import "@shoelace-style/shoelace/dist/components/button/button.js";
import formStyles from "./form.styles.js";

export default class EccUtilsDesignFormGroup extends LitElement {
static styles = [
// primitiveStylesheet,
// sholelaceStyles,
// hostStyles,
formStyles,
];
static styles = [formStyles];

// TODO
// build required but empty functionality
Expand All @@ -23,14 +18,14 @@ export default class EccUtilsDesignFormGroup extends LitElement {
@property({ type: Boolean, reflect: true }) required = "";
@property({ type: String, reflect: true }) tooltip = "";

// array item options
// array options
@property({ type: Number, reflect: true })
instances = 0;

@property({ type: Number, attribute: "max" }) maxInstances = "";
@property({ type: Number, attribute: "min" }) minInstances = "";

// group item options
// group options
@property({ type: Boolean, reflect: true }) collapsible = false;

@state() private arrayInstances: Array<{
Expand Down Expand Up @@ -64,7 +59,7 @@ export default class EccUtilsDesignFormGroup extends LitElement {
super.connectedCallback();
if (!this.key) {
noKeyWarning("ecc-d-form-group", this.label);
this.key = toCamelCase(this.label);
this.key = _.camelCase(this.label);
}

this.findNearestFormGroup();
Expand Down
33 changes: 23 additions & 10 deletions packages/ecc-utils-design/src/components/form/formInput.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as _ from "lodash-es";
import { html, LitElement, TemplateResult } from "lit";
import { property, state } from "lit/decorators.js";
import { property, state, query } from "lit/decorators.js";
import { repeat } from "lit/directives/repeat.js";
import { renderInTooltip, toCamelCase, noKeyWarning } from "./utils.js";
import { renderInTooltip, noKeyWarning } from "./utils.js";
import "@shoelace-style/shoelace/dist/components/alert/alert.js";
import "@shoelace-style/shoelace/dist/components/icon/icon.js";
import "@shoelace-style/shoelace/dist/components/input/input.js";
Expand Down Expand Up @@ -44,23 +45,24 @@ export default class EccUtilsDesignFormInput extends LitElement {
@property({ type: String, reflect: true }) default = "";
@property({ type: Boolean, reflect: true }) checked = false;
@property({ type: Boolean, reflect: true }) multiple = false;
@property({ type: String, reflect: true }) value: any;
@property({ type: String, reflect: true }) accept = "*";
@property({ type: String, attribute: "tus-endpoint" }) tusEndpoint = "";
@property({ type: String, attribute: "endpoint" }) tusEndpoint = "";
@property({ type: String, reflect: true }) protocol: "native" | "tus" =
"native";

@property({ type: String, reflect: true }) value: any;

@state() private alertText = "Something went wrong";
@state() private alertType: AlertType = "info";
@state() private showAlert = false;
@state() path = "";

@query("sl-input") input!: HTMLInputElement;

connectedCallback(): void {
super.connectedCallback();
if (!this.key) {
noKeyWarning("ecc-d-form-group", this.label);
this.key = toCamelCase(this.label);
this.key = _.camelCase(this.label);
}

this.findNearestFormGroup();
Expand Down Expand Up @@ -88,10 +90,12 @@ export default class EccUtilsDesignFormInput extends LitElement {
const parentPath = parentElement.getAttribute("path");
this.path = parentPath ? `${parentPath}.${this.key}` : this.key;
}

this.findNearestFormGroup(parentElement);
}

private handleDismissAlert() {
this.alertText = ""; // reset error text
this.alertText = "";
this.showAlert = false;
this.requestUpdate();
}
Expand All @@ -103,6 +107,18 @@ export default class EccUtilsDesignFormInput extends LitElement {
this.requestUpdate();
}

validity() {
return this.input.validity;
}

checkValidity() {
return this.input.checkValidity();
}

reportValidity() {
return this.input.reportValidity();
}

private handleFireChangeEvent() {
this.dispatchEvent(
new CustomEvent("ecc-utils-change", {
Expand All @@ -121,10 +137,7 @@ export default class EccUtilsDesignFormInput extends LitElement {
const target = e.target as HTMLInputElement;
this.value = this.type === "switch" ? target.checked : target.value;

// fire change event
this.handleFireChangeEvent();

// update
this.requestUpdate();
}

Expand Down
53 changes: 0 additions & 53 deletions packages/ecc-utils-design/src/components/form/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,6 @@ export function renderInTooltip(
: content;
}

// write a function that takes any string and converts it to a camelCase variable name
export function toCamelCase(str: string): string {
return str
.replace(/[^a-zA-Z0-9\s]/g, "") // Remove special characters
.split(/[\s_-]+/) // Split on spaces, underscores, and hyphens
.map((word, index) => {
if (index === 0) {
return word.toLowerCase();
}
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
})
.join("");
}

// write a function to console.warn a string that is sent as a param, only when app is in dev mode
export function devWarn(message: string): void {
// eslint-disable-next-line turbo/no-undeclared-env-vars
Expand All @@ -44,42 +30,3 @@ export function noKeyWarning(Element: string, label: string): void {
export function isShadowElement(element: Element): boolean {
return element.getRootNode() instanceof ShadowRoot;
}

/**
* Finds the nearest form group and returns its path.
* @param element The starting element to search from.
* @param key The key of the current element (if applicable).
* @returns The path of the nearest form group, or null if not found.
*/
export function findNearestFormGroup(
element: HTMLElement,
key?: string,
groupItem = false
): string | null {
if (!element) return null;

if (element.matches("ecc-d-form") || element.matches("ecc-d-form-group")) {
return null;
}

const { parentElement } = element;
if (!parentElement) return null;

const specialAttributes = [
"ecc-array-item",
"ecc-form-item",
"ecc-group-item",
];
const hasSpecialAttribute = specialAttributes.some((attr) =>
parentElement.hasAttribute(attr)
);

if (hasSpecialAttribute) {
const parentPath = parentElement.getAttribute("path");
return parentPath && key
? `${parentPath}.${key}`
: key || parentPath || null;
}

return findNearestFormGroup(parentElement, key, groupItem);
}

0 comments on commit da7b208

Please sign in to comment.