Not getting file data in Extjs Ajax request - javascript

I have a form on form-window, and inside form window I have a form with many fields and one upload button. When try to submit form using Ajax.request I have got textfield value but can not get file data. Except filename.
var fd = Ext.getCmp('users-form').form;
var fileInput = document.getElementById('company_logo');
console.log(fd.getEl().dom.files);
params = {
name : fd.findField('name').getValue(),
login : fd.findField('login').getValue(),
email : fd.findField('email').getValue(),
password : fd.findField('password').getValue(),
password_repeat : fd.findField('password_repeat').getValue(),
id : fd.findField('id').getValue()
company_logo : fd.findField('logo').getValue()
}
console.log(params);
Ext.Ajax.request({
url: Scada.reqUrl('users', 'save'),
method: 'post',
params: {
data: Ext.encode(params)
},
success: function() {
console.log('in success');
},
failure: function() {
console.log('in failure');
}
});
Here logo is input type file. I want to send logo data with ajax request. Please help me to figure out the problem. Thanks

Not sure why you started a new question instead of editing Encode form data while fileupload true in Extjs Form Submit as this seems to be the same problem.
Assuming logo is your file upload field you are trying to get the file data using getValue does not actually return the file content (if you use modern there is a getFiles method which returns the selected file objects).
General problems with your approach:
As I stated in my original answer it is not a good idea to send files in a standard ajax request. In your case those problems are:
If you expect getValue to return file contents, you are potentially encoding binary data into a JSON string. This will maybe work but create a large overhead and as the only available JSON datatype that could handle this content is string your parser would have to guess that property company_logo contains binary data and needs to be somehow converted into some sort of file reference.
You are sending files without metadata, so when just adding the raw content into your JSON string you would not be able to detect the expected file type without testing the file in multiple ways
As far as I know you would not be able to access the file content in classic toolkit at all
Submitting the data as a form: In your original question you explained that you submit the form instead of doing Ajax requests which is generally the preferred way.
When you submit a form that contains a file upload field the form will automatically be submitted as multipart/form-data the raw files are added to the request body with it's original content while preserving metadata collected by the browser.
If you look at https://docs.sencha.com/extjs/7.0.0/modern/Ext.Ajax.html#method-request you would have to set isUpload to true and use the form proeprty instead of params, passing a reference to the parent form.

Related

Write back values to HTML form from XMLHttpRequest

I'm working on an embedded device (ESP32) serving static pages from the internal flash (SPIFFS). I'm looking for a simple way to populate the form values with the actual values since with this approach they are loaded with the default values.
I have a working XMLHttpRequest communication channel. For example I'm able to POST the form values retrieving them with:
document.getElementById("form-controls").onsubmit = function (event) {
event.preventDefault();
fetch("/controls", {
method: 'post',
body: new FormData(document.getElementById("form-controls"))
}).then(function(response) {
});
}
I wondering if there's the opposite function. Using a GET method on the same url I would answer from my MCU with the actual values to be written in the form fields.
I'm able to do this manually using JSON and updating each input tag via javascript.
My question is if there is an equivalent of FormData that given an input data can fill automatically the related form fields.

Saving Javascript FormData() Object on client side

I have a html page which contains a form element with some text and file input elements.
This from is submitted with an ajax call to the server using a method suggested here: How can I upload files asynchronously?
As you may see in the referenced page from the above link, the FormData() object is used as a container for inputed data and I have done the job successfully.
But now we want to create a new page that have these html elements, save the text and file inputs on client side (Cookie or Local Strorage or . . .) and do the ajax submit later on another page.
I wasn`t able to save new FormData() in either cookie or local storage; what got saved is a small string:"[object FormData]" instead of entered file and strings.
I also tried using JSON.stringify() with no success; it just returned an empty JSON("{}").
(the code is using jQuery selector)
var postData = new FormData($(form)[0]);
// var sPostedData = JSON.stringify(postData); // returns: "{}"
var myStorage = window.localStorage; // returns: "[object FormData]"
myStorage.setItem("contentOrder", postData);
Please help, how should I save this object on my client-side?
To get the file from form data use formData.get('file') where file is the name of an input. The returned object will be of type Blob (see how to get its content).
The complete example can be found in this fiddle: https://jsfiddle.net/skm5m467/1/

How to send files and attributes to controller in ASP.NET MVC and receive a dynamically generated PDF as Binary as response?

I'm facing this struggle for some days now and I really can't get my head around this.
I have to call an action that receives two pictures and 3 strings as parameters, this function will generate a pdf using itextsharp, save it in the server and return the binary array as
return File(bytes, "application/pdf", "mobile.pdf");
I was trying to used ajax to receive the binary file like this:
$.ajax({
url: "/Home/PDF",
type: "POST",
dataType: 'json',
data: {
Id : $("#ID").val(),
String : $("#String").html(),
Type: type,
Image: Item,
Image2: Item2,
},
success: function (data) {
if(data != null)
{
//Something
}
},
});
As it is, I can see that I have received the binary information through the network tab, but I have no idea of how to display it as a PDF to the user, anything I try on success will end up simply not happening or I receive a internal server error.
The images and parameters I need to pass are generated dynamically in the view
The action on the controller can be roughly summarized as something like this:
public ActionResult PDF(string Id, string String, string Type, string Image, string Image2)
{
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
//Code...
byte[] bytes = memoryStream.ToArray();
return File(bytes, "application/pdf", "mobile.pdf");
}
any help would be very much appreciated.
Thanks guys.
If you send this request as a form submission, the browser should correctly download the pdf file. This isn't possible with ajax requests. Here is a helper function you could use.
function sendFormRequest(url, nameValuePairs) {
var form = document.createElement('form');
form.method = 'POST';
form.action = url;
for (var v in nameValuePairs) {
var input = document.createElement('input');
input.name = v;
input.value = nameValuePairs[v];
form.appendChild(input);
}
document.body.appendChild(form);
form.submit();
}
You could use it like so:
sendFormRequest("/Home/PDF", {
Id : $("#ID").val(),
String : $("#String").html(),
Type: type,
Image: Item,
Image2: Item2,
});
Anthony is correct that JavaScript pretty much lacks the ability to save files locally from a browser, mainly for security concerns.
The simplest option is a normal form submit as suggested already. However if you want to keep the upload via ajax for an asynchronous user experience, you can generate and keep the file on the server. You can then return a unique identifier (such as a guid) as the ajax response. The code can then redirect the window to a new controller action which takes the unique id and returns the pre-generated file as a file stream. The browser will then download the file as normal.
Two issues with this would be ensuring security of the files so malicious users couldn't spam file ids until they crack one. And cleaning up of the generated files on the server periodically.

jQuery file upload doesn't submit extra parameters

I need to use the formData parameter available in the jQuery File Upload control to send additional data to the server on submit. The default implementation for formData is to invoke a function that grabs all controls in the form and serializes them to an array (using the jQuery serializeArray() method).
I have controls in my form, but when the file is uploaded, I am not getting any additional data. When I inspect via Fiddler, there is nothing in the request that shows these form fields are being submitted.
Is there something additional that needs to be done to get these to submit?
Btw, these two links discuss formData...
https://github.com/blueimp/jQuery-File-Upload/wiki/Submit-files-asynchronously
https://github.com/blueimp/jQuery-File-Upload/wiki/Options
...for this one search the page for formData.
For what its worth, the multipart option is set to true.
I also needed to pass an extra parameter and here is what i used :
$('#fileupload').fileupload({
formData: {
param1: 'test'
,param2: "value2"
,param3: "yasseshaikh"
}
});
The formData option can be used to set additional form data programmatically.
Complete code (I modified the answer provided by Yasser)
Add these code into jquery.fileupload.js
submit: function (e, data) {
$('#fileupload').fileupload({
formData: {
param1: 'test'
,param2: "value2"
,param3: "yasseshaikh"
}
});
},
If the blueimp plugin isn't a requirement I would really recommend the jquery malsup form.
You can use a regular multipart form and just create a regular file input field along with other input fields of your own choice and everything is submitted as usual.
Reference: http://www.malsup.com/jquery/form/
Code sample:
$('#myForm2').submit(function() {
$(this).ajaxSubmit(options);
return false;
});
You have to bind Your data to fileupload. Look at this question
Blueimp jQuery file upload, passing extra form data

Manipulate form data before it's sent with jQuery

I want to encrypt some data in a form using jQuery before it's sent to the server, it can be a MD5 hash. It is a small project, so I don't really need to use SSL.
I have the following JavaScript code where I use $.md5 in the password confirmation info:
$(document).ready(function() {
var dataToSend = {};
dataToSend['action'] = 'signup';
dataToSend['name'] = name.val();
dataToSend['email'] = email.val();
dataToSend['confsenha'] = $.md5(pass2.val());
var options = {
target: '#error',
url: 'insert.php',
beforeSubmit: validate,
data: dataToSend,
success: function(resposta) {
$('#message').html(resposta);
}
};
$('#customForm').ajaxForm(options);
});
The problem is that the data is being duplicated. I tought that overwriting the data being sent by using the var dataToSend would make ajaxForm send only data in that map. But besides sending data from dataToSend, it also sends data from the form, so what I wanted to encrypt using MD5 appears both encrypted and clean. This is an example of what goes in the request:
usuario=user&email=user%40email.com&senha=12345&confsenha=12345&send=&action=signup&name=user&email=user%40email.com&confsenha=d41d8cd98f00b204e9800998ecf8427e
I know I have to define the a function beforeSerialize, but I don't know how to manipulate form data. Can anyone tell me how to do that?
As per the documentation on the plugin site:
data
An object containing extra data that should be submitted
along with the form.
The word along is the crux.
So when you pass data as a part of the options object that data is serialized and is sent along with any data/input elements values that are part of a form.
A better approach would be to hash the password value and assign it to the same field or another hidden field in the beforeSubmit handler(in your case the validate function) and remove the dataToSend object totally.
Something like:
Without any hidden element:
function validate(){
//Other Code
pass2.val($.md5(pass2.val()));
}
With a hidden element in the form:
function validate(){
//Other Code
$("#hdnPass").val($.md5(pass2.val()));
pass2.val("");
}

Categories