JSFiddle - React, Tailwind, and code Playground

by Julien Etienne

HTML

<form id="form" class="upload-form-js" method="post" enctype="multipart/form-data">
            <!-- IMAGE DETAILS COMPONENT. THESE COMPONENTS ARE OUTPUTTED WITH A WHILE LOOP-->  
            <div class="upload-details-component" data-upload-details-component>                
                <div class="image-wrapper">
                    <img src="image.jpg">
                </div>
                <div class="edit-zone">
                    <div class="form-row">
                        <label for="image-title">Image Title</label>
                        <input data-image-title id="title-title" class="input-title" type="text" name="image-title[]">
                    </div>
                    <div class="form-row">
                        <label for="tags">Comma Separated Image Tags</label>
                        <textarea data-tab id="tags" class="text-area" type="text" name="image-tags[]"></textarea>
                    </div>
                    <div class="form-row">
                        <!-- DELETE BUTTON -->
                        <button data-delete name="upload-details-delete" value="12" class="remove-image">DELETE</button>
                        <input type="hidden" name="image-id[]" value="12">
                    </div>
                </div>
            </div>
            <!-- IMAGE DETAILS COMPONENT - END -->
        <div class="form-row upload-details-submit-row">
            <button id="upload-submit" class="upload-details-submit" type="submit" name="upload-submit">COMPLETE UPLOADS</button>
        </div>
    </form>

JavaScript

const uploadSubmit = document.querySelector('#upload-submit')
    const form = document.querySelector('#form')
    let currentImageTab
    let activeElement

    document.addEventListener('keydown', (e) => {
      // Check the input element is the image-title 
      const hasImageTitle = document.activeElement.hasAttribute('data-image-title')
      if (hasImageTitle) {
        // The current component

        if (e.key === 'Enter') {
          /* 
           ** Only using click for testing on SO ** 
           */
          uploadSubmit.click()
          e.preventDefault()

          /*  
            Use `form.submit()` instead of `uploadSubmit.click()` as it is 
            less hacky and less  prone to any propagation issues.
            Submit will submit the form but will not fire the submit event */
          // form.submit() 
        } else if (e.key === 'Tab') {
          // Re-enables tab
          e.preventDefault()
          currentImageTab.focus()
        }

      }
    })


    const getTab = () => document.activeElement.closest('[data-upload-details-component]')
      .querySelector('[data-tab]')


    document.addEventListener('focus', () => {
      // Updates current image tab

      if (document.activeElement.hasAttribute('data-image-title')) {
        // Each new image title is updated
        currentImageTab = getTab()
        // This prevents textarea being jumped to
        currentImageTab.setAttribute('tabindex', '-1')
      } else {
        // This re-enables textarea to be focus-able. 
        // Dosen't have to until the current image title has been accessed
        if (currentImageTab) {
          currentImageTab.removeAttribute('tabindex')
        }
      }
    }, true)


    /*
     Just as @bravo's example, this is just for testing, not required 
    */
    form.addEventListener('submit', e => {
      e.preventDefault()
      document.body.insertAdjacentHTML('afterend', `<div>Form submitted</div>`)
    })