Skip to content

Instantly share code, notes, and snippets.

@vlucas
Created May 10, 2022 20:50
Show Gist options
  • Save vlucas/71fbd57df45847c2bbcd5188985b6244 to your computer and use it in GitHub Desktop.
Save vlucas/71fbd57df45847c2bbcd5188985b6244 to your computer and use it in GitHub Desktop.
ApiForm React Component for native <form> onSubmit support
import type { FormEvent } from 'react';
export type onFormSubmit = (e: FormEvent, data: { [key: string]: any}) => void
export type ApiFormProps = {
children: any,
onSubmit: onFormSubmit,
[key: string]: any, // Allows any other props to be passed through to element
}
/**
* Create object with provided arrays of keys and values
*
* @param {string[]} keys
* @param {any[]} values
*/
function zipObject(keys: any[], values: any[]) {
return keys.reduce(function(object, currentValue, currentIndex) {
object[currentValue] = values[currentIndex];
return object;
}, {});
}
function getFormValues(form: HTMLFormElement) {
let fieldsArray = Array.from(new FormData(form).entries());
let fieldNames = fieldsArray.map(f => f[0]);
let fieldValues = fieldsArray.map(f => f[1]);
return zipObject(fieldNames, fieldValues);
};
/**
* onSubmit
*/
function handleOnSubmit(e: FormEvent, formEl: HTMLFormElement, onSubmitCallback: onFormSubmit) {
e.preventDefault();
let formData = getFormValues(formEl);
// Call 'onSubmit' method if present with formatted data
if (onSubmitCallback !== undefined) {
onSubmitCallback(e, formData);
}
return false;
};
export default function ApiForm(props: ApiFormProps) {
let formEl: HTMLFormElement;
const { children, onSubmit, ...restProps } = props;
return (
<form onSubmit={(e) => handleOnSubmit(e, formEl, onSubmit)} ref={(form: HTMLFormElement) => formEl = form} {...restProps}>
{props.children}
</form>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment