OnSubmit method to prepare data to be sent on an action - javascript

This would be a follow-up of question [A form's “action” and “onsubmit”: Which executes first?][1]
where it's concluded that onSubmit runs first, and then the action to submit a form is done.
I would like to compose my onSubmit method to clean up the POST submission that will be sent; is there a way to modify said POST message that will be sent to the server, not by changing the values of the fields, but rather the composition of it?
As an example, my form consists of two fields, name and surname. The submit action ends up sending a POST body like:
name=John&surname=Doe
But I'd like the POST body to be
fullname=John_Doe
I am actually stuck without an idea of how to approach this problem, so any hint on where to look for documentation about this is appreciated - I don't want to leech the code that will do it, but some hint of where to start.
Thanks!
[1]: A form's "action" and "onsubmit": Which executes first?_

You can achieve this by modifying form-data before sending the request.
But you need to send the request yourself.
const form = document.querySelector("form");
form.addEventListener("submit", e => {
e.preventDefault();
let preparedData = new FormData(form);
preparedData.append(
"fullName",
`${preparedData.get("firstName")} ${preparedData.get("lastName")}`
);
console.log("Fullname: " + preparedData.get("fullName"));
var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(preparedData);
});
Example:
https://stackblitz.com/edit/js-yia2yg?file=index.js

To stop the form action you can call a onSubmit method:
<form action="/action_page.php" onsubmit="myFunction()">
Enter first name: <input type="text" name="fname">
Enter last name: <input type="text" name="lname">
<input type="submit" value="Submit">
</form>
function myFunction(evt) {
evt.preventDefault();
let data = {
fullname: //place the data you need to send here
};
fetch("/post/data/here", {
method: "POST",
body: JSON.stringify(data)
}).then(res => {
console.log("Request complete! response:", res);
});
};

Related

Form is not submited after form submit button click with javascript event listener

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',
]
)
]
);
}
}
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>
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
});
}
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

Unable to render inner HTML for AJAX form with Node.js

I've coded a straightforward form which submits via Mailchimp's API to a waiting list.
This works, and the form upon submission doesn't reload the page (good), and submits the request to the server to store in Mailchimp (also good).
However, I'm wanting to update the inner HTML of the form to reflect whether the form was submitted successfully or not, without reloading the page. I've followed other questions but can't get it to work.
Here's my code at present:
Form -
<form id="early-access" class="hero-form " action="early-access" method="POST">
<input type="email" name="email" placeholder="Enter your email">
<button class="cta-button" type="submit" name="button">Get early access</button>
</form>
My AJAX jQuery code -
<script type="text/javascript">
$("#early-access").submit(function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: form.serialize(),
done: function(data)
{
alert(data);
}
});
});
</script>
EDIT: Now adding my Early Access POST code. Noting that the form successfully adds the user to my waiting list..
module.exports = (req, res) => {
const email = req.body.email;
const data = {
members: [{
email_address: email,
status: "subscribed"
}]
};
const jsonData = JSON.stringify(data);
const url = process.env.MAILCHIMPURL;
const options = {
method: "POST",
auth: process.env.MAILCHIMPAPIKEY
};
const request = https.request(url, options, function(response) {
response.on("data", function(data) {
// console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end();
};
Also for reference - my backend is Node.js, not PHP.. Not sure if that impacts things with jQuery either.
The 'alert' in the success / error call in my AJAX isn't working, neither is my console.log. There's no mention of the request in my log. If the alert was working, I'd assume that I could just use .html to update the #early-access form.. I've tried that already but no luck unfortunately.
EDIT: In my console, after perhaps 2 minutes (roughly) after successfully submitting my form I get a 'error' alert pop up, and my console shows a 'Failed to load resource: The network connection was lost' error.
If anyone could advise, that'd be appreciated!

Prevent Form Resubmission With Javascript After Ajax Post (No Redirect)

A similar question has been asked before with regards to POSTing a form without redirecting, but none of the solutions actually have worked in my case, and those answers are about 8 years old. In my situation, I have a simple form that submits a few text fields to a URL using Ajax:
<form id="f">
<input type="text" name="name">
<button type="submit" form="f">Submit</button>
</form>
<script>
$("#f").submit(function() {
var arr = $("#f").serializeArray();
var name = arr[0].value;
var ajaxConfig = {type: "post", url: "submit_form", data: {name: name}};
$.ajax(ajaxConfig);
return false;
});
</script>
This works perfectly as far as submitting the data to the server goes. The POST request is sent and received, but whenever the page is visited again the browser will attempt to resubmit the data for no reason (Why?). This results in an invalid request being sent to my sites homepage and an HTTP 405 "Page not working error". The page will work again upon subsequent requests. This happens in both Chrome and Safari.
I've tried the history.replaceState(null, null, location.href);, which others have stated works for them, but for me it did not work, neither in Chrome or Safari.
Post/Redirect/Get is not a viable solution as I am wanting to stay on the same page. Please do not recommend that I use the Post/Redirect/Get solution as it does not fit my use case.
One solution is to not use the default "submit" functionality, and simply have the form be submitted through a custom javascript function and click handler:
<form id="f">
<input type="text" name="name">
<button form="f" onmousedown='submit()'>Submit</button>
</form>
<script>
function submit() {
var arr = $("#f").serializeArray();
var name = arr[0].value;
var ajaxConfig = {type: "post", url: "submit_form", data: {name: name}};
$.ajax(ajaxConfig);
});
</script>
But this answer seems to be hacky. Is there a way to submit using canonical form submit buttons without required resubmission upon the next page visit? Furthermore, why would forms be implemented such that they are resubmitted for no reason on page revisiting, even after it's been confirmed they've been submitted once before?
Edit:
Using preventDefault() does not do anything:
<script>
$("#f").submit(function(e) {
e.preventDefault();
var arr = $("#f").serializeArray();
var name = arr[0].value;
var ajaxConfig = {type: "post", url: "submit_form", data: {name: name}};
$.ajax(ajaxConfig);
return false;
});
</script>
You need to run preventDefault() on your form submission event.
It prevents the default action of the form - as form is supposed to reload your page every time it is submitted.
Read more at official documentation
<script>
$("#f").submit(function(e) {
e.preventDefault();
var arr = $("#f").serializeArray();
var name = arr[0].value;
var ajaxConfig = {type: "post", url: "submit_form", data: {name: name}};
$.ajax(ajaxConfig);
return false;
});
</script>

how to ignore redirect after login and redirect another page

I wonder how do I ignore a diversion from the server after performing a login and then redirects you to another page, have researched a lot about it and could not find something that really worked, already tried to use the window.location, window.location .href, window.location.assign but none works.
The best I could until now was only open a new page using window.open to the site that I want, but I keep getting redirected.
<HTML>
<HEAD>
<TITLE>ECORI LOGIN</TITLE>
<script language="JavaScript" type="text/javascript">
window.onbeforeunload = function(){
window.open("mypage.html");
}
</script>
<BODY>
<FORM action="http://mylogin.com/security/jspring_security_check" method="post" >
Usuario: <INPUT type="text" name="j_username"><BR>
Senha: <INPUT type="password" name="j_password"><BR>
<INPUT type="submit" value="Login" onclick="function">
</FORM>
</BODY>
</HTML>
All help is welcome and sorry for my english.
Thank so much!
I saw one of the comments suggested using AJAX, this is just another way of doing this. xhr is basically AJAX but without the bells and whistles. Honestly you should use AJAX. It is much cleaner.
function doPost(url, method, callback, data){
xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.send(data);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if(typeof callback() != 'undefined')
callback(xhr.responseText);
}
}
}
function handleLogin(respObj){
console.log(respObj);
//Do what needs to be done here after form submit...
}
$(function(){
$("form input:button").on('click', function(e){
formid = "loginForm";
var form = document.getElementById(formid);
var formdata = new FormData(form);
doPost("http://mylogin.com/security/jspring_security_check", "post", "handleLogin", formdata);
});
});
And I changed your form to this:
<FORM method="post" id="loginForm">
Usuario: <INPUT type="text" name="j_username"><BR>
Senha: <INPUT type="password" name="j_password"><BR>
<INPUT type="button" value="Login">
</FORM>
If you want to use AJAX you would use this instead of doPost
formid = "loginForm";
var form = document.getElementById(formid);
var formdata = new FormData(form);
$.ajax({
url: 'http://mylogin.com/security/jspring_security_check',
data: formdata,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
handleLogin(data);
}
});
The act of submitting a form is basically telling the browser to leave the page, send the form data to wherever action is, ending up in that page. You have 2 options though:
Intercept your login using JavaScript and instead use AJAX to do the login. Once the server responds to your AJAX request, depending on the response, you can then redirect the user to wherever you want using JavaScript.
You appear to use Java. I believe you can change the configuration to redirect you to your desired page once login succeeds. It's a safer approach than hacking a JS solution. It's like
form -(submit)-> jspring_security_check -(server redirect)-> final destination

Ajax: form data not passing on to e-mail

This is my form:
<form id='forma' action="index1.php" method="post">
<input name="name1" type="text">
<input class="s_submit" value="ЗАКАЗАТЬ" type="button" onclick="send1()">
</form>
This is my javascript:
function send1(){
$('#forma').submit(function(event){
var formData = {
'fio' : $('input[name=name1]').val(),
};
$.ajax({
type : 'post',
url : 'index1.php',
data : formData,
dataType : 'json',
encode : true
})
.done(function(data) {
console.log(data);
});
event.preventDefault();
});
}
This is my index1.php:
$fio=$_POST['name1'];
$mail_to="_______my_email_________";
$msg="Your name is: $fio
mail($mail_to, $thm, $msg, $headers);
On my e-mail only "Your name is:" message is sent, without the name someone submitted. Code works as expected when I set input type to submit and get rid entirely of send1() function. But input must be the button type and never go to another page on press. I suppose I should get rid of some of variable assignments, but which ones?
Your variable in the POST data is defined in formData object with the key of fio. Your PHP to retrieve it should therefore be:
$fio = $_POST['fio'];
On the form submission, you are overriding the actual form (containing your text field) from being submitted, and submitting your own formData object.
You can quite easily get the data from your HTML form by using
$("#forma").serializeArray()

Categories