Submit dynamically created input from Angular to PHP Page - javascript

I am trying to create an invoice form, which can make all the necessary calculations like subtotal, tax total by itself .
Hitting the submit button should submit all values and the dynamically created items to a PHP page, which will insert these values (written by the user, or calculated by angularjs) to the appropriate SQL table/column as I wish.
Based on this project , I added this javascript code.
function PhpCtrl($scope, $http, $templateCache) {
var method = 'POST';
var url = 'added.php';
$scope.codeStatus = "";
$scope.add = function() {
var FormData = {};
$http({
method: method,
url: url,
data: FormData,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
cache: $templateCache
}).
success(function(response) {
$scope.codeStatus = response.data;
}).
error(function(response) {
$scope.codeStatus = response || "Request failed";
});
return false;
};
}
Can anyone help me how to store all the dynamically created items, along with their values, in order to submit them to a php page ?

You can create a FormData to be submitted dynamically using plain javascript like this:
var fd = new FormData();
fd.append("fieldName", valueToSubmit);
fd.append("arrayField[]",[1,2,3]); //you can even post array data
The you push fd to the server:
var uri = "added.php";
var xhr = new XMLHttpRequest();
xhr.open("POST",uri,true);
xhr.onreadystatechange=function(){
if(xhr.readyState == 4 && xhr.status==200){
//do something with returned data
}
};
fd.append("img_file",blob_to_upload);// you can even upload a file
fd.append("user_id",data);
fd.append("category_id",category_id);
xhr.send(fd);

Related

Use javascript to rename file before upload

Let's say I have this list of forms like so:
var forms = document.getElementsByClassName('uploadImage');
each item in this list look like this:
<form method=​"post" action=​"/​upload" enctype=​"multipart/​form-data" id=​"f_x" class=​"uploadImage">
​ <input type=​"file" id=​"u_x">​
<input type=​"submit" value=​"Submit" id=​"s_x">​
</form>​
where x = [0,1,2,3,4,5]
How do I loop through this list and do two things:
1 - Rename the file name
2 - Submit the form for uploading the file
I looked for many resources online like this one: https://www.telerik.com/forums/change-file's-name-when-it's-uploaded-via-html-form, all of them are using Jquery , I need it in javascript
update :-
I figured out how to get to the input value of each form
forms[0].elements[0] this will return the first input of the first form on the list
forms[0].elements[0].value this output the value of the file input
So here is the code you linked to, and I will break it down a bit after. A lot of it is vanilla javascript.
$(document).ready(function() {
initImageUpload();
function initImageUpload() {
$("#btn-submit").click(function(e) {
e.preventDefault();
var everlive = new Everlive({
appId: "",
scheme: "https"
});
// construct the form data and apply new file name
var file = $('#image-file').get(0).files[0];
var newFileName = file.filename + "new";
var formData = new FormData();
formData.append('file', file, newFileName);
$.ajax({
url: everlive.files.getUploadUrl(), // get the upload URL for the server
success: function(fileData) {
alert('Created file with Id: ' + fileData.Result[0].Id); // access the result of the file upload for the created file
alert('The created file Uri is available at URL: ' + fileData.Result[0].Uri);
},
error: function(e) {
alert('error ' + e.message);
},
// Form data
data: formData,
type: 'POST',
cache: false,
contentType: false,
processData: false
});
return false;
});
}
});
As is mentioned, this uses jQuery $.ajax() to create an AJAX POST to the server with new FormData where the name of the file has been modified. The new FormData is then sent to the server instead of the HTML Form data.
So, when the button is clicked to submit the form, this event is prevented.
var file = $('#image-file').get(0).files[0];
This is then used to select the <input> element in jQuery and then collect the files info from the element.
var file = document.getElementById("image-file").files[0];
This can be done with JavaScript. Largely the rest of the script would be unchanged, except for the initialization and sending of POST Data via AJAX.
It might be best to create a function that you send the form to and it can then return the new form data with new name. As you did not want to provide an MCVE, it's hard to give you an example since it's not clear how the data for the new name would be create or gathered from.
function nameFile(inEl, newName){
var file = inEl.files[0];
var results = new FormData();
results.append('file', file, newName);
return results;
}
function sendFile(url, formData){
var request = new XMLHttpRequest();
request.open("POST", url);
request.send(formData);
}
sendFile("/​upload", nameFile(document.getElementById("file-image"), "UserFile-" + new Date().now() + ".jpg"));
Another issue is if you have multiple forms, and multiple submit buttons, which one will trigger all the items to get uploaded? Either way, you'd have to iterate each form (maybe with a for() loop) collect the form data from each, update the name, and submit each one, most likely via AJAX.
Hope this helps.

Sending FormData with AngularJS [duplicate]

I want to pass the username and form_data object to the php file using http.post
when i pass only form_data it works my picture upload. but i want to pass some other information like username as well. please help me how to pass other data in http.post
And here is my php file.
<?php include "connectdb.php";
$data=json_decode(file_get_contents("php://input"));
$name=$dbhandle->real_escape_string($data->susername);
if (!empty($_FILES)) {
$date=2;
$path = 'fooditem/'. $_FILES['file']['name'];
if (move_uploaded_file($_FILES['file']['tmp_name'],$path)) {
$query="INSERT INTO `login`(`id`,`type`,`img`) VALUES('".$name."','".$date."','".$_FILES['file']['name']."')";
if($dbhandle->query($query)){
echo 'File Uploaded';
}
else
echo 'File Uploaded But Not Saved';
}
}else{
echo 'Some Error';
}
myapp.directive("fileInput",function($parse){
return{
link: function($scope,element,attrs){
element.on("change",function(event){
var files = event.target.files;
$parse(attrs.fileInput).assign($scope, element[0].files);
$scope.$apply();
// console.log(files[0].name);
});
}
}
});
myapp.controller("myController",function($scope,$http){
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
$http.post("picupload.php",{'susername':$scope.susername,form_data})
.then(function(response){
console.log(response);
})
});
<input type="text" ng-model="username" name="username">
<input type="file" file-input="files" accept="image/*" />
<input type="submit" value="SIGN UP" ng-click="signup()"
name="signup_btn" class="btn btn-primary">
You can add something like this:
myapp.controller("myController",function($scope,$http){
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
form_data.append('susername',$scope.susername); // new line
var config = {headers: { 'Content-type': undefined } };
$http.post("picupload.php",form_data, config)
.success(function(response){
alert(response);
});
}
I'm not sure about PHP but after googling I found that in php 'susername' can retrieved as below:
$_POST['susername'];
How to make POST requests with the FormData API
When posting objects created by the FormData API, it is important to set the Content-type header to undefined.
$scope.signup = function(){
var form_data = new FormData();
angular.forEach($scope.files,function(file){
form_data.append('file',file);
});
form_data.append('susername', $scope.susername);
var config = {headers: { 'Content-type': undefined } };
return $http.post("picupload.php",form_data, config)
.then(function(response){
console.log(response.data);
return response.data;
});
};
Also a FormData object can not be serialized into a JSON string it must be sent by the XHR API alone. Append all necessary data to the FormData object.
When the XHR send API posts an object created by the FormData API, it automatically sets the content type header to multipart/form-data with a proper encapsulation boundary and encodes the data using base64 encoding.
Normally the $http service overrides the XHR API sets the content type header to application/json. Setting the content type header to undefined allows the XHR API the freedom to set the header properly.
Update
On the server side use:
$_POST['susername'];
to receive the data item.

Uploading File via FormData

I am trying to upload a file to a Node backend that uses Multer. Multer requires the form to be submitted a specific way. If it's not submitted that way, the request.file parameter will be undefined. I have created an approach that works by using brute force. That working approach looks like this:
index-1.html:
<form method="POST" enctype="multipart/form-data" id="fileUploadForm">
<input type="file" id="selectedFile" name="selectedFile" /><br/><br/>
<input type="submit" value="Submit" id="btnSubmit"/>
</form>
...
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
e.preventDefault();
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
console.log(data);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/upload",
data: data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
success: function (data) {
console.log("SUCCESS!");
},
error: function (e) {
console.log("ERROR : ", e);
}
});
});
The code above successfully posts the file to my server. That server has the following:
server.js
app.post('/upload', upload.single('selectedFile'), function(req, res) {
if (req.file) {
console.log('file uploaded');
} else {
console.log('no file');
}
res.send({});
});
Using the code above, "file uploaded" is displayed in the console window as expected. However, I need a more dynamic approach. For that reason, I need to programmatically build the form in JavaScript. In an attempt to do that, I've created the following:
index-2.html
[my UI]
var btn = document.getElementById('btnSubmit');
btn.addEventListener('click', function(e) {
var form = document.createElement('form');
form.action = '/upload';
form.method = 'POST';
form.enctype = 'multipart/form-data';
var node = document.createElement("input");
node.name = 'selectedFile';
node.value = GLOBAL_SELECTED_FILE;
form.appendChild(node);
var data = new FormData(form);
data.append('id', this.id);
console.log(data);
$.ajax({
type: 'POST',
url: '/profile-picture/upload',
enctype: 'multipart/form-data',
data: data,
contentType: false,
processData: false,
success: function(res) {
console.log('success!');
},
error: function(xhr, status, err) {
console.log('error');
}
});
});
This second approach does not work. To clarify, the GLOBAL_SELECTED_FILE variable is the data of a file that was selected from an input element. The data is loaded via the FileReader api. That looks like this:
var GLOBAL_SELECTED_FILE = null;
var fileReader = new FileReader();
fileReader.onload = function(e) {
GLOBAL_SELECTED_FILE = e.target.result;
}
fileReader.readAsDataURL(fileSelected); // file selected comes from the onchange event on a <input type="file">..</input> element
Basically, I'm loading a preview of the image. Anyways, when I hit the submit button in the working version (index-1.html), I notice in Fiddler that a different value is sent over the value sent in index-2.html.
With the approach in index-1.html, Fiddler shows something like this in the "TextView" tab:
------WebKitFormBoundary183mBxXxf1HoE4Et
Content-Disposition: form-data; name="selectedFile"; filename="picture.PNG"
Content-Type: image/png
PNG
However, when I look in the "TextView" tab in Fiddler for the data sent via index-2.html, I see the following:
------WebKitFormBoundary9UHBP02of1OI5Zb6
Content-Disposition: form-data; name="selectedFile"
data:image/png;base64,iVBORw0KGg[A LOT MORE TO GO]
It's like the FormData is using two different encodings for the same value. Yet, I don't understand why. How do I get index-2.html to send the image in the same format as index-1.html so that Multer will populate the req.file property?
Thank you!
In index-1.html, you are using a file input:
<input type="file" id="selectedFile" name="selectedFile" />
In index-2.html, you are creating an ordinary form input (not a file input):
var node = document.createElement("input");
node.name = 'selectedFile';
node.value = GLOBAL_SELECTED_FILE;
form.appendChild(node);
To create a file input, you would need to add node.type = 'file'. However, you won't be able to set the value because browser security restrictions prevent setting the value of file inputs.
Instead, what you need to do is append the file that was selected by the user to the FormData object:
var data = new FormData(form);
data.append('id', this.id);
data.append('selectedFile', $('#fileInputElement')[0].files[0]);

How to upload FormData object using AngularJS

I am new to angular-js, and wants to submit the multipart/form-data with an image and it's $http.post() method supports only json format, so I want to convert formdata object to the json format,
$scope.SubmitForm=function()
{
url = siteurl + '/admin/' + $scope.module + '/add';
var form=document.getElementById("addForm");
var formData=new FormData(form);
$http({
url : url,
method : "POST",
data : formData,
})
.then(function(responseText) {
alert(JSON.stringify(responseText));
//process data
},function(){
alert("hello from error");
});
}
it didnot work for me; and i tried to make json format data for this and works fine
formData={
"first_name" : $('#first_name').val(),
"last_name" : $('#last_name'),
//....
};
but don't have any idea to append my image file to this format; what should i do right here to get my job.
Is there any way(function) to convert formdata object to json format
solved by putting two line of code like below, in $http configuration lines (thanks every body)-
$http({
url : url,
method : "POST",
data : formData,
transformRequest: angular.identity, // see the angugular js documentation
headers : {'Content-Type':undefined}// setting content type to undefined that change the default content type of the angular js
}).then(function(responseText){
alert(JSON.stringify(responseText));
///$scope.tablerows=$scope.totaltablerows;
///$scope.searchFunction();
},function(){
alert("hello from error");
});
just this works for me
You should really use ng-model when working with forms in angular (can you provide your form in your example?). It creates a scope variable to work with in your controller and you will have two way binding if it is already defined... for example as your form isn't present I'd do something like this, this is simplified (and not tested)...:
<form name="myForm" ng-submit="SubmitForm()">
Name: <input ng-model="fields.name">
Address: <input ng-model="fields.address">
....
</form>
and in your JS controller...
$scope.submitForm = function(){
var data = $scope.fields,
url = '/admin/' + $scope.module + '/add'; // I assume $scope.module is available from elsewhere...
$http.post(url, data).then(function(resp){
// do stuff...
});
}
There's more info here... https://docs.angularjs.org/api/ng/directive/ngModel and W3schools have some examples: http://www.w3schools.com/angular/angular_forms.asp
It Should be constructed like this:
var form = document.getElementById('addForm');
var fd = new FormData(form);
var file = this.files[0];
fd.append("afile", file);
// These way you add extra parameters
fd.append("first_name", $('#first_name').val());
fd.append("last_name", $('#last_name').val());
Reference example - from github

Access file upload field from ajax

I have a problem with accessing file upload field
//HTML
<input type='file' name='images' id="images" multiple>
//////////////////
$('.bt-add-com').click(function(){
var formdata = new FormData();
var sessionID = 8;
var theCom = $('.the-new-com');
var theName = $('#name-com');
var theMail = $('#mail-com');
var theFile = formdata.append("images", sessionID);
if( !theCom.val()){
alert('You need to write a comment!');
}else{
$.ajax({
type: "POST",
url: "ajax/add-comment.php",
data: 'act=add-com&id_post='+<?php echo $id_post; ?>+'&name='+theName.val()+'&email='+theMail.val()+'&comment='+theCom.val()+'&file='+formdata.append("images[]", sessionID),
success: function(html){
theCom.val('');
theMail.val('');
theName.val('');
$('.new-com-cnt').hide('fast', function(){
$('.new-com-bt').show('fast');
$('.new-com-bt').before(html);
})
}
});
}
});
////RESULT
array (size=6)
'file' => string 'undefined' (length=9)
problem is when i access file upload field using formdata as code below. it display value as undefined. can't get uploaded file details
You're taking the form data object and appending it to a string. That won't work.
Don't try to build a string to pass to data, use the FormData API for all your fields, then pass the FormData object itself.
You also need to append the file data form the input instead of the number 8.
formdata.append("images", sessionID);
formdata.append("images[]", sessionID)
Don't use images and images[]. If you're using PHP, then use just images[]
Don't use sessionID, use the file.
formdata.append("images[]", document.getElementById('images').files[0]);

Categories

Resources