0

I am trying to stop the page from refreshing when submitting a form by using this:

window.addEventListener("load", function () {
  let settings_form = document.getElementById("settings_form");

  // handle form submit
  settings_form.addEventListener("submit", function (e) {
    e.preventDefault(); // before the code
    save_settings();

    // Should be triggered on form submit
    console.log("hi");
    return false;
  });
});

But it does not work. If I comment the save_settings method the page won't reload. Obviously, I need that method.

function save_settings() {
  //   let form = document.getElementById("settings_form");
  let json_data = toJSONstring(settings_form);
  console.log(json_data);
  post_data("api/settings/change", json_data).then((send_response) => {
    console.log(send_response);
    conn_status = 1;
    // logs to page
    // get_settings() // update interface with newer settings
    get_info();
  });
}

I don't know which function makes e.preventDefault(); to not work.

For more context:

// parse form data into json
function toJSONstring(form) {
  let object = {};
  console.log(form);
  let formData = new FormData(form);
  formData.forEach((value, key) => {
    // Reflect.has in favor of: object.hasOwnProperty(key)
    if (!Reflect.has(object, key)) {
      object[key] = value;
      return;
    }
    if (!Array.isArray(object[key])) {
      object[key] = [object[key]];
    }
    object[key].push(value);
  });
  console.log(JSON.stringify(object));
  return JSON.stringify(object);
}

// send/post json
async function post_data(api_path, json_data) {
  let post_url = ROOT_URL + api_path;
  const response = await fetch(post_url, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: json_data,
  });
  //check
  if (!response.ok) {
    conn_status = 0;
    const message = `An error has occured: ${response.status}`;
    throw new Error(message);
  }
  return await response.json();
}
<form id="settings_form" class="settings_form">
  <label for="wifi_ssid">Change SSID</label>
  <input type="text" name="wifi_ssid" id="wifi_ssid" />
  <label for="wifi_pass">Change Password</label>
  <input type="text" name="wifi_pass" id="wifi_pass" />

  <label for="ap_ip">Change IP Address</label>
  <input type="text" name="ap_ip" list="ap_ip" />
  <datalist id="ap_ip">
      <option>192.168.100.20</option>
  </datalist>
  <input type="button" value="Save Settings" id="submit_btn">
</form>

I have also tried listening to the click event on the button:

window.addEventListener("load", function () {
  let button = document.getElementById("submit_btn");

  // handle form submit
  button.addEventListener("click", function (e) {
    e.preventDefault(); // before the code
    save_settings();

    // Should be triggered on form submit
    console.log("hi");
    return false;
  });
});

Later Edit:

I am running a local mock-up JSON server in order to test my code.

I've tried the code here: https://jsbin.com/xogozovawe/1/edit?html,js,output and it works.

Might this be the local server's fault ?

biberman
  • 5,606
  • 4
  • 11
  • 35
  • try to use input type=submit instead of button – Sfili_81 Aug 31 '21 at 13:20
  • Using `` has the same behavior. – George Florian Aug 31 '21 at 13:21
  • Duplicate question - see the [answer](https://stackoverflow.com/a/45634140/16593275) – wowandy Aug 31 '21 at 13:22
  • 1
    https://jsbin.com/humayatepi/1/edit?html,js,output — I can't reproduce the problem. – Quentin Aug 31 '21 at 13:22
  • @wowandy — That says "Use event.preventDefault()" which this code does already. – Quentin Aug 31 '21 at 13:23
  • @Quentin As I said in the OP, if I comment out `save_settings()` then `e.preventDefault();` works fine for me too. The problem has to do with the `save_setting()` method or the methods inside it. But I can't figure out what is wrong. – George Florian Aug 31 '21 at 13:29
  • @GeorgeFlorian I read your question. But you apparently did not notice the difference between the answer and the question. Try to handle the click event, not the submit – wowandy Aug 31 '21 at 13:35
  • @wowandy And in that answer it says: `Prevent default form submission when button is clicked. Note that this is not the ideal solution because you should be in fact listening to the submit event, not the button click event:`. Even so, I have changed to code to listen to a `click` event and it still does not work. – George Florian Aug 31 '21 at 13:39
  • Also, if you prevent the default submit behavior you don't need a submit button, use a common button – wowandy Aug 31 '21 at 13:40
  • Also, you can try `
    – wowandy Aug 31 '21 at 13:43
  • "Might this be the local server's fault ?" — It *really* shouldn't be (unless the local server is failing to serve up the local JS at all — have you checked (with the Network tab) that your JS URL isn't 404ing and has the right JS in it with the right Content-Type?) since you hit `e.preventDefault()` before doing anything that touches the server. – Quentin Aug 31 '21 at 13:48
  • @wowandy — "if you prevent the default submit behavior you don't need a submit button" — Noooo… https://en.wikipedia.org/wiki/Unobtrusive_JavaScript – Quentin Aug 31 '21 at 13:48
  • I'd also look at adding a break point to the JS and stepping through it to see if there's anything there which explicitly triggers browser navigation. – Quentin Aug 31 '21 at 13:49
  • @Quentin Under Network tab it says: `script.js Status: 304 Type: script Initiator: index.html Time 2ms`. It looks fine. – George Florian Aug 31 '21 at 13:53
  • @Quentin I think that this is outdated for a long time, now there are very few services that can work without javascript. Check out what Google [forms](https://accounts.google.com/signin/v2/identifier?flowName=GlifWebSignIn&flowEntry=ServiceLogin) look like, they don't even use a form tag, let alone a submit button – wowandy Aug 31 '21 at 13:55
  • @GeorgeFlorian `save_settings` function working without errors? – wowandy Aug 31 '21 at 13:56
  • @wowandy Yes, `save_settings()` works fine. All the code works without errors. – George Florian Aug 31 '21 at 14:00
  • @GeorgeFlorian check the headers that the server sends in the response, it can refresh the page or make a redirect. Or try without request – wowandy Aug 31 '21 at 14:09
  • @wowandy How do I do that ? Also, I found this: https://github.com/typicode/json-server/issues/1106 I think that the setup of my VSCode is the one at fault right here. Beside JSON Server, I use LiveServer to launch index.html. The JSON Server launches at `http://localhost:3000`, but LiveServer launches at `http://127.0.0.1:5501/index.html` – George Florian Aug 31 '21 at 14:23
  • @GeorgeFlorian If the problem is not in the LiveServer, then you can see the headers using the [cURL](https://github.com/curl/curl) request in the command line. Something like this: `curl -v -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d 'put json here' http://URL/` – wowandy Aug 31 '21 at 14:35
  • @wowandy the problem came from the combination between LiveServer and JSON Server. From the moment I've served the static files(html,css) with the JSON Server everything worked perfectly. – George Florian Aug 31 '21 at 14:47
  • @wowandy Also, It seems that when preventDefault() is used on the `submit` event, you need to actually have a `submit` button in the form, otherwise it won't work. But the `click` event works with whatever button you decide to use. – George Florian Aug 31 '21 at 14:52

0 Answers0