Knowing if a field in a form has been filled can sometimes be useful, for instance, to apply design adjustments to this field.

Method 1: CSS pseudo-class

The :placeholder-shown CSS pseudo-class is probably the simplest way to detect if there is text in the field.

I would recommend this method whenever possible, as it uses a native browser capability. That means there is no need for custom JS functions.

We can tell if a field is filled in based on the visibility status of its placeholder.

If the placeholder is displayed (:placeholder-shown) - it means no data was typed. This is because as soon as the user types in any text, the placeholder disappears.

HTML

The HTML structure of an input will look something like this:

<input
	id="first_name"
	name="first_name"
	class="form-control"
	type="text"
	placeholder="John"
/>

We created a text input and added a form-control class in order to select all relevant inputs later.

Yet, if we don’t want to set a specific placeholder, we can also leave it blank using a space, like so:

<input
	id="first_name"
	name="first_name"
	class="form-control"
	type="text"
	placeholder=" "
/>

CSS

We can now select all filled fields with a simple CSS selector:

.form-control:not(:placeholder-shown) {
	/* This field has been filled. */
}

JavaScript

The same selector can be used in JS:

const filledFields = document.querySelectorAll(
	'.form-control:not(:placeholder-shown)'
);

for (const filledField of filledFields) {
	// This field has been filled.
}

Method 2: JavaScript function

However, sometimes we can’t use the :placeholder-shown method. For example, when using a select tag (used to create a dropdown menu). This tag does not support the placeholder attribute.

Thus, a possible solution could be a JavaScript function that would mark the status of the field:

function updateFieldStatus(e) {
	const field = e.currentTarget;
	const isFilled = field.value ? true : false;

	field.dataset.filled = isFilled;
}

const fields = document.querySelectorAll('.form-control');

for (const field of fields) {
	field.addEventListener('change', updateFieldStatus);
	field.addEventListener('keydown', updateFieldStatus);
	field.addEventListener('keyup', updateFieldStatus);
}

This function is triggered whenever a change is being made in a field (with a form-control class). It adds a filled data attribute to the field.

This data attribute will have a value of true if the field is filled, or false if not.

So when the user selects an option from a dropdown, for example, the filled data attribute of the select tag will be updated as follows:

<select
	id="country"
	name="country"
	class="form-control"
	data-filled="true"
></select>

CSS

We can then select these filled fields using this simple CSS selector:

.form-control[data-filled='true'] {
	/* This field has been filled. */
}

JavaScript

Once again, we can use the same selector also in JS:

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

for (const filledField of filledFields) {
	// This field has been filled.
}

References