0

I have an HTML form which hits this endpoint. It sends data, but I don't want the page to refresh once sending the data. is this possible?

im not sure what the best solution is, there is no preventdefault in nodejs, but I don't want to redirect/refresh the same page

const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");

const app = express();


app.use(bodyParser.urlencoded({ extended: true }))
app.use(express.static("public"));

const PORT = process.env.PORT || 5001;

app.get("/", (req, res) => {
  res.sendFile("index.html", { root: __dirname });
});

app.post("/rumi", (req, res) => {
  console.log(res.req.body);

  res.json({ status: "ok" });


});

app.get("/rumi", (req, res) => {
  res.sendFile("index2.html", { root: __dirname });
});

app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`);
});


Here is the html :

<!DOCTYPE html>
<html>

<head>
  <meta name="viewport"
        content="initial-scale=1.0, user-scalable=no" />
  <meta charset="UTF-8" />
  <title>Drawing Tools</title>

  <style type="text/css">
    #map,
    html,
    body {
      padding: 0;
      margin: 0;
      height: 100%;
    }

    #panel {
      width: 200px;
      font-family: Arial, sans-serif;
      font-size: 13px;
      float: right;
      margin: 10px;
    }

    #color-palette {
      clear: both;
    }

    .color-button {
      width: 14px;
      height: 14px;
      font-size: 0;
      margin: 2px;
      float: left;
      cursor: pointer;
    }

    #delete-button {
      margin-top: 5px;
    }
  </style>

  <script src="/js/script.js"></script>

  <script>
    function submitRumiForm(e) {
      e.preventDefault();
      var formData = new FormData(document.getElementById("rumiForm"));
      var options = {
        body: formData,
        method: "POST"
      }
      fetch("/rumi", options).then(function(data) {
        console.log("post successful");
      }).catch(function(err) {
        console.log(err);
      })
    }

    var el = document.getElementById("stair-button")
    if (el) {
      el.addEventListener("click", submitRumiForm);
    }
  </script>
</head>

<body>
  <div id="panel">
    <div id="color-palette"></div>
    <div>
      <button id="delete-button">Delete Selected Shape</button>
      <button id="delete-all-button">Delete All Shapes</button>
    </div>
    <form id="rumiForm"
          action="/rumi"
          method="POST">
      <div>
        <h3>Elements</h3>
      </div>
      <button type="submit"
              name="stairs"
              value="clicked"
              id="stair-button"
              onclick="console.log('hi')">
        <img src="./images/stair.png" />
      </button>
      <button type="submit"
              name="ramp"
              value="clicked"
              id="ramp-button">
        <img src="./images/ramp.png" />
      </button>
      <button type="submit"
              name="exit"
              value="clicked"
              id="exit-button"><img src="./images/exit.png" /></button>
      <button type="submit"
              name="narrow"
              value="clicked"
              id="narrow-button">
        <img src="./images/narrow.png" />
      </button>
      <button type="submit"
              name="wide"
              value="clicked"
              id="wide-button"><img src="./images/wide.png" /></button>
      <button type="submit"
              name="construction"
              value="clicked"
              id="construction-button">
        <img src="./images/construction.png" />
      </button>
    </form>
  </div>
  <div id="map"></div>
</body>

</html>

I have an HTML form which hits this endpoint. It sends data, but I don't want the page to refresh once sending the data. is this possible?

im not sure what the best solution is, there is no preventdefault in nodejs, but I don't want to redirect/refresh the same page

This happens when i tried the solution

This happens after a while

Hussein Nagri
  • 21
  • 1
  • 4

2 Answers2

0

As this is browser specific behaviour, this has to be done on the client side via JavaScript & using prevent default with the form, see here.

If you simply don't want to refresh to that specific page, you can do a redirect in express, so after they submit the form, they are directed away from it, see here.

Mjr
  • 96
  • 1
  • 3
0

If you don't want the page to reload, then you need to send the POST with Javascript from the browser using an Ajax call rather than letting the browser post the form automaticallyl. Anytime the browser posts the form automatically, it will display the form response in the browser window. So, if you don't want that, you have to take control (in the browser) and submit the form with your own Javascript so then you can control what happens with the result.

Add an identifier to your form:

<form id="rumiForm" action="/rumi" method="POST">

Add this script after the form in your HTML:

<script>

function submitRumiForm(e) {
   e.preventDefault();
   var formData = new FormData(document.getElementById("rumiForm"));
   var options = {body: formData, method: "POST"}
   fetch("/rumi", options).then(function(response) {
       return response.json();
   }).then(function(data) {
       // have the JSON response from the POST operation here
       console.log(data);
   }).catch(function(err) {
       console.log(err);
   })
}

document.getElementById("stair-button").addEventListener("click", submitRumiForm);

</script>

Change this form item from this:

  <button type="submit"
          name="stairs"
          value="clicked"
          id="stair-button"
          onclick="console.log('hi')">

to this:

  <button type="submit"
          name="stairs"
          value="clicked"
          id="stair-button"
  >
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • i tried your solution but look at the picture i attached, thats what happened – Hussein Nagri Nov 27 '19 at 02:06
  • @HusseinNagri - I have made some edits to the solution in my answer, but what you show in your screenshot is a server-side problem. Not sure what to do with that. – jfriend00 Nov 27 '19 at 02:12
  • your code worked, but the post request still times out after a bit, is there a reason why? I added another pic – Hussein Nagri Nov 27 '19 at 02:27
  • @HusseinNagri - You need to send a response of some kind on the server - otherwise the browser is still waiting for a response from the ajax call. If you don't have anything particular to send, the just do `res.json({status: "ok"});`. I don't know what `res.off()` is or what you intended with that. I don't see that as an Express method. I would replace that with something like `res.json({status: "ok"});`. – jfriend00 Nov 27 '19 at 02:31
  • the issue when i do ```res.json({status: "ok"});``` is that the page will be now show that – Hussein Nagri Nov 27 '19 at 02:34
  • @HusseinNagri - well you need the preventDefault. – jfriend00 Nov 27 '19 at 02:36
  • yeah thats added in as well, i can re update the code for you – Hussein Nagri Nov 27 '19 at 02:37
  • @HusseinNagri - You have to put the ` – jfriend00 Nov 27 '19 at 02:46
  • That works, but the response doesnt return anything unfortunately – Hussein Nagri Nov 27 '19 at 04:43
  • @HusseinNagri - OK, progress. See how I edited the client-side `fetch()` call to actually read the JSON response. Feel free to examine [some doc for `fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) at any time to learn how it works. – jfriend00 Nov 27 '19 at 04:52
  • ``` var formData = new FormData(document.getElementById("rumiForm")); ``` what does this do? i dont think this seems to be getting any data – Hussein Nagri Nov 27 '19 at 05:49
  • hey man, do you think you can explain the script more. i dont think it's sending anything to /rumi – Hussein Nagri Nov 27 '19 at 06:14
  • @HusseinNagri - The latest code you show in your question, has the ` – jfriend00 Nov 27 '19 at 06:23
  • @HusseinNagri - `var formData = new FormData(document.getElementById("rumiForm"))` gets the data out of the form and puts it into a `FormData` object. In [this reference page on fetch()](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), search for `const form = new FormData(document.getElementById('login-form'));` and you will see an identical example to what I suggested your code do (obviously the form id and URL are different, but otherwise the `fetch()` arguments are identical. – jfriend00 Nov 27 '19 at 06:25