Explain Codes LogoExplain Codes Logo

How to filter input type="file" dialog by specific file type?

javascript
file-input
javascript-validation
client-side-validation
Alex KataevbyAlex Kataev·Jan 25, 2025
TLDR

To specify certain type acceptance for a file input, utilize the accept attribute. If you want the file type to be a JPEG image:

<input type="file" accept=".jpg, .jpeg">

Or, to accept PDFs, Word, and Excel files:

<input type="file" accept=".pdf, .docx, .xlsx">

Thus, non-specified formats are filtered out by the file picker.

More on the accept attribute

The accept attribute is quite flexible. It can name MIME types for improved coverage:

<input type="file" accept="image/jpeg, application/pdf">

In this case, the file input recognises JPEG images and PDF files based on their content type instead of extensions for wider recognition (tip: you can use both methods together).

Handle browser behaviour & server-side validation

Remember that the accept attribute interpretation varies across browsers. Hence, consider client-side filtering as a helping aid rather than a firewall. Ensure that the file type is validated on the server-side too, as client-side security measures can be bypassed.

Supercharge validation with JavaScript

Better control can be achieved by using the accept attribute in conjunction with JavaScript:

const fileInput = document.querySelector('input[type="file"]'); fileInput.addEventListener('change', function (event) { const fileName = event.target.value; // "You shall not pass!"—Gandalf (if not a JPEG) if (fileName.lastIndexOf('.jpg') === -1) { alert('Please select a JPEG file.'); return false; } }); fileInput.accept = '.jpg'; // Dynamically setting the file type Gandalf likes fileInput.click(); // Open the dialog programmatically, like magic!

This way, the extra layer of client-side validation guides users toward correct file selection and blocks Gandalf-angering files.

Better UX through feedback

Always provide user feedback when an incorrect file type is chosen:

if (fileName.lastIndexOf('.jpg') === -1) { alert('Invalid file type. Please select a JPEG image.'); }

And of course, spread positivity with confirmation messages:

alert('JPEG image selected! 🎉');

Tactics

  • Employ accept and stay away from non-standard attributes.
  • MIME types are reliable over extensions, so opt for MIME types whenever possible.
  • Guard both client-side (usability) and server-side (security) like a vigilant watchman.
  • Okay, accept filters the dialog, but be careful to verify the actual file content to curb Gandalf's wrath.

Preparing countermeasures

Present in accept is your first line of defense, determining what the user should select. But the enemy is crafty, manually typing "." into the file name field exposes all file types despite the filter, revealing the gaps in client-side filtering.

By handling the onchange event through JavaScript, you set up a secondary checkpoint that alerts the user if they attempt to select a disallowed file type.

Going the extra mile

  • Enhance accessibility by providing adequate responses for every user interaction.
  • Foster a habit of progressive enhancement: start with basic HTML, then jazz it up with CSS and JavaScript.
  • Keep an eye out for browser updates that might alter how file inputs and the accept attribute perform.