0

I have created a form. Everything works perfect with javascript but the main problem is that my form is not being submited and sent after I click the submit button. If I comment out the event.preventDefault(); than after submit button is clicked, it refresh the page and submits the form. Do you have any idea how can I prevent the page to be refreshed and submit the form after the submit button is clicked?

Code bellow. Thanks in advance.

HTML

 <form action="" method="post" id="formId">
                <p class="email">Email<span style="color:red">*</span><br/>
                <input type="email" placeholder="Enter your email" name="users_email" size="40" required>
                <input type="submit" class="btn" name="send-form" value="ODOBERAŤ NOVINKY">
                </p>
<p id="opTag" class="textove"></p>
                </form>

JS

var form = document.getElementById("formId");
var opTag = document.getElementById("opTag");
      function submitForm(event) {
         event.preventDefault();
         form.style.display = "none";
         opTag.innerHTML = "Thank you. Your form has been sent.";
         var expDate = new Date();
         expDate.setTime(expDate.getTime() + (24 * 60 * 60 * 1000 * 1000));
         $.cookie("hidepopup", "hide", { path: '/', expires: expDate });
      }
      form.addEventListener('submit', submitForm);

UPDATE: After the form is submitted I need to run this php to subscribe to mailchimp API.

PHP code bellow

function send_mail() {

  // if the submit button is clicked, add to subscriber
  if ( isset( $_POST['send-form'] ) ) {


      $apiKey = 'xxxxxxx';
      $users_email = $_POST['users_email']; // the user email we are going to subscribe
      $list_id = 'xxxxxxx'; // List / Audience ID
      $server = explode( '-', $apiKey );


      $url = 'https://' . $server[1] . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/';

      $response = wp_remote_post(
    $url,
    [
        'method'      => 'POST',
        'data_format' => 'body',
        'timeout'     => 45,
        'headers'     => [
            'Authorization' => 'apikey ' . $apiKey,
            'Content-Type'  => 'application/json; charset=utf-8',
        ],
        'body'        => json_encode(
            [
                'email_address' => $users_email,//email
                'status'        => 'subscribed',
                'status_if_new' => 'subscribed',
            ]
        )
    ]
);

  }
}
Lubo Masura
  • 1,034
  • 6
  • 20

3 Answers3

1

event.preventDefault(); prevents the default behaviour from happening so in your case using it on the form would prevent the normal process from happening i.e form is POSTed and the page is refreshed.

Since you are using event.preventDefault(); you will need to write some additional JS to grab your form input and do something with it.

I have wrote some example JS for something similar to your case.

  var form = document.getElementById("formId");
    var opTag = document.getElementById("opTag");

    function submitForm(event) {
        event.preventDefault();
        console.log("form submitted"); // logs "form submitted" to the console when submit button is clicked.
        opTag.innerHTML = "Thank you. Your form has been sent."; // Gives user a message

        // You want to do something with your form data here
        // For example grab your input, clear it and do something with it...
        let inputField = document.querySelector('.email-field');
        let inputValue = inputField.value; // get the value
        inputField.value = ""; // clear the field once submit is clicked

        console.log(inputValue) // Logs the value entered into email fields after submit is clicked


        // Send a ajax post request to somewhere
        // Create and Send the request
        var fetch_status;
        fetch('https://jsonplaceholder.typicode.com/users', {
            method: "POST",
            // Set the headers
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            // Set the post data
            body: JSON.stringify({
                email : inputValue,
            })
        })
            .then(function (response) {
                // Save the response status in a variable to use later.
                fetch_status = response.status;
                // Handle success
                // eg. Convert the response to JSON and return
                return response.json();
            })
            .then(function (json) {
                // Check if the response were success
                if (fetch_status == 201) {
                    // Use the converted JSON
                    console.log(json);
                }
            })
            .catch(function (error){
                // Catch errors
                console.log(error);
            });
    }
    form.addEventListener('submit', submitForm);
<form action="" method="post" id="formId">
    <p class="email">Email<span style="color:red">*</span><br/>
        <input class="email-field" type="email" placeholder="Enter your email" name="users_email" size="40" required>
        <input type="submit" class="btn" name="send-form" value="ODOBERAŤ NOVINKY">
    </p>
    <p id="opTag" class="textove"></p>
</form>
  • Hello Shane, thanks for the answer. I get this error in console. Cannot read properties of null (reading 'value') at HTMLFormElement.submitForm. It can not read email value. – Lubo Masura Jan 16 '23 at 15:00
  • I'm guessing your JS is being run before your HTML is rendered. Try wrapping your JS is a `addEventListener('DOMContentLoaded', () => {});` – Shane Muirhead Jan 16 '23 at 15:03
  • And how about the name="send-form" - this is running a php and with ajax it seems it does not work now. How can we solve it to run a php once ajax form is submited? – Lubo Masura Jan 16 '23 at 15:07
  • Please explain what you are intending this form to do etc and what you are requiring further. If you have a PHP script this form needs to send data to please update your question to include everything you req – Shane Muirhead Jan 16 '23 at 15:10
  • 1
    I have updated my question. At the bottom you could find the php. – Lubo Masura Jan 16 '23 at 15:45
  • Do you mean to wrap the whole function do DOMContentLoaded or just the value? – Lubo Masura Jan 16 '23 at 15:50
  • @LuboMasura to post to php script you will need to change the url in the fetch to point to your php script. then in php you can use the `$_REQUEST` or `$_POST` globals to check and do something with your POSTed data. – Shane Muirhead Jan 16 '23 at 16:10
  • You mean https://jsonplaceholder.typicode.com/user this url to my php file for example domain.com/send.php? – Lubo Masura Jan 16 '23 at 16:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251175/discussion-between-shane-muirhead-and-lubo-masura). – Shane Muirhead Jan 16 '23 at 16:13
  • Im in chat. Thank you – Lubo Masura Jan 16 '23 at 16:25
0

Your problem should be caused from action attribute of form tag. If you leave it empty the default behavior is to refresh the current page. To fix it, you have to put inside action attribute the backend page that must handle the form request.

Note that with the above suggested solution, you will receive the response html page that will override your current page.If you want keep the current page you have to use ajax and call your server page with ajax. Here an example with php in mind: How to submit this form using AJAX without jQuery but pure Javascript

Nick
  • 1,439
  • 2
  • 15
  • 28
0

You could use fetch to perform an AJAX request.

function submitForm(event) {
    event.preventDefault();
    // ...
    fetch(form.action, {method: form.method, body: new FormData(form)}).then(res => {
        // use response here...
        // e.g. res.json() returns a Promise resolving to the result of parsing the body as JSON
    });
}
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
  • @LuboMasura What do you mean? I have provided code in my answer that you can easily adapt. – Unmitigated Jan 16 '23 at 14:46
  • That I dont know exactly how to adapt. I mean if you could add the answer with the full code. I would appreciate it. – Lubo Masura Jan 16 '23 at 14:47
  • @LuboMasura Just using `fetch(form.action, {method: form.method, body: new FormData(form)})` is sufficient to emulate submitting the form, without using the returned response. – Unmitigated Jan 16 '23 at 14:49