Angular4 File upload with fom submission.? - javascript

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);
}

Related

I want to remove files from object

I created a multiple file upload form. And it shows me the list of files I'm about to upload once I've selected the files. and i made delete file button to remove files that have been deleted from the object but cannot be deleted
<input type="file" class="" id="fileInput" multiple onchange="displayFiles()" style="width: 85px">
function removeFile(index) {
var input = document.getElementById("fileInput");
Array.from(input.files).splice(index, 1);
displayFiles();
}
I tried this method and it didn't work.
function removeFile(index) {
var input = document.getElementById("fileInput");
delete input.files[index];
displayFiles();
}
please help me
Hopefully this small example helps, you could create an array of indices to skip which are used when uploading.
const get = str => document.querySelector(str);
get("#myFiles").addEventListener("change", e => {
get("#howMany").setAttribute("max", e.target.files.length);
});
get("#upload").addEventListener("click", () => {
const files = get("#myFiles").files;
const len = get("#howMany").value;
const data = new FormData();
for (let i = 0; i < len; i++) {
const targetFile = files[i];
data.append("files[]", targetFile, targetFile.name);
}
devFetch("testurl", {
method: "POST",
body: data
});
});
/* DEV FETCH EMULATE NORMAL FETCH FOR STACK SNIPPET, SHOULD JUST BE FETCH */
function devFetch(url, options) {
console.log("Posting to", url, "with method", options.method);
console.log("Body:");
console.log(options.body.getAll("files[]"));
}
<input id="myFiles" type="file" multiple /> <br />
<input id="howMany" type="range" min=0 max=0 /> <br />
<button id="upload">upload</button>

Object is possibly null. TypeScript error (angular typescript)

I want to add an image file to "convert" function.
this is my code from the component.html for the input:
<li>
<label for="avatarIMG" id="avatarLbL"> image: </label>
<input type="file" accept="image/*" #imageBox name="image" id="avatarinput" (change)="convert($event)">
<button type="button" id="avatarInputBTN" (click)="imageBox.click()"> Profile Picture </button>
</li>
the event suppose to send the values of the object with all of the values + the image file from the form to the component.ts and this is the code of it:
public convert(e: Event): void {
this.eventFiles = (e.target as HTMLInputElement).files[0];
if (this.eventFiles !== null) {
this.user.image = this.eventFiles;
const fileReader = new FileReader();
fileReader.onload = args => this.preview = args.target?.result?.toString();
fileReader.readAsDataURL(this.eventFiles);
}
}
i get an error of object possibly null for (e.target as HTMLInputElement).files[0].
how can i fix this?..
try this:
this.eventFiles = (e.target as HTMLInputElement)?.files?.[0];

Unable to pass Checkbox values to a database

I am building a simple form with text fields as well as an image upload and checkbox options.
I need people to be able to select multiple checkboxes, and those need to be passed to a database.
All the form fields are passing to the database with no issue, except for the Videos(checkbox) field.
Because of the nature of the form, I am required to use client side javascript to pass the form fields via json to SSJS.
At this point, the checkbox values do post to the console log, but they do not make their way to the database. Any help will be much appreciated.
var btn = document.getElementById("button");
btn.addEventListener("click", function() {
var files = document.getElementById("file").files;
if (files.length > 0) {
getBase64(files[0]);
}
});
function getChcked() {
var form = document.getElementById('myform');
var chks = form.querySelectorAll('input[type="checkbox"]');
var checked = [];
for(var i = 0; i < chks.length; i++){
if(chks[i].checked){
checked.push(chks[i].value)
}
}
return checked;
};
var Videos = '';
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
//prepare data to pass to processing page
var fileEncoded = reader.result;
var base64enc = fileEncoded.split(";base64,")[1];
var fullFileName = document.getElementById("file").files[0].name;
var fileName = fullFileName.split(".")[0];
var assetName = fullFileName.split(".")[1];
var AgencyName = document.getElementById("AgencyName").value;
var AgencyPhone = document.getElementById("AgencyPhone").value;
var AgencyEmail = document.getElementById("AgencyEmail").value;
var AgencyWebsite = document.getElementById("AgencyWebsite").value;
var Videos = console.log(getChcked());
fetch("processingpage", { //provide URL of the processing page
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
base64enc: base64enc,
fileName: fileName,
assetName: assetName,
AgencyName: AgencyName,
AgencyPhone: AgencyPhone,
AgencyEmail: AgencyEmail,
AgencyWebsite: AgencyWebsite,
Videos: Videos
})
});
};
}
<div class="form-group">
<label class="col-md-4 control-label" for="Videos">Select which video(s) you’d like co-branded:</label>
<div class="col-md-4">
<div class="checkbox">
<label for="Videos-0">
<input type="checkbox" name="Videos" id="Videos-0" value="The Flour Child">
The Flour Child
</label>
</div>
<div class="checkbox">
<label for="Videos-1">
<input type="checkbox" name="Videos" id="Videos-1" value="The Loose Tooth Situation">
The Loose Tooth Situation
</label>
</div>
console.log returns undefined, so you are assigning undefined to Videos
var Videos = console.log(getChcked()); // equivalent to var Videos=undefined;

drag and drop post multiples files

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.

Asp.net Mvc multiple file upload with ajax some errors

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.

Categories

Resources