Uvod
Korišćenje FormData interfejsa prilično olakšava rad sa formama, jer je u stanju da jednostavno pokupi sve vrednosti input-a u formi i sačuva ih u objektu u vidu key/value parova.
Dodatna prednost nad standardnim metodom vezana je za olakšano pisanje serverskog koda. Sa standardnim metodom moramo dodati određeni kod na strani servera koji bi dolazne podatke obradio na specijalizovan način, dok sa FormData to nije potrebno, jer je poslati kod standardizovan i debug-ovan! Treba naglasiti da u formi svi HTML input tag-ovi moraju da imaju atribut ‘name’, jer FormData preko njega ima pristup vrednostima input-a.
Sintaksa
a) Prikupljanje podataka iz cele forme
Kada želimo da pokupimo sve vrednosti inputa forme onda koristimo:
1 2 |
var myForm = document.getElementById('form-id'); formData = new FormData(myForm); |
FormData objekat se popunjava sa keys/values parovima. JavaScript koristi name svojstvo za svaki element forme kao keys i pridružuje mu enkodovanu vrednost ulaza.
Primer:
1 2 3 4 5 6 7 8 9 10 11 |
<form id="myform" name="myform"> <div> <label for="username">Unesi ime:</label> <input type="text" id="username" name="username"> </div> <div> <label for="userTel">Unesi telefonski broj:</label> <input type="text" id="userTel" name="userTel"> </div> <input type="submit" value="Pošalji!"> </form> |
JavaScript
1 2 3 4 5 6 7 8 |
document.getElementById("myform").onsubmit = function(event) { event.preventDefault(); var eForma = event.target; var formData = new FormData(eForma); var xhr = new XMLHttpRequest(); xhr.open("POST", "submit.php"); xhr.send(formData); } |
PHP (submit.php)
1 2 3 4 5 |
<?php echo "<pre>"; print_r( $_POST); echo"</pre>"; ?> |
b) Prikupljanje specifičnog podataka iz forme
Ukoliko želimo da FormData objektu pridružimo samo jedan podatak (tj. jedan par key/value), potrebno je da napravimo prazan formData objekata kome naknadno dodajemo željene key/vrednost
1 |
formData.append('nameImputa', unetaVrdnost); |
onda možemo da koristimo i sledeću syntax-u:
1 2 3 4 5 6 7 8 9 10 |
document.getElementById("myform").onsubmit = function(event) { event.preventDefault(); var eForma = event.target; var formData = new FormData(); // Novi prazni objekat var vrednostInputa = document.getElementById("username").value; formData.append('backendKljucIme', vrednostInputa); var xhr = new XMLHttpRequest(); xhr.open("POST", "submit.php"); xhr.send(formData); } |
Na server stiže:
1 2 3 4 |
Array ( [backendKljucIme] => Dragoljub ) |
MDN snippet
EventHandler snippet
Ukoliko imate više formi da ne bi ponavljali kod možemo da koristimo snippet preporučen od MDN zajednice koji pokriva sve moguće načine slanja podataka. U kodu je definisana funkcija AJAXSubmit koja prihvata form objekat kao argument. Nakon toga je dovoljno u svakoj našoj formi samo definisati callback nakon submit-a forme onsubmit="AJAXSubmit(this);.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// EventHandler funkcija function AJAXSubmit (oFormElement) { if (!oFormElement.action) { return; }d var oReq = new XMLHttpRequest(); oReq.onload = ajaxSuccess; if (oFormElement.method.toLowerCase() === "post") { oReq.open("post", oFormElement.action); oReq.send(new FormData(oFormElement)); } else { var oField, sFieldType, nFile, sSearch = ""; for (var nItem = 0; nItem < oFormElement.elements.length; nItem++) { oField = oFormElement.elements[nItem]; if (!oField.hasAttribute("name")) { continue; } sFieldType = oField.nodeName.toUpperCase() === "INPUT" ? oField.getAttribute("type").toUpperCase() : "TEXT"; if (sFieldType === "FILE") { for (nFile = 0; nFile < oField.files.length; sSearch += "&" + escape(oField.name) + "=" + escape(oField.files[nFile++].name)); } else if ((sFieldType !== "RADIO" && sFieldType !== "CHECKBOX") || oField.checked) { sSearch += "&" + escape(oField.name) + "=" + escape(oField.value); } } oReq.open("get", oFormElement.action.replace(/(?:\?.*)?$/, sSearch.replace(/^&/, "?")), true); oReq.send(null); } } // Deo vezan za uspešnost AJAX zahteva: function ajaxSuccess () { console.log(this.responseText); } |
Primena MDN snippeta
Da bi prethodni snippet imao svrhu potrebno je da se kroz atribut forme definiše koja je EventHandler funkcija onsubmit="AJAXSubmit(this)
1 2 3 4 5 6 7 8 9 10 11 12 |
<form action="submit.php" method="post" onsubmit="AJAXSubmit(this); return false;"> <fieldset> <legend>Registration example</legend> <p> First name: <input type="text" name="firstname" /><br /> Last name: <input type="text" name="lastname" /> </p> <p> <input type="submit" value="Submit" /> </p> </fieldset> </form> |
Ukoliko se iz forme prikupljaju podaci različitih tipova (ako se pored teksta šalju i fajlovi), onda telo zahteva mora da se sastoji iz delova koji su odvojeni sa granicama “boundary”. Stoga je potrebno da u header-u postoji “Content-Type” polje koje definiše “multipart” telo enctype="multipart/form-data"
The content type “application/x-www-form-urlencoded” is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type “multipart/form-data” should be used for submitting forms that contain files, non-ASCII data, and binary data.
https://www.w3.org
Primer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<form action="submit.php" method="post" enctype="multipart/form-data" onsubmit="AJAXSubmit(this); return false;"> <fieldset> <legend>Upload example</legend> <p> First name: <input type="text" name="firstname" /><br /> Last name: <input type="text" name="lastname" /><br /> Sex: <input id="sex_male" type="radio" name="sex" value="male" /> <label for="sex_male">Male</label> <input id="sex_female" type="radio" name="sex" value="female" /> <label for="sex_female">Female</label><br /> Password: <input type="password" name="secret" /><br /> What do you prefer: <select name="image_type"> <option>Books</option> <option>Cinema</option> <option>TV</option> </select> </p> <p> Post your photos: <input type="file" multiple name="photos[]"> </p> <p> <input id="vehicle_bike" type="checkbox" name="vehicle[]" value="Bike" /> <label for="vehicle_bike">I have a bike</label><br /> <input id="vehicle_car" type="checkbox" name="vehicle[]" value="Car" /> <label for="vehicle_car">I have a car</label> </p> <p> Describe yourself:<br /> <textarea name="description" cols="50" rows="8"></textarea> </p> <p> <input type="submit" value="Submit" /> </p> </fieldset> </form> |