JSFiddle - React, Tailwind, and code Playground

HTML

<html>
  <input type="file"/>
  <br><br>
  <select id="footer">
    <option disabled selected>-- Select a footer --</option>
    <option value="47020000CD10700274066A380C00000043616E31">S-2002_e BRAWL BROTHERS</option>
    <option value="470200004411740670010A00000043616E31">S-2003_e Breath Of Fire</option>
    <option value="4702000046117646740670010C00000043616E31">S-2004_e Demon's Crest</option>
    <option value="47020000621274067002500400001E0000001200000043616E31">S-2006_e Joe & Mac 2: Lost in the Tropics</option>
    <option value="4702000058107682740670020C00000043616E31">S-2007_e Kirby's Dream Course</option>
    <option value="47020000A2107678740670020C00000043616E31">S-2008_e Kirby's Dream Land 3</option>
    <option value="47020000C710700174060A00000043616E31">S-2013_e SUPER E.D.F. EARTH DEFENSE FORCE</option>
    <option value="4702000003107628740670010C00000043616E31">S-2015_e Super Ghouls'n Ghosts</option>
    <option value="47020000BD10740663016A3870020E00000043616E31">S-2016_e Super Mario Kart</option>
    <option value="4702000011107691740670020C00000043616E31">S-2017_e Super Mario World</option>
    <option value="470200004712700476A574060C00000043616E31">S-2020_e Super Puyo Puyo 2</option>
    <option value="470200004112740670020A00000043616E31">S-2021_e Super Soccer</option>
    <option value="470200006612740770020A00000043616E31">S-2022_e Super Tennis</option>
    <option value="470200001D107682740670010C00000043616E31">S-2024_e The Legend of Zelda: A Link to the Past</option>
    <option value="470200004A126803740670040C00000043616E31">S-2014_j Super Family Tennis</option>
    <option disabled>-- Super FX --</option>
    <option value="470200003B12650C74067001550200003C051200000043616E31">S-2011_e Star Fox</option>
    <option value="470200003E12650C74067002550200003C051200000043616E31">S-2012_e Stunt Race FX</option>
    <option value="470200003D12650C74067001550200004A061200000043616E31">S-2023_e Super Mario World 2: Yoshi's...

JavaScript

document.querySelector('select').addEventListener('change', processSelection, false);
document.querySelector('button').addEventListener('click', processDownload, false);

function processDownload() {
  var file = document.querySelector('input').files[0];
  var sel = document.querySelector('select');
  var pid = document.getElementById('pid').value;

  if (file && sel.options.selectedIndex && pid.length == 4) {
    var reader = new FileReader();
    reader.onload = function() {
      var romBytes = new Uint8Array(reader.result);
      var footerHex = sel.options[sel.selectedIndex].value;
      var footerBytes = new Uint8Array(Math.ceil(footerHex.length / 2));
      
      for (var i = 0; i < footerBytes.length; i++) {
        footerBytes[i] = parseInt(footerHex.substr(i * 2, 2), 16);
      }
  
      if (pid != footerHex.substr(10, 2) + footerHex.substr(8, 2)) {
        footerBytes[4] = parseInt(pid.substr(2, 2), 16);
        footerBytes[5] = parseInt(pid.substr(0, 2), 16);
      }

      var joinedBytes = new Uint8Array(romBytes.byteLength + footerBytes.byteLength);
      joinedBytes.set(romBytes);
      joinedBytes.set(footerBytes, romBytes.byteLength);

      var blob=new Blob([joinedBytes], {type: "application/octet-stream"});

      if (window.navigator && window.navigator.msSaveBlob) {
        window.navigator.msSaveBlob(blob, 'test.sfrom');
      } else {
        var link=document.createElement('a');
        link.href=window.URL.createObjectURL(blob);
        link.download="test.sfrom";
        document.body.appendChild(link)
        link.click();
      }

    }
    reader.readAsArrayBuffer(file);
  } else {
    alert("File, footer or preset invalid");
  }
}

function processSelection(evt) {
  document.getElementById('pid').value = evt.target.value.substr(10, 2) + evt.target.value.substr(8, 2);
}

// https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input
// Restricts input for the given textbox to the given inputFilter.
function...