I trying to multiple file upload in mvc with Jquery ajax but i have some problems.
Here its my Html design and codes..
<div id="fileinputdiv">
<input type="file" name="mainfile" id="mainfile" onchange="OnValueChanged(this)">
</div>
<div id="tab_images_uploader_container" class="text-align-reverse margin-bottom-10">
<span class="btn green fileinput-button">
<i class="fa fa-plus"></i>
<span> New Image... </span>
</span>
<a id="tab_images_uploader_uploadfiles" class="btn btn-primary">
<input type="button" value="Upload Images" id="btnUpload" name="btnUpload" />
</a>
</div>
Javascript codes...
<script type="text/javascript">
var files = []; // Creating array for list of files
function OnValueChanged(fileUploadItemId) {
var selectedvalue = $(fileUploadItemId).val();
files.push(selectedvalue);
}
$(document).ready(function () {
$("#AddFile").click(function (e) {
e.preventDefault();
$(" <input type='file' onchange='OnValueChanged(this)'>").appendTo("#fileinputdiv");
})
$("#btnUpload").on("click", function () {
var fileData = new FormData();
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
$.ajax({
url: "/Product/UploadFiles",
type: "POST",
contentType: false,
processData: false,
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
})
});
And the finally my function..
[HttpPost]
public ActionResult UploadFiles()
{
if (Request.Files.Count > 0)
{
try
{
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
string fname;
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
fname = Path.Combine(Server.MapPath("~/ProductImages/"), fname);
file.SaveAs(fname);
}
return Json("File Uploaded Successfully!");
}
catch (Exception ex)
{
return Json("Error occurred. Error details: " + ex.Message);
}
}
else
{
return Json("No files selected.");
}
}
My question is when i click the "Upload Files" button no any data sending with ajax to the UploadFiles() function i always getting "No files selected" errors but i tested with this code
for (var i = 0; i < files.length; i++) {
alert(files[i]);
}
i'm able to display all files which is selected. where is the problem that i could not find ?
You have to replace Request.Files with request.Form.Files.
I recommend you not to use Ajax for asynchronous file upload for various reasons. One would be to experience problems with attaching FormData and getting it in your API, and the other would be to get error when accessing HttpContext.Request.Form especially in ASP.Net Core. My recommendation to you is to use the following if asynchronous upload is a REQUIREMENT, else you could do it the non-ajax way in a separate popup window.
Use the following Javascript code:
function uploadAsync(evt){
if (evt.enctype == "multipart/form-data") {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// Add the response to the desired tag by calling the xhr.responseText
}
};
xhr.onprogress = function(progressEvent){
// Update your progress here
}
xhr.open(evt.method, evt.action, true);
xhr.send(new FormData(evt));
}
}
This code may cause post back, in order to prevent it use return false; after calling the method:
<form id="fileUploadForm" action="your action API" method="post" enctype="multipart/form-data" onsubmit="uploadAsync(this); return false;">
<input name="personalImage" type="file" />
<input name="coverImage" type="file" />
<input type="submit" value="submit" />
</form>
now assuming:
public class FileHandlerController: Controller{
[HttpPost]
public String GetFileAndVerify(){
var files = HttpContext.Request.Form.Files;
// do the process on files
return "We got them files";
}
}
or you can use IFormFile in ASP.Net Core or HttpPostedFile in ASP.Net 4.
If you run into any problems when using this approach, let me know in the comment to provide you with more information and solve your problem.
Update
I have developed an unobtrusive version of this approach which you can find here: GitHub
here's the user manual:
<form async progress-bar-parent="pbarMain" progress-bar-name="pbar" response-parent="updArea" response="updElement" progress-bar-percentage="pbarPercent" dateset-ajax="true" action="/AdminArea/FilesAPI/PostFile" method="post" enctype="multipart/form-data" >
<div class="input-group input-group-sm pull-left p-10">
<input type="file" id="file" name="file" />
<span class="input-group-btn">
<input type="submit" class="btn btn-primary" value="Submit" />
</span>
</div>
</form>
<div id="pbarMain" class="progress" style="margin-top:20px; width:96%; margin-left:2%; position:relative; display:none;"></div>
<div id="updArea" class="input-group input-group-sm pull-left p-10" style="display:none;">
<input id="updElement" type="text" class="form-control" value="" />
<span class="input-group-btn">
<button class="btn btn-primary" onclick="copyText('#updElement')">Copy</button>
</span>
</div>
To allow uploading files in multiple forms at the same time, include allow-multi in your form tag like <form allow-multi class="..." ...>. However, this may result in some UI problems as this version I have developed is still the alpha version.
Related
I am creating a html form to capture applicants' inputs and then send a POST request to an api with the data. I do not know how to go about hiding three specific values from something like 'View Page Source' or console.log(). I need to store the values securely and still be able to use them in the HTML form.
I know I will probably have to rewrite my solution but I do not know the best way to go about this. Is there a way to store the values of the api keys in a database?
Here are the three values in question:
<body>
<main role="main" class="container-fluid">
<form id="form1" name="form1" onsubmit="beforeSubmit(); return false;">
<div class="aspNetHidden">
<input type="hidden" name="merchantID" id="merchantID" />
<input type="hidden" name="login" id="login" />
<input type="hidden" name="password" id="password" />
</div>
<script type="text/javascript">
var merID = "1234567";//need to store these values somewhere else!!!!!!!
var log = "API123";
var pass = "1234567";
//even if these values are moved they would be viewable by something like console.log(obj)
document.getElementById("merchantID").value = merID;
document.getElementById("login").value = log;
document.getElementById("password").value = pass;
</script>
And here is where I make the API call:
<script type="text/javascript">
beforeSubmit = function () {
//======================================================================================================
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
//======================================================================================================
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
xhttp.open("POST", "https://someurl.com/enroll.svc/JSON/CreateMerchant", true);
xhttp.setRequestHeader("Content-type", "application/json");
var obj = JSON.stringify($('#form1').serializeObject());
console.log(obj);//security concern! all someone would have to do is cntrl+shift+j when the form is submitted
//this log command would display the entire JSON object including the merchant ID, Login and Password
xhttp.send(obj);
} //=====================================================================================================
</script>
I am very new to this. The code does what it is supposed to aside from sensitive information easily being viewed by inspecting the page source. Any suggestions of for a better/more secure way would be appreciated.
Its shouldn't be too hard put your api in a php variable then insert your variable into your database table.
Then use select to take it out when you need it also php is not readable from view source.
If you don't know how to input and select from databases there are plenty of tutorials out there.
Your code is a horrid mix of unnecessary serialisation you are not using and a weird event handling of beforesubmit.
This is how a generic jQuery ajax looks like
$(function() { // page load
$("#form1").on("submit", function(e) {
e.preventDefault(); // cancel the submit
$.post("https://someurl.com/enroll.svc/JSON/CreateMerchant", // url
$(this).serialize(), // serialising the form
function(result) {
console.log(result); // do something with the result of the submission
});
});
});
<form id="form1" name="form1">
<div class="aspNetHidden">
<input type="hidden" name="merchantID" id="merchantID" />
<input type="hidden" name="login" id="login" />
<input type="hidden" name="password" id="password" />
</div>
</form>
I would like to create a form with drag and drop functionality.
I see filelist is a read-only object and it's and it's not used with drag and drop. So I copy the file into an array and pass it to my form with formdata. But It doesn't work.
Any ideas?
html :
<form id="upload" action="action.php" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>HTML File Upload</legend>
<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />
<div>
<label for="fileselect">Files to upload:</label>
<input type="file" id="fileselect" name="fileselect[]" multiple="multiple" />
<div id="filedrag">or drop files here</div>
</div>
</fieldset>
</form>
<button id="submitbutton" >Upload Files</button>
<div id="messages">
<p>Status Messages</p>
</div>
a reduce of javascript :
var myfiles = [];
(function() {
// getElementById
function $id(id) {
return document.getElementById(id);
}
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
myfiles.push(f);
ParseFile(f);
}
}
$id("submitbutton").onclick = function(){
var xhr = new XMLHttpRequest();
formData = new FormData(document.querySelector('form'));
xhr.open('get','action.php');
formData.append("files", myfiles);
xhr.onload = function () {
console.log(this.responseText);
};
xhr.send(formData);
}
You must append files to FormData one at a time. The syntax used is similar to what you do in your input element and looks like an array. So append your files like this:
myfiles.forEach(file=>{
formData.append("files[]", file);
});
Then, on the server side they will be available in the files array.
This is my .html file
<form [formGroup]="complexForm" (ngSubmit)="submitForm(complexForm.value)">
<div class="row">
<div class="col-md-12 col-12">
<label>My name is</label>
</div>
<div class="col-md-12 col-12 q-row">
<div class="form-group" [ngClass]="{'has-error':!complexForm.controls['name'].valid && complexForm.controls['name'].touched}">
<input class="form-control" type="text" [formControl]="complexForm.controls['name']">
<div *ngIf="complexForm.controls['name'].hasError('required') && complexForm.controls['name'].touched" class="invalid">Please provide your name.</div>
</div>
</div>
</div>
<input type="file" (change)="fileChanged($event)" name="file1" [formControl]="complexForm.controls['file1']">
<input type="file" (change)="fileChanged($event)" name="file2" [formControl]="complexForm.controls['file2']">
<div class="form-group">
<button type="submit" class="btn btn-primary pull-right">Submit</button>
</div>
</form>
this my .ts file
complexForm : FormGroup;
constructor(fb: FormBuilder){
this.complexForm = fb.group({
'name': [],
'file1':[],
'file2':[]
});
}
fileChanged(e: Event) {
debugger;
var target: HTMLInputElement = e.target as HTMLInputElement;
for(var i=0;i < target.files.length; i++) {
this.upload(target.files[i]);
}
}
upload(uploads: File) {
debugger
var formData: FormData = new FormData();
formData.append("files", uploads, uploads.name);
console.log(formData);
}
submitForm(values){
console.log(values);
console.log(FormData);
}
but while selecting file ,upload function is called,but nothing is appending with formData.i want to upload file only after form submission.but some problem with formdata.while consoling it is not showing anything.In formbuild also it is not showing.so any solution for this?thanks in advance.
First of all, you are calling upload for each file, and inside it you create a new instance of FormData. This means that even if you try to submit this form it will only contain the last of the files.
Secondly, you have no reference to that FormData instance you want to submit, because it is created var formData: FormData = new FormData(); inside the scope of the upload function. So, it is not available inside the submitForm function. What you are trying to log there is the Object prototype for FormData, and it would not contain any useful information.
In order to try again you need to refactor your code :
complexForm : FormGroup;
// Declare the object here
private formData: FormData = new FormData();
constructor(fb: FormBuilder){
this.complexForm = fb.group({
'name': [],
'file1':[],
'file2':[]
});
}
fileChanged(e: Event) {
debugger;
var target: HTMLInputElement = e.target as HTMLInputElement;
for(var i=0;i < target.files.length; i++) {
this.upload(target.files[i]);
}
}
upload(uploads: File) {
debugger
// now reference the instance
this.formData.append('file', uploads, uploads.name);
console.log(formData);
}
submitForm(values){
console.log(values);
// Check the formData instance
console.log(this.formData);
}
I have downloaded JQuery Multiple file uploader from this site
http://www.fyneworks.com/jquery/multiple-file-upload/
I need to check whether the file input field is null or not before submitting the form.
<form onsubmit="return validate();">
<input type="file" name="File" class="multi" />
<input type="file" name="File" class="multi" />
<input type="submit" name="BtnSubmit" value="save" />
</form>
I tried
function validate() {
$(".multi").each(function () {
var multi = $(this).val();
if (multi) {
return true;
} else {
return false;
}
});
}
Not working because the filed is always empty. So is there any other way to achieve this ?
try this
var multi = $(".multi").val();
if (multi) {
console.log("multi");
} else {
console.log("no multi");
}
fiddle:
http://jsfiddle.net/w4qVv/
UPDATE:
or you can do it like this
function validate(field) {
var fieldVal = $(field).val();
if(!fieldVal) alert("No files selected");
}
and then:
validate(".multi");
fiddle:
http://jsfiddle.net/jk8aZ/
UPDATE2:
yep, you can use each like this
var multi = (".multi");
$(multi).each(function () {
validate(this);
});
fiddle:
http://jsfiddle.net/jk8aZ/1/
I have the following html code :
<form name="uploadForm" action="" method="POST" enctype="multipart/form-data">
<input type="file" name="file_sub[]" />
<input type="file" name="file_sub[]" />
<input type="file" name="file_sub[]" />
<input type="file" name="file_sub[]" />
<input type="file" name="file_sub[]" />
<input type="button" onClick="javascript:submitform();" value="SUBMIT BTN" />
</form>
and here is the javascript function submitform() :
function submitform()
{
var minUpload = 1;
var uploadNo;
var count=document.uploadForm.file_sub.length;
for(a=0;a<count;a++)
{
if(document.uploadForm.file_sub.value != '')
{
uploadNo++;
}
}
if(uploadNo > minUpload){
document.uploadForm.submit();
}else{
alert('Please Upload Atleast ' + minUpload + ' files');
}
}
the javascript is suppose to validate and make sure atleast minUpload of the the file fields a file inside them.
but for some reason when I try to get the length of the file in the function I get an error (according to the debugger of chrome, I get "Uncaught TypeError: Cannot read property 'length' of undefined" ) however I have tried the same thing with checkboxes and it works just fine. What am I doing wrong? is it even possible to do such task in js?
You have to refer to file_sub[]. Fixed function:
var count = document.uploadForm["file_sub[]"].length;
function submitform(){
var minUpload = 1;
var uploadNo;
var files = document.forms['uploadForm']["file_sub[]"];
var count = files.length;
for(var a=0; a<count; a++){
if(files[a].value != ''){
uploadNo++;
}
}
if(uploadNo > minUpload){
document.forms['uploadForm'].submit();
} else {
alert('Please Upload Atleast ' + minUpload + ' files');
}
}