I've written some code for custom validation for file upload and thought I'd share

Hi All,

I’ve seen a few requests recently for some kind of file restriction / validation in the form block, and thought I’d share the custom code I’ve developed for something I was working on. It’s a little hacky but works great for me at the moment. Hopefully it can be of use to others too.

How it works:

  • Disables the pointer event on the button on load, basically making it unclickable
  • When a file is uploaded, if it is one of the listed file types, the button becomes clickable again
  • If it is not one of the listed file types, a prompt will appear asking the user to upload a valid file type. At the same time, the upload field will be removed (thus limiting to only 1 file per form). Users will need to delete a file before being allowed to upload another.
  • There’s an additional check for file size too.

Add this script to the Head of your page:

<script>
window.addEventListener("load", function () {
  setTimeout(function () {
    const fileInput = document.getElementById("form-File-1762187525"); // change this
    const submitButton = document.querySelector("#form .css-v5uos8 .MuiButton-root"); // change this
    
    if (fileInput) {
      fileInput.setAttribute("onchange", "validateFileInput(this)");
    }
    
    if (submitButton) {
      submitButton.style.pointerEvents = "none";
      submitButton.style.opacity = "0.5";
    }
    
    // Event delegation for delete icon click
    const fileUploadContainer = document.querySelector(".file-holder"); 
    if (fileUploadContainer) {
      fileUploadContainer.addEventListener("click", function (e) {
        if (e.target && e.target.closest("svg")) {
          deleteUploadedFile();
        }
      });
    }
  }, 100);
});

function validateFileInput(input) {
  const fileUploadElement = document.querySelector(".css-7w99y0");
  const submitButton = document.querySelector("#form .css-v5uos8 .MuiButton-root"); // change this
  const validationMessage = document.getElementById("validation-message");
  const file = input.files[0];
  let isValid = true;

  if (file) {
    if (file.size > 24000000) {
      validationMessage.innerText = "File size should be less than 24MB.";
      isValid = false;
    } else {
      const allowedExtensions = ["pdf", "doc", "txt", "rtf"]; // change this
      const fileExtension = file.name.split(".").pop().toLowerCase();

      if (!allowedExtensions.includes(fileExtension)) {
        validationMessage.innerText = "Only pdf, doc, txt, or rtf files are allowed. Please delete the current file and upload a new one."; // change this
        isValid = false;
      } else {
        validationMessage.innerText = "";
      }
    }
  } else {
    validationMessage.innerText = "";
    isValid = false;
  }

  validationMessage.style.display = isValid ? "none" : "block";

  if (fileUploadElement) {
    fileUploadElement.style.display = file ? 'none' : 'flex';
  }

  if (submitButton) {
    if (isValid) {
      submitButton.style.pointerEvents = "auto";
      submitButton.style.opacity = "1";
    } else {
      submitButton.style.pointerEvents = "none";
      submitButton.style.opacity = "0.5";
    }
  }
}

function deleteUploadedFile() {
  const fileUploadElement = document.querySelector(".css-7w99y0");
  const submitButton = document.querySelector("#form .css-v5uos8 .MuiButton-root"); // change this
  const validationMessage = document.getElementById("validation-message");
  if (fileUploadElement) {
    fileUploadElement.style.display = 'flex';
  }
  const fileInput = document.getElementById("form-File-1762187525"); // change this
  if (fileInput) {
    fileInput.value = "";
  }

  if (submitButton) {
    submitButton.style.pointerEvents = "none";
    submitButton.style.opacity = "0.5";
  }

  validationMessage.innerText = "";
  validationMessage.style.display = "none";
}
</script>

You’ll also want to put this DIV in a custom code block under the form:

<div id="validation-message" style="display: none; color: #de350b; text-align: center; font-size: 12px;"></div>

Things you need to modify to make this work for you:

Replace “form-File-1762187525” with whatever your form upload field is:

    const fileInput = document.getElementById("form-File-1762187525");

Set this to whatever your form is called:

  const submitButton = document.querySelector("#form .css-v5uos8 .MuiButton-root");

Set the array to whatever file extensions you want to allow:

      const allowedExtensions = ["pdf", "doc", "txt", "rtf"];

Add your own text to the error message:

        validationMessage.innerText = "Only pdf, doc, txt, or rtf files are allowed. Please delete the current file and upload a new one.";

Here’s some photos of what it looks like:


I think that’s everything. Like I said, this works well for my use case, but probably not written very well / formatted very well. If anyone fancies improving on this, feel free.

Any questions, just ask.

9 Likes

Hi @EnigmaXXIII, thank you very much for sharing the custom code with us :heart:

This is useful, do you know how to add # of files validation?

IE - it only accepts 1 file upload

Many thanks!

Note that it is in our plans to add multiple file upload options to our form blocks in the future.

@EnigmaXXIII This is really fantastic! I am hoping to do something similar for my form, except instead of check for valid files, I would like to dynamically compare the input with elements in my data (airtable).

In my case, my form is for people to enter potential commenters on articles. I want to check two things: 1) if the email entered in the form is one of the articles authors (each articles information is stored in one base sheet), and 2) if the email has already been suggested as a commenter (potential commenters are in a different sheet of the same base). I have tried having chatgpt to help me with this, but it seems to be a lost cause, and I have very limited html/javascript experience. I can provide my code if that would be helpful!