1

I have some code that works perfectly for grabbing and clicking a custom upload file button. The thing is I want it to duplicate this form 2 more times to have the user use 3 upload buttons in my overall form. So the user will be able to upload three files. My question is, how do I change my vanilla JavaScript so that instead of grabbing the one element, it grabs multiple elements? Do I use getElementsByClassName? And if I do how do I iterate through each form element individually to upload the file?

Upload form 1:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
Upload form 2:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>
upload form 3:
<input type="file" id="real-file" hidden="hidden" />
<button type="button" id="custom-button">CHOOSE A FILE</button>
<span id="custom-text">No file chosen, yet.</span>

const realFileBtn = document.getElementById("real-file");
const customBtn = document.getElementById("custom-button");
const customTxt = document.getElementById("custom-text");

customBtn.addEventListener("click", function() {
  realFileBtn.click();
});

realFileBtn.addEventListener("change", function() {
  if (realFileBtn.value) {
    customTxt.innerHTML = realFileBtn.value.match(
      /[\/\\]([\w\d\s\.\-\(\)]+)$/
    )[1];
  } else {
    customTxt.innerHTML = "No file chosen, yet.";
  }
});

CSS 

#custom-button {
  padding: 10px;
  color: white;
  background-color: #009578;
  border: 1px solid #000;
  border-radius: 5px;
  cursor: pointer;
}

#custom-button:hover {
  background-color: #00b28f;
}

#custom-text {
  margin-left: 10px;
  font-family: sans-serif;
  color: #aaa;
}

luek baja
  • 1,475
  • 8
  • 20
Jeremy Mark
  • 73
  • 1
  • 1
  • 4
  • Related: https://stackoverflow.com/questions/59887834/getting-the-value-of-the-input-field-using-jquery/59888053#59888053 Use classes instead of repeating ids. – Taplar Aug 24 '20 at 17:27

1 Answers1

0

As suggested by @Taplar, you'll need to change IDs to classes and then somehow link the elements (I used data-file-input-id).

One of the possible solutions could be:

HTML:

      <input type="file" class="real-file" id="first" hidden="hidden" />
      <button type="button" class="custom-button" data-file-input-id="first" >CHOOSE A FILE</button>
      <span class="custom-text" data-file-input-id="first">No file chosen, yet.</span>

      <input type="file" class="real-file" id="second" hidden="hidden" />
      <button type="button" class="custom-button" data-file-input-id="second">CHOOSE A FILE</button>
      <span class="custom-text" data-file-input-id="second">No file chosen, yet.</span>

      <input type="file" class="real-file" id="third" hidden="hidden" />
      <button type="button" class="custom-button" data-file-input-id="third">CHOOSE A FILE</button>
      <span class="custom-text" data-file-input-id="third">No file chosen, yet.</span>

JS:

// Grab only buttons with data-file-input-id attribute
const buttons = document.querySelectorAll("button[data-file-input-id]");
const fileInputs = document.querySelectorAll("input[type=file]");

Array.from(buttons).forEach(function (button) {
  button.addEventListener("click", function () {
    const correspondingInputId = button.getAttribute("data-file-input-id");
    document.getElementById(correspondingInputId).click();
  });
});

Array.from(fileInputs).forEach(function (fileInput) {
  fileInput.addEventListener("change", function () {
    const fileInputId = fileInput.id;
    const correspondingTextField = document.querySelector(
      'span[data-file-input-id="' + fileInputId + '"]'
    );

    if (fileInput.value) {
      correspondingTextField.innerHTML = fileInput.value.match(
        /[\/\\]([\w\d\s\.\-\(\)]+)$/
      )[1];
    } else {
      correspondingTextField.innerHTML = "No file chosen, yet.";
    }
  });
});

CSS:

.custom-button {
  padding: 10px;
  color: white;
  background-color: #009578;
  border: 1px solid #000;
  border-radius: 5px;
  cursor: pointer;
}

.custom-button:hover {
  background-color: #00b28f;
}

.custom-text {
  margin-left: 10px;
  font-family: sans-serif;
  color: #aaa;
}
watofundefined
  • 334
  • 4
  • 6