Skip to content

Commit

Permalink
feat(button): disable button while submitting
Browse files Browse the repository at this point in the history
  • Loading branch information
ido-pluto committed Jul 6, 2024
1 parent b236de0 commit 53e0fe5
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
1 change: 1 addition & 0 deletions examples/simple-form/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"reactstrap": "^9.2.1",
"sleep-promise": "^9.1.0",
"zod": "^3.22.4"
}
}
8 changes: 6 additions & 2 deletions examples/simple-form/src/pages/counter.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
import { BButton, Bind, BindForm } from "@astro-utils/forms/forms.js";
import { Button } from 'reactstrap';
import Layout from "../layouts/Layout.astro";
import sleep from "sleep-promise";
const { session } = Astro.locals;
function increaseCounter() {
async function increaseCounter() {
session.counter ??= 0
session.counter++
session.counter++;
console.log(session.counter)
await sleep(1000 * 5);
}
---
<Layout title="counter">
<BindForm key="page">
Expand Down
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.

37 changes: 33 additions & 4 deletions packages/forms/src/components/WebForms.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { asyncContext } from '@astro-utils/context';
import { createFormToken } from '../form-tools/csrf.js';
import { getFormOptions } from '../settings.js';
export interface Props extends astroHTML.JSX.FormHTMLAttributes {}
export interface Props extends astroHTML.JSX.FormHTMLAttributes {
loadingClassName?: string;
}
const context = {
...Astro.props,
Expand All @@ -14,34 +16,45 @@ const context = {
const htmlSolt = await asyncContext(() => Astro.slots.render('default'), Astro, { name: '@astro-utils/forms', context, lock: 'webForms' });
const { webFormsSettings, tempValues, statesKey, ...props } = context;
const { webFormsSettings, tempValues, statesKey, loadingClassName = 'loading', ...props } = context;
if (webFormsSettings.haveFileUpload) {
props.enctype = 'multipart/form-data';
}
const useSession = getFormOptions(Astro).session?.cookieOptions?.maxAge;
const formRequestToken = useSession && (await createFormToken(Astro));
const clientScript = Astro.locals.forms.scriptToRun;
const clientWFS = { loadingClassName };
---

<form method='post' {...props}>
{formRequestToken && <input type='hidden' name={formRequestToken.filed} value={formRequestToken.token} />}
<Fragment set:html={htmlSolt} />
{clientScript && <script set:html={clientScript} />}
</form>

<script define:vars={{ clientWFS }} is:inline>
window.clientWFS = clientWFS;
</script>

<script>
declare global {
interface Window {
__enterToSubmit: (event: KeyboardEvent, id: string) => void;
submitForm(value: HTMLElement | string): void;

clientWFS: {
loadingClassName: string;
};
}
}

window.__enterToSubmit = function (event) {
const target = event.target as HTMLElement;
const isMultiLine = target instanceof HTMLTextAreaElement;

if ((isMultiLine && event.ctrlKey || !isMultiLine) && event.code === 'Enter') {
if (((isMultiLine && event.ctrlKey) || !isMultiLine) && event.code === 'Enter') {
event.preventDefault();
document.getElementById(target.getAttribute('data-submit')!)?.click();
}
Expand All @@ -51,9 +64,25 @@ const clientScript = Astro.locals.forms.scriptToRun;
if (typeof value !== 'string') {
value = value.getAttribute('data-submit');
}
if(value == null){
if (value == null) {
return console.warn('submitForm: value is null, make sure you pass `this` to this method or an id of the button you want to submit.');
}
document.getElementById(value)?.click();
};

const form = document.querySelector('form');
form?.querySelectorAll('button[type="submit"]').forEach(button => {
button.addEventListener('click', () => {
button.classList.add(window.clientWFS.loadingClassName);
document.dispatchEvent(new CustomEvent('WFSubmitting', { detail: { button } }));
});
});

form?.addEventListener('submit', () => {
setTimeout(() => {
form.querySelectorAll('button[type="submit"]').forEach(button => {
(button as HTMLButtonElement).disabled = true;
});
}, 0);
});
</script>

0 comments on commit 53e0fe5

Please sign in to comment.