I needed a function that resets a form.

This means deleting the values from the fields and adjusting other settings to their default configuration.

This reset function will be performed after successful form submission and will be called from JS fetch functions (without reloading the page upon submission).

This way, the form will be ready for another submission if needed.

Although the native reset() function is great, I couldn’t use only it, because:

  • I needed the ability to reset only a specific part of the form (and not the whole form).
  • I needed the ability to re-adjust additional settings.

So I wrote a custom function that handles this.

Custom form reset function

/**
 * Reset Form.
 *
 * @param {HTMLElement} element - the entire form or a container object.
 */
function resetForm(element) {
	if (typeof element === undefined || element === null) {
		return;
	}

	if (element.tagName === 'FORM') {
		// The provided element is a form.
		// Use the native reset functionality.
		element.reset();
	} else {
		// The provided element is not a form.
		// Manually reset the fields within this element.

		// Fields to reset.
		const fields = element.querySelectorAll(
			'input:not([type="submit"]):not([type="hidden"]), textarea, select'
		);

		for (const field of fields) {
			if (field.type === 'checkbox' || field.type === 'radio') {
				if (field.hasAttribute('checked')) {
					// Was checked by default.
					field.checked = true;
				} else {
					field.checked = false;
				}
			} else {
				field.value = '';
			}
		}
	}

	const filledFields = element.querySelectorAll('[data-filled="true"]');

	for (const filledField of filledFields) {
		filledField.dataset.filled = false;
	}
}

Explanation

We can pass to this function either the entire form or another container object.

If the element that was passed is a form

(tag name is form).

We’ll use the native reset function. I always prefer to use native solutions if available.

If the element that was passed is not a form

(tag name is not equal to form).

In this case, we’ll have to manually reset the fields within this element.

Note that the function will reset all inputs (except submit and hidden inputs), text areas, and select elements within the container that was provided, as defined in const fields. To include other elements to reset, we can simply modify this querySelectorAll.

This part of the function will delete the values from the fields and reset checkboxes and radio buttons to their default configuration.

Additional adjustments

Then, for all types of elements (both form and other containers), the function will change the data-filled attribute of fields that were filled (filledFields) to false, as they are now empty again.

This part was needed because of another custom function that sets the data-filled attribute to true if a field has a value. This is done to apply some CSS settings to the label of the filled fields.

Usage

First, we’ll need to place this function in a JS file that is loaded on all relevant pages (such as pages that have a form).

Then, we can call this function from the fetch/ajax functions after the form is successfully submitted.

As explained, we can pass the entire form element, for example:

resetForm(form);

or another container object, such as:

resetForm(secondStep);