Browsers are constantly adding new HTML, JavaScript and CSS features. Here are some useful additions to working with forms that you might have missed…
requestSubmit()
Safari 16 will be the final browser to add support for requestSubmit
.
Before we look at how .requestSubmit()
works, let’s remind ourselves how programmatically submitting a form with JavaScript works when using the .submit()
method. Submitting a form with submit()
does not trigger a submit event. So in the following code, the form is submitted, preventDefault()
has no effect, and nothing is logged to the console:
const form = document.forms[0];
form.addEventListener('submit', function(event) {
// code to submit the form goes here
event.preventDefault();
console.log('form submitted!');
});
document.querySelector('.btn').addEventListener('click', function() {
form.submit();
})
.submit()
will also ignore any HTML form validation. Given the following markup, the form will be submitted when the input is empty even though the input has a required
attribute:
<form>
<label for="name">Name</label>
<input required name="name" id="name" type="text">
</form>
.requestSubmit()
is an alternative way to submit a form using JavaScript, but in contrast to .submit()
, HTML form validation will prevent the form from being submitted. If all the data entered in the form passes validation, the submit
event will be fired, meaning “form submitted!” would be logged to the console in the following example:
form.addEventListener('submit', function(event) {
event.preventDefault();
console.log('form submitted!');
});
document.querySelector('.btn').addEventListener('click', function() {
form.requestSubmit();
})
You could already achieve this by programmatically clicking the form’s submit button, but requestSubmit
is perhaps a more elegant solution.
submitter
property of submit event
The SubmitEvent.submitter
property gained full cross-browser support with the release of Safari 15.4. This read-only property specifies the <button>
or <input type="submit">
element that caused a form to be submitted.
<form>
<button name="foo" value="bar" type="submit">Bar</button>
<button name="foo" value="baz" type="submit">Baz</button>
</form>
When you have multiple submit buttons or inputs, each with a different value, only the value of the button or input that was clicked on to submit the form will be sent to the server, rather than both values. That’s nothing new. What is new is that the event listener for the submit event now has access to the event.submitter
property. You can use this to add a class to the button or input that triggered the form submission, for example, or to obtain its value
or any other of its HTML attributes.
document.forms[0].addEventListener('submit', function(event) {
event.preventDefault();
console.log(event.submitter.value);
console.log(event.submitter.formaction);
event.submitter.classList.add('spinner-animation');
})
formdata
event
This isn’t particularly new, but only achieved cross-browser support with the release of Safari 15. The main use case for the formdata
event is enabling custom elements to take part in form submissions. Outside of web components, though, it can still be useful.
You add a formdata
event listener to the form you want to interact with:
document.querySelector('form').addEventListener('formdata', handleFormdata);
The event is fired both by a regular HTML form submission and also by an occurrence of new FormData()
. event.formData
holds all of the data being submitted.
function handleFormdata(event) {
for (const entry of event.formData.values()) {
console.log(entry);
}
}
The callback function for the formdata
event listener runs before the data is sent to the server, giving you a chance to add to or modify the data being sent.
function handleFormdata(event) {
event.formData.append('name', 'John');
}
You could have modified or appended the FormData
inside the submit event handler but formdata
allows you to separate out the logic. It’s also an alternative to using hidden inputs in the markup of your form in cases where you are submitting the form “the old fashioned way” — i.e. relying on the built-in functionality of HTML to submit the form rather than doing it with fetch
.
showPicker()
for input elements
showPicker()
has been supported since Chrome 99, Firefox 101, and in the upcoming Safari 16. For an input element whose type attribute is either Date, Month, Week, Time, datetime-local
, color, or file, showPicker()
provides a programmatic way to display the selection UI. For color and file inputs, it’s always been possible to programmatically show the picker by calling .click
on the input:
document.querySelector('input[type="color"]').click();
That approach doesn’t work on date inputs, which is why this new API was added. .showPicker()
will also work with color and file inputs but there’s no real advantage to using it over .click()
.
![Datepicker open to August 2022.](https://i0.wp.com/css-tricks.com/wp-content/uploads/2022/08/s_1D10429F982A9F25F1E75E6799ABEAA4EAF24C27F477961C36F8FE7BAE1D4D7A_1661513159201_ScreenShot2022-08-26at12.25.52PM.png?resize=930%2C726&ssl=1)
Inert attribute
It’s always been possible to disable multiple inputs at once by wrapping them in a HTML fieldset
and disabling the fieldset
:
Inert is a new HTML attribute. It isn’t only for forms, but forms are certainly a key use-case. Unlike the disabled
attribute, inert
can be applied to a form
element itself. Everything within the form will be non-focusable and non-clickable. When it comes to assistive technologies, inert
is similar to setting aria-hidden="true"
. Unlike the disabled
attribute, inert
does not apply any styling by default, but it’s easy to add your own:
form[inert] {
opacity: .2;
}
There’s more to come…
The big one is styling <select>
elements, something developers have wanted for decades. It looks set to finally become a reality sometime soon with the introduction of selectmenu
.
But that’s it for now! The recent updates bring full browser support to form features we’ve been waiting for, making them prime for production use.
why input[type=”date”]’s calender cannot be styled? even it cannot be inspected using browsers inspect element.
The calendar HTML is in the shadow DOM so you can’t see in DevTools.
So, Apple has held back the advancement of the web platform in several different ways, for a substantial period of time, … again.
One day, maybe they will get tired of bringing up the rear, dragging their proverbials like a ship with it’s anchor permanently down?
I know, it’s not very correctist to ‘call out’ this sort of thing in comments … but, to me, a twit is British for idiot. Not something someone does online
If Apple delay
selectmenu
, I’m dusting off the pitchfork and heading to Cupertino!Couldn’t agree more. Apple should’ve never entered the browser game, or at least switch to using another engine. It’s a real PITA.
As an amateur front-end dev, pretty much everything in this article was new to me, which is fantastic! I’m stoked to attack my janky forms I’ve developed for work and update them! Thanks for the article!
I’m eagerly waiting for the built-in cursor stylings. But till date, the custom cursor is the only option.
If I remember, disabled elements are not included in the form POST this makes it tricky if you still want to know the value of those disabled elements.
Are elements with inert send with the form POST request?
Replacing disabled attributes with inert=“true” causes information loss to screen reader users. Like you say, it’s the equivalent of adding aria-hidden=“true”. The forms example is not typical, the typical example is for content outside of modal dialogs.
Just realised it’s not inert=true, it’s just inert