javascripthtmlnode.jsfrontendejs

how to make a button submit the form value to the server but not refresh the page?


I've made an html button which gets triggered when I change the select tag's value. I just want to send information to the server and retrieve the corresponding data back, and use it on the same page I'm on. But as soon as I trigger the button, it either doesn't submit it if I set type = 'button' or sends the data but refresh the page when I set the type = 'submit'. refreshing the page is not something I really want, so how can I set it to just receive and process the data instead of refreshing the page too.

Here's my button's code-

<form id="selectedScript">
      <label for="script">Choose a script:</label>
      <select name="script" id="script">
        <option value="main" selected>Main</option>
        <option value="main2">Main2</option>
      </select>
      <button hidden form="selectedScript" formaction="/playground/scriptBtn" formmethod="post" formtarget="_self" id="scriptBtn" type="button"></button>
    </form>

here's my JS script file's code -

selectedScript.addEventListener("change", () => {
  if (
    confirm(
      "Are you sure you want to change the script? This will clear the current text from input box"
    ) == true
  ) {
    inputBox.value = "";
    outputBox.value = "";
    document.getElementById('scriptBtn').click(); //this is where button gets triggered.
  }
});

here's the code from behind, Right now I am not sending any data back, but just consoling the request object, to see everything works. -

router.route('/playground/scriptBtn')
.post((req, res) =>{
    console.log(req)
    res.end()
})

also note that the button is actually in /playground.ejs file and is making action on /playground/scriptBtn url. So when it refreshes, it goes to a url which doesn't render any html but registers a post request on it.

Thanks in advance.


Solution

  • You don't need a button to achieve this. You can call an ajax call from inside the change event listener.

    selectedScript.addEventListener("change", () => {
      if (confirm("Are you sure you want to change the script? This will clear the current text from input box") == true) {
        callAPI();
      }
    });
    function callAPI() {
      var formData = new FormData();
      formData.append("feild1", "feild1 value");
      formData.append("feild2", "feild2 value");
    
      var xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          // this.response => this is the API response you can process and use
        }
      };
      xhttp.open("POST", "/playground/scriptBtn", true);
      xhttp.send(formData);
    }
    <form id="selectedScript">
      <label for="script">Choose a script:</label>
      <select name="script" id="script">
        <option value="main" selected>Main</option>
        <option value="main2">Main2</option>
      </select>
      <button hidden form="selectedScript" formaction="/playground/scriptBtn" formmethod="post" formtarget="_self" id="scriptBtn" type="button" onclick="loadDoc()"></button>
    </form>
    
    <p id="demo"></p>

    If you want to call a GET API just change the POST to GET,

    selectedScript.addEventListener("change", () => {
      if (confirm("Are you sure you want to change the script? This will clear the current text from input box") == true) {
        callAPI();
      }
    });
    function callAPI() {
      var xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          // this.response => this is the API response you can process and use
        }
      };
      xhttp.open("GET", "/playground/scriptBtn?field1=value1&field2=value2", true);
      xhttp.send();
    }
    <form id="selectedScript">
      <label for="script">Choose a script:</label>
      <select name="script" id="script">
        <option value="main" selected>Main</option>
        <option value="main2">Main2</option>
      </select>
      <button hidden form="selectedScript" formaction="/playground/scriptBtn" formmethod="post" formtarget="_self" id="scriptBtn" type="button" onclick="loadDoc()"></button>
    </form>
    
    <p id="demo"></p>


    If you need to use a Fetch API. Find full documentation here.

    selectedScript.addEventListener("change", () => {
      if (confirm("Are you sure you want to change the script? This will clear the current text from input box") == true) {
        callAPI();
      }
    });
    async function callAPI() {
      var formData = new FormData();
      formData.append("feild1", "feild1 value");
      formData.append("feild2", "feild2 value");
      const response = await fetch("/playground/scriptBtn", {
        method: "POST", // *GET, POST, PUT, DELETE, etc.
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: formData
      });
      return response.json();
    }
    <form id="selectedScript">
      <label for="script">Choose a script:</label>
      <select name="script" id="script">
        <option value="main" selected>Main</option>
        <option value="main2">Main2</option>
      </select>
      <button hidden form="selectedScript" formaction="/playground/scriptBtn" formmethod="post" formtarget="_self" id="scriptBtn" type="button" onclick="loadDoc()"></button>
    </form>
    
    <p id="demo"></p>