0

I have a file input tag which I want to trigger a form submission when it's state changes (files are selected to upload).

The reason I want to trigger the form submission is because submission triggers validation of required elements.

export default function Add() {
    const [status, setStatus] = useState('Upload a menu')

    //Create a ref to access a DOM element
    const fileInput = useRef(null) //<input type='text' />
    const form = useRef(null) // <form></form>

    //Used by the onChange prop to handle changeEvents, like addEventListener('change', )
    function handleUploads() {


        //******What do I put in here?*****

    }

    function handleSubmit() {
        setStatus('Uploading...')
        const resto = document.getElementById('resto')
        //Reference to the node accessible at 'current' attribute of ref
        const files = fileInput.current.files

        //Create a shallow-copied Array from files
        const filesArray = Array.from(files)
        filesArray.map(img => {
            const storageRef = storage.ref()
            const fileRef = storageRef.child(`menus/${resto}/${img.name}`)
            fileRef.put(img).then((snapshot) => {
                setStatus('Added!')
            })
        })
    }

    return (
        <section id="add">
            <form name="form" id="form" onSubmit={handleSubmit} ref={form}>
                <input type="text" placeholder="Restaurant" id="resto" required />
                <input type="file" capture="environment" accept="image/*" id="file" multiple
                    ref={fileInput} onChange={handleUploads} required
                />
                <label htmlFor="file">{status}</label>
                <button type="submit">Submit</button>
            </form>
        </section >
    )
} 

As I understand, I can't call handleSubmit() directly from handleUploads() as this will not trigger the browser "validation" of required values. Thus I have to make the browser think I am clicking a submit button.

Problem is, getting the form element by id does not trigger anything ``` document.getElementById("form").submit() ````

I found this solution which leads me to using refs to get the DOM element, and dispatchEvent to force a submission form.current.dispatchEvent(new Event("submit"))

But now the required validation that I wanted is not counted. What gives?

kmoser
  • 8,780
  • 3
  • 24
  • 40
Christian
  • 124
  • 2
  • 11
  • 2
    Why not call `handleSubmit()` from `handleUploads()`? – ichigolas May 16 '20 at 03:55
  • although what @nicooga has suggested would work for your use case, You should probably run validation using onBlur on your input elements and show a custom error if the value is missing. – Ilias Aboubeker May 16 '20 at 03:56
  • @nicooga as stated I want the form to be checked for the input fields with a required value. Meaning the form should throw an error on its own when it's trying to be submitted with a null field, just like a regular form on it's own – Christian May 16 '20 at 04:15
  • Does this answer your question? [Triggering HTML5 Form Validation](https://stackoverflow.com/questions/7548612/triggering-html5-form-validation) – ichigolas May 16 '20 at 05:15
  • @nicooga looks like checkValidity() is good for custom error handling/validation, so that isn't the fix. But, I looked at the related methods though and found **requestSubmit()** which is exactly what I was looking for! This question is solved. This is my first SO question but I assume I can't mark your comment as the answer? Regardless, if you can respond with an answer of requestSubmit() so I can mark this solved for everyone else to see – Christian May 16 '20 at 06:59

1 Answers1

4

The requestSubmit() function can be used to trigger input field validation and submission, however it is not compatible with all browsers so a fallback is needed

    //Check if requestSubmit() is available to current browser
    if (form.current.requestSubmit) {
        form.current.requestSubmit()
    }
    //If not, perform constraint validation and call submit function directly
    else {
        if (form.current.reportValidity()) {
                handleSubmit()
        }
    }

More info here:

  1. https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit
  2. https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
  3. https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation
lepsch
  • 8,927
  • 5
  • 24
  • 44
Christian
  • 124
  • 2
  • 11