Skip to content

Commit

Permalink
Allow users to set a callback function (#11)
Browse files Browse the repository at this point in the history
* Allow users to set a callback function

* 1.3.0
  • Loading branch information
Spencer14420 authored Nov 24, 2024
1 parent b854ce1 commit dc46c68
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 135 deletions.
26 changes: 15 additions & 11 deletions dist/ContactForm.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import "bootstrap";
import { Modal } from "bootstrap";

export declare class ContactForm {
serverScript: string;
tokenInputName: string | null;
successModal: Modal | null;
messageAlert: HTMLElement | null;
constructor(serverScript: string, tokenInputName?: string | null);
initializeEventListeners(): void;
isEmail(email: string): boolean;
messageSuccess(): void;
sendMessage(data: Record<string, string>): Promise<void>;
handleSubmit(): void;
displayAlert(message: string): void;
serverScript: string;
tokenInputName: string | null;
successModal: Modal | null;
messageAlert: HTMLElement | null;
onSuccess: ((responseData: Record<string, any>) => void) | null;

constructor(
serverScript: string,
tokenInputName?: string | null,
onSuccess?: ((responseData: Record<string, any>) => void) | null,
);

handleSubmit(): void;
displayAlert(message: string): void;
}
106 changes: 55 additions & 51 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,19 @@
import "bootstrap";
import { Modal } from "bootstrap";
export class ContactForm {
constructor(serverScript, tokenInputName = null) {
this.successModal = null;
constructor(serverScript, tokenInputName = null, onSuccess = null) {
this.serverScript = serverScript;
this.tokenInputName = tokenInputName;
this.onSuccess = onSuccess;
const modalElement = document.querySelector(
"#success"
);
if (modalElement) {
this.successModal = new Modal(modalElement);
}
this.successModal = modalElement ? new Modal(modalElement) : null;
this.messageAlert = document.querySelector(
"#message-alert"
);
this.initializeEventListeners();
}
initializeEventListeners() {
document.querySelector("#sendmessage")?.addEventListener("click", () => this.handleSubmit());
}
isEmail(email) {
if (email.length > 254) {
return false;
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}
messageSuccess() {
["#name", "#email", "#message"].forEach((selector) => {
const element = document.querySelector(
selector
);
if (element) {
element.value = "";
}
});
document.querySelector("#contactCancel")?.click();
if (this.successModal) {
this.successModal.show();
}
}
async sendMessage(data) {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => formData.append(key, value));
try {
const response = await fetch(this.serverScript, {
method: "POST",
body: formData
});
const responseData = await response.json();
const errorMessage = responseData.message || "An error occurred. Please try again later.";
if (!response.ok || responseData.status !== "success") {
this.displayAlert(errorMessage);
return;
}
this.messageSuccess();
} catch (error) {
console.error("Error sending message", error);
this.displayAlert(
"An unexpected error occurred. Please try again later."
);
}
}
handleSubmit() {
const emailElement = document.querySelector(
"#email"
Expand Down Expand Up @@ -113,4 +65,56 @@ export class ContactForm {
console.error("Message alert element not found.");
}
}
initializeEventListeners() {
document.querySelector("#sendmessage")?.addEventListener("click", () => this.handleSubmit());
}
isEmail(email) {
if (email.length > 254) {
return false;
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}
messageSuccess(responseData) {
["#name", "#email", "#message"].forEach((selector) => {
const element = document.querySelector(
selector
);
if (element) {
element.value = "";
}
});
const cancelButton = document.querySelector(
"#contactCancel"
);
cancelButton?.click();
if (this.successModal) {
this.successModal.show();
}
if (this.onSuccess) {
this.onSuccess(responseData || {});
}
}
async sendMessage(data) {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => formData.append(key, value));
try {
const response = await fetch(this.serverScript, {
method: "POST",
body: formData
});
const responseData = await response.json();
const errorMessage = responseData.message || "An error occurred. Please try again later.";
if (!response.ok || responseData.status !== "success") {
this.displayAlert(errorMessage);
return;
}
this.messageSuccess(responseData);
} catch (error) {
console.error("Error sending message", error);
this.displayAlert(
"An unexpected error occurred. Please try again later."
);
}
}
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spemailhandler",
"version": "1.2.0",
"version": "1.3.0",
"description": "A script to handle the interaction between a Bootstrap-based contact form and the server, handling form submission and feedback.",
"main": "dist/index.js",
"types": "dist/ContactForm.d.ts",
Expand Down
151 changes: 81 additions & 70 deletions src/ContactForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import "bootstrap";
import { Modal } from "bootstrap";

export class ContactForm {
serverScript: string;
tokenInputName: string | null;
successModal: Modal | null = null;
messageAlert: HTMLElement | null;

constructor(serverScript: string, tokenInputName: string | null = null) {
public serverScript: string;
public tokenInputName: string | null;
public successModal: Modal | null;
public messageAlert: HTMLElement | null;
public onSuccess: ((responseData: Record<string, any>) => void) | null;

constructor(
serverScript: string,
tokenInputName: string | null = null,
onSuccess: ((responseData: Record<string, any>) => void) | null = null,
) {
this.serverScript = serverScript;
this.tokenInputName = tokenInputName;
this.onSuccess = onSuccess;

const modalElement = document.querySelector(
"#success",
) as HTMLElement | null;
if (modalElement) {
this.successModal = new Modal(modalElement);
}
this.successModal = modalElement ? new Modal(modalElement) : null;

this.messageAlert = document.querySelector(
"#message-alert",
Expand All @@ -25,66 +29,7 @@ export class ContactForm {
this.initializeEventListeners();
}

initializeEventListeners(): void {
document
.querySelector("#sendmessage")
?.addEventListener("click", () => this.handleSubmit());
}

isEmail(email: string): boolean {
if (email.length > 254) {
return false;
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}

messageSuccess(): void {
["#name", "#email", "#message"].forEach((selector) => {
const element = document.querySelector(
selector,
) as HTMLInputElement | null;
if (element) {
element.value = "";
}
});
(
document.querySelector("#contactCancel") as HTMLButtonElement | null
)?.click();
if (this.successModal) {
this.successModal.show();
}
}

async sendMessage(data: Record<string, string>): Promise<void> {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => formData.append(key, value));

try {
const response = await fetch(this.serverScript, {
method: "POST",
body: formData,
});

const responseData = await response.json();
const errorMessage =
responseData.message || "An error occurred. Please try again later.";

if (!response.ok || responseData.status !== "success") {
this.displayAlert(errorMessage);
return;
}

this.messageSuccess();
} catch (error) {
console.error("Error sending message", error);
this.displayAlert(
"An unexpected error occurred. Please try again later.",
);
}
}

handleSubmit(): void {
public handleSubmit(): void {
const emailElement = document.querySelector(
"#email",
) as HTMLInputElement | null;
Expand Down Expand Up @@ -138,12 +83,78 @@ export class ContactForm {
this.sendMessage(data);
}

displayAlert(message: string): void {
public displayAlert(message: string): void {
if (this.messageAlert) {
this.messageAlert.innerHTML = message;
this.messageAlert.style.display = "block";
} else {
console.error("Message alert element not found.");
}
}

private initializeEventListeners(): void {
document
.querySelector("#sendmessage")
?.addEventListener("click", () => this.handleSubmit());
}

private isEmail(email: string): boolean {
if (email.length > 254) {
return false;
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailPattern.test(email);
}

private messageSuccess(responseData?: Record<string, any>): void {
["#name", "#email", "#message"].forEach((selector) => {
const element = document.querySelector(
selector,
) as HTMLInputElement | null;
if (element) {
element.value = "";
}
});

const cancelButton = document.querySelector(
"#contactCancel",
) as HTMLButtonElement | null;
cancelButton?.click();

if (this.successModal) {
this.successModal.show();
}

if (this.onSuccess) {
this.onSuccess(responseData || {});
}
}

private async sendMessage(data: Record<string, string>): Promise<void> {
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => formData.append(key, value));

try {
const response = await fetch(this.serverScript, {
method: "POST",
body: formData,
});

const responseData = await response.json();
const errorMessage =
responseData.message || "An error occurred. Please try again later.";

if (!response.ok || responseData.status !== "success") {
this.displayAlert(errorMessage);
return;
}

this.messageSuccess(responseData);
} catch (error) {
console.error("Error sending message", error);
this.displayAlert(
"An unexpected error occurred. Please try again later.",
);
}
}
}

0 comments on commit dc46c68

Please sign in to comment.