Send multiple input using FormData - javascript

I have this form:
<form action="#" id="form-add">
<input type="text" name="test[]" value="hello">
<input type="text" name="test[]" value="bye">
<button type="submit"><Submit/button>
</form>
And I want, when the user submits, this information to be sent via AJAX using FormData like this:
$('form-add').submit(function (event)
{
//Prevents from submitting form
event.preventDefault();
var formData = new FormData();
var form_fields = $('#form-add').serializeArray();
$.each(form_fields, function (key, input)
{
formData.append(input.name, input.value);
});
});
The problem is when I try to check the entries inside the variable formData, it only shows the value of the first input:
console.log(formData.get('teste[]'));
//Returns
hello
How can I send this kind of inputs using FormData?

It will send all values. But if you want to check on a client you'll need to use getAll method.
const form = new FormData
form.append('a', 1)
form.append('a', 2)
console.log(form.getAll('a'))

Related

Can you access a HTML form data from the event property, or a "this" keyword, in javascript?

I know that you can easily get data from a form like:
function getData(event) {
event.preventDefault();
const inpt = document.getElementById("inpt").value;
return inpt;
}
//OR
function getData(event) {
event.preventDefault();
const inpt = document.getElementById('form').elements[0].value;
return inpt;
}
<form id="form" onsubmit="getData(event)">
<input id="inpt" type="text"></input>
</form>
what I'd like to know is if this same value could be reached through the event property or a this keyword, withou using a "getElementBy..." of any sort or any querySelector.
I think I like James' answer better. Much simpler. Haven't tested either too extensively sorry.
If you assign all of your form elements a name attribute, on the form submission event you can use the FormData Api to get their data. I believe this won't work on I.E. or other older browsers (check for browser compatibility).
Form Data: https://developer.mozilla.org/en-US/docs/Web/API/FormData#browser_compatibility
Object.fromEntries(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries#browser_compatibility
<form id="form" onsubmit="getData()">
<input name="input1" id="inpt" type="text"></input>
<input name="input2" id="NotNeededForThis" type="text"></input>
</form>
function getData(event) {
event.preventDefault();
const formData = new FormData(event.target);
const formObject = Object.fromEntries(data.entries());
return formObject;
}
This will return the object:
{
input1: "whatever the value was",
input2: "whatever the value was"
}
Since the event listener is set on the form, the form element is available as
event.target
And so the text field value would be accessible by
event.target.elements[0].value
The form element is also this within the submit handler, so you could also do
this.elements[0].value.
You can access the value of the input through the event directly. For example in the function to access the data of the input field with the name 'input1':
function getData(event){
//format event.target.nameOfInput.value
//for the input field with the name input1
let inp1 = event.target.input1.value;
//for the input field with the name input2
let inp2 = event.target.input2.value;
//
console.log( inp1 , inp2)
}

How to show the data from my form in console?

I have a form with a couple of inputs. I want to show the value of the inputs (including the names of the fields) in console in json format when I click the submit button.
How can I do this? I read about new FormData way, but I don't really understand how to use it (so far I've come up with this code, but it doesn't work)
//popup is my form
popup.addEventListener("submit", function (event) {
let formData = new FormData(popup);
console.log(formData);
event.preventDefault();
}, false);
If you want to get all of your data in your form (including names), and you ain't planning to use jQuery, you can try to handle the inputs by yourself based on the form:
const form = document.myForm;
form.addEventListener("submit", function(event) {
event.preventDefault(); // Always preventDefault() first
let formData = new FormData(this);
let object = {};
formData.forEach((value, key) => {
object[key] = value
});
let json = JSON.stringify(object);
console.log(json);
}, false);
<form name="myForm">
<input name="input1">
<input name="input2">
<input name="input3">
<button>Submit</button>
</form>

How do I change FormData before it submits?

I'm working on a project where I need to change FormData before it submits. I can't change the element value, I have to change the actual FormData that goes into a the POST.
I've tried changing form.onsubmit to update the value (works for some fields but others dont work due to validation checks)
<form name="aspnetForm" method="post" action="Posturl.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm" autocomplete="off">
<input type="text" name="field1" id="field1" value="">
<input type="text" name="field2" id="field2" value="">
</form>
I know I can create a new FormData object and can set the values of the object with formData.set('field1', 'newValue') but Im unsure on how to POST this new FormData object and not the old object.
Try to use formdata event listener.
document.querySelector("form").addEventListener('formdata', (e) => {
const formData = e.originalEvent.formData;
formData.append('alphabet', "abcde");
formData.append('a1b2', "123123");
});
source:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/formdata_event
I use e.originalEvent.formData instead of e.formData (following the doc above) because e.formData is undefined And of course, don't use e.preventDefault on submit because it will cancel the default form request (Doc type request).
You can get the data by putting a event listener on the "[type='submit']" button. In the following example I am using jquery to locate the form and ajax to send a request. Hope it Helps.
$("#submit-info").click(function ()
{
var data = new FormData($('form')[0]);
data.append("route",1); (//adding a new value)
data.set('field','newValue'); //use the name attribute of html tag to target the respective key-value pair
$.ajax({
send the data(optional)
});
});
<form method="post" enctype="multipart/form-data" >
<input type="text" name="field" id="field1" value="">
<button type="submit" class="btn btn-primary" id="submit-doc">Submit</button>
</form>
You can simply put the data in the input along with onsubmit
<form name="aspnetForm" method="post" action="Posturl.aspx" onsubmit="formData.set('field1', 'newValue');javascript:return WebForm_OnSubmit();" id="aspnetForm" autocomplete="off">
<input type="text" name="field1" id="field1" value="">
<input type="text" name="field2" id="field2" value="">
</form>
var formData =new FormData();
formData.set('field1', 'sample');
formData.set('field2', 'try');
formData.set('field3', 'again');
//delete the key
formData.delete('field1');
//append new value of the key
formData.set('field1', 'test');
//check all formdata values
for(var pair of formData.entries())
{
console.log('FormData Pair ('+ pair[0]+ ': '+ pair[1]+')');
}
You can try this solution by deleting the key and setting new value
var formData =new FormData();
formData.set('field1', 'sample');
//delete the key
formData.delete('field1');
//append new value of the key
formData.set('field1', 'test');
//check the formdata key if value was updated object
for(let val of formData.values())
{
console.log(val);
}

multipart/form-data form with no field names

I have an HTML form that I was using to send information to the nodejs backend. I then tried to implement file uploads using the same form. To do that, I had to change the enctype of the form from the default value (application/x-www-form-urlencoded) to be enctype='multipart/form-data', and I had to use multer on the backend. I also had this button:
<input type="button" value="Submit" onclick="submitRequest(this);">
which I had to change to:
<input type="submit" value="Submit" onclick="submitRequest(this);">
This worked great in the sense that I now had files uploading to the server. However, this implementation depends on the field's names in the form. The problem is that most of the fields that I have don't have names.
I was wondering if there is a way to get both files and data to send without having to give names to each field in the form? I am wondering if it would be possible to inject my own data into the result that is generated after clicking Submit and before that result is sent to the backend? If not, is there any other way?
You can use FormData to set key and value multipart/form-data, fetch() or XMLHttpRequest() to POST data to server.
<form id="form">
<select>
<option value="1">1</option>
<option value="2">2</option>
</select>
<input type="file" />
<input type="submit" value="Submit" />
</form>
function submitRequest(event) {
event.preventDefault();
var i = 0;
var inputs = form.querySelector("input[type=file], select");
var fd = new FormData();
for (let el of inputs) {
if (el.tagName === "SELECT") {
fd.append("select", el.value)
}
if (el.type === "file") {
if (el.files.length) {
for (let file of el.files) {
fd.append("file" + (i++), file);
}
}
}
}
fetch("/path/to/server", {method:"POST", body:fd})
.then(function(response) {
return response.text()
})
.then(function(res) {
console.log(res)
})
.catch(function(err) {
console.log(err)
})
}
const form = document.getElementById("form");
form.onsubmit = submitRequest;

How to serialize multiple forms and access the submitted one's data using Javascript?

I want to make a generic form validation script where I would compare a form's existing data with the data that is submitted. The validation would fail if the submitted data is NOT different from that which exists on page load.
The problem is if one has multiple forms and one wants to validate the existing data for just a single form. Here's a JSFiddle that's seems pretty close to working but still isn't: http://jsfiddle.net/aMUNh/33/
I think the problem with this JSFiddle is the $.each(function) and setting up the existingData JSON object.
HTML:
<form id="form1">
<input name='form1name1' value='form1value1'>
<input name='form1name2' value='form1value2'>
<input id="1" type="submit" value='submit'>
</form>
<form id="form2">
<input name='form2name1' value='form2value1'>
<input name='form2name2' value='form2value2'>
<input id="2" type="submit" value='submit'>
</form>
JS:
var existingData={}; //declaring the object to be cached
$("form").each(function(index){
existingData.id+=this.id;
existingData.id.data+=$(this).serialize();
});
var id='form1';
document.write('existingData:'+existingData.id.data);
$('input [type=submit]').click(function(){
var id='form'+this.id;
var submittedData=$(this.form).serialize();
if(submittedData==existingData.id.data){
console.log('nothing changed');
}
else console.log('this form changed');
});​
The problem is with the formatting of your data references; just use the form's id. You need something like this:
var existingData = {}; //cached data
$('form').each(function(index){
existingData[this.id] = $(this).serialize();
});
$('form').submit(function(e){
e.preventDefault(); // don't really submit for testing
var form = this;
var submittedData = $(form).serialize();
var originalData = existingData[form.id];
if (submittedData == originalData)
console.log('nothing changed');
else
console.log('this form changed');
});​

Categories