Skip to content

Commit 5dba43f

Browse files
committed
feat(forms): disabled action buttons while submiting data
1 parent ea98009 commit 5dba43f

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

README.md

-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ A React implementation of Boostrap v4 components.
66

77
## Roadmap
88

9-
- [] UrlLinkedTabs
10-
- [] UrlLinkedPagination
119
- [] Smartable
1210
- [] Form Range
1311
- [] Form generation based on a configuration option
@@ -19,7 +17,6 @@ A React implementation of Boostrap v4 components.
1917
- [] Keyboard navigation on FormAutocomplete
2018
- [] Automatic input id
2119
- [] Subforms
22-
- [] Button with loading/saving state
2320
- [] Sidebar
2421
- [] Stepper
2522
- [] Tree

demo/FormExamples.jsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ export function FormExamples() {
2525
dateField: new Date().toISOString(),
2626
}}
2727
onChange={console.info}
28-
onSubmit={(formData, reset) => {
28+
onSubmit={(formData) => {
2929
console.log('onSubmit', formData);
30-
// return Promise.resolve();
31-
reset();
30+
31+
return new Promise((resolve) => {
32+
setTimeout(() => {
33+
resolve();
34+
}, 1000);
35+
});
3236
}}
3337
transform={(formData, pathUpdated, update) => {
3438
formData.__v = formData.__v ? formData.__v + 1 : 1;

src/forms/Form.jsx

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef } from 'react';
1+
import React, { useRef, useState } from 'react';
22
import PropTypes from 'prop-types';
33
import { FormContext } from './helpers/form-helpers';
44
import { useForm } from './helpers/useForm';
@@ -19,6 +19,7 @@ export function Form({
1919
}) {
2020
const formState = useForm(initialValues, { validations, onChange, transform });
2121
const formRef = useRef(null);
22+
const [isSubmiting, setIsSubmiting] = useState(false);
2223

2324
function resetForm() {
2425
formRef.current.classList.remove('was-validated');
@@ -36,11 +37,20 @@ export function Form({
3637
return;
3738
}
3839

39-
const res = onSubmit(formState.getFormData(), resetForm);
40+
setIsSubmiting(true);
41+
const submitResponse = onSubmit(formState.getFormData(), resetForm);
4042

41-
if (res && res.then) {
42-
res.then(resetForm);
43+
let submitPromise = Promise.resolve();
44+
45+
if (submitResponse && submitResponse.then) {
46+
submitPromise = submitResponse.then(() => {
47+
resetForm();
48+
});
4349
}
50+
51+
submitPromise.finally(() => {
52+
setIsSubmiting(false);
53+
});
4454
}
4555

4656
function handleCancel() {
@@ -61,7 +71,7 @@ export function Form({
6171
<form {...formProps}>
6272
<FormContext.Provider value={formState}>{children}</FormContext.Provider>
6373

64-
{customActions || <FormActions {...{ submitLabel, cancelLabel, onCancel: handleCancel }} />}
74+
<FormActions {...{ submitLabel, cancelLabel, onCancel: handleCancel, isSubmiting, customActions }} />
6575
</form>
6676
);
6777
}

src/forms/FormActions.jsx

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import { isFunction } from '../utils/types';
4+
5+
export function FormActions({ submitLabel, cancelLabel, onCancel, isSubmiting, customActions }) {
6+
if (customActions) {
7+
return isFunction(customActions) ? customActions(isSubmiting) : customActions;
8+
}
39

4-
export function FormActions({ submitLabel, cancelLabel, onCancel }) {
510
return (
611
<div className="form-actions">
7-
<button type="submit" className="btn btn-primary mr-1">
8-
{submitLabel}
12+
<button type="submit" className="btn btn-primary mr-1" disabled={isSubmiting}>
13+
{isFunction(submitLabel) ? submitLabel(isSubmiting) : submitLabel}
914
</button>
10-
<button type="button" className="btn btn-secondary" onClick={onCancel}>
15+
<button type="button" className="btn btn-secondary" onClick={onCancel} disabled={isSubmiting}>
1116
{cancelLabel}
17+
{isFunction(cancelLabel) ? cancelLabel(isSubmiting) : cancelLabel}
1218
</button>
1319
</div>
1420
);
1521
}
1622

1723
FormActions.propTypes = {
18-
submitLabel: PropTypes.string,
19-
cancelLabel: PropTypes.string,
24+
submitLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
25+
cancelLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
2026
onCancel: PropTypes.func.isRequired,
27+
isSubmiting: PropTypes.bool,
28+
customActions: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
2129
};

0 commit comments

Comments
 (0)