Why is HTML validation not working in Electron?

Viewed 281

I've searched for this for a while. I have an Electron (version 13.2.2, Node v14.17.3, Chrome 92) application that I want to add some validations to, in one of the simple forms I have. The code below is part of the HTML file that is loaded in a window. The results are passed through IPC communication and everything else Electron-related works fine. Console logs don't show anything undefined or any other issue at all. When I open the HTML file directly in Chrome, for instance, I get the required name working as advertised and also the regex pattern being applied to the input in the year field. But in my Electron window, I can still save objects without any validation being triggered. Searching on GitHub I found an issue that is somewhat similar (although I'm not facing any other issues whatsoever, this is a working app) but it mentions it's been closed as fixed (https://github.com/electron/electron/issues/1043). What am I missing to get the required and pattern validations to work?

This is the HTML form:

    <section>
      <form action="#" method="POST" id="add-new-pattern-form">
        <label for="pattern-name">Name:</label>
        <input id="pattern-name" type="text" name="pattern-name" required />
        <p></p>
        <div id="cover-image"></div>
        <p></p>
        <button type="button" id="open-cover-image">Add Cover Image</button>
        <p></p>
        <label for="company-name">Company:</label>
        <input id="company-name" type="text" name="company-name" />
        <p></p>
        <label for="year">Year:</label>
        <input id="year" type="text" name="year" pattern="^\d{4}$" />
        <p></p>
        <label for="notes">Notes:</label>
        <textarea id="notes" name="notes" style="resize: true"></textarea>
        <p></p>
        <div id="additional-images"></div>
        <p></p>
        <button type="button" id="add-images">Add Images</button>
        <p></p>
        <input
          id="submit-new-pattern-button"
          type="submit"
          value="Save Pattern"
        />
      </form>
    </section>

This is the usage in the renderer:

submitNewPatternButton.addEventListener("click", () => {
  console.log("addnewrenderer - click submit new pattern button");
  let pattern = createPatternObjectFromInputs();
  ipcRenderer.send("submit-new-pattern-button-clicked", pattern);
});

Another relevant piece of data is the window setup in the main process:

const createNewWindow = (fileLocation, id) => {
  let x, y;
  const currentWindow = BrowserWindow.getFocusedWindow();

  // When we already have a window we open a new one to the right and down of the current one
  if (currentWindow) {
    const [currentWindowX, currentWindowY] = currentWindow.getPosition();
    x = currentWindowX + 20;
    y = currentWindowY + 20;
  }

  let newWindow = new BrowserWindow({
    x,
    y,
    webPreferences: {
      preload: path.join(__dirname, "preload.js"),
    },
    show: false,
  });

  newWindow.loadFile(fileLocation);

  newWindow.once("ready-to-show", () => {
    newWindow.show();
  });

  // Necessary otherwise the HTML default title is always used
  newWindow.on("page-title-updated", (event) => {
    event.preventDefault();
  });

  newWindow.on("close", () => {
    windows.delete(id);
    newWindow = null;
  });

  windows.set(id, newWindow);
  console.log("main - finished new window creation for id: " + id);

  return newWindow;
};

One final note I'll add is that while refactoring code to use preload.js and set contextIsolation: true and nodeIntegration: false (the default values after Electron 12 and as per security best practices) I noticed that when I have an error in the page the validations work.

For instance, let's say I introduce a deliberate error in my renderer such as:

const x;
x.doSomething;

In this case, the validations work! Obviously, nothing else does :)

1 Answers

Note that the submit event fires on the element itself, and not on any <button> or <input type="submit"> inside it. However, the SubmitEvent which is sent to indicate the form's submit action has been triggered includes a submitter property, which is the button that was invoked to trigger the submit request.

MDN Docs

The form validation is tied to the submit event, which fires on the form element, thus listening for a click event on the submit button won't trigger it.

Instead, try listening to the submit event fired by the form, like so:

const formElement = document.getElementById('myForm');
formElement.addEventListener('submit', () => {
    // Handle form submission
});
Related