I won't submit form on upload Javascript - javascript

Which part of function submit my form on upload image? I won't submit form on upload image. I want on submit button. Which part of code make mi problem? One think this code work okay , but I want submit form on upload photo automation. Also which part of my code maybe not need me for this time?
uploadFile(event) {
const formData = new FormData()
formData.append('image', event.target.files[0])
axios({
method: "post",
url: "linkmyapi",
data: formData,
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(response => {
this.items.push(response.data);
this.image = "";
this.profile_image = ''
this.loading = false
this.dragAndDropUpload = false
this.styleObject.backgroundColor = ''
})
.catch(error => {
this.loading = false;
},
onDropFile(e) {
this.dragAndDropUpload = true
e.stopPropagation()
e.preventDefault()
let files = e.dataTransfer.files
this.createFile(files[0])
},
onChangeFile(e) {
// this.manualUpload = true
let files = e.target.files;
this.createFile(files[0])
},
createFile(file) {
if (!file.type.match('image.*')) {
alert('Select an image')
return
}
let reader = new FileReader()
let vm = this
reader.onload = function (e) {
vm.profile_image = e.target.result
}
reader.readAsDataURL(file)
this.uploadFile(event)
},
removeFile() {
this.profile_image = ''
this.styleObject.backgroundColor = ''
},
onDragOver () {
this.styleObject.backgroundColor = 'rgba(0, 160, 223, 0.4)'
},
onDragLeave () {
this.styleObject.backgroundColor = ''
},
HTML is
<div class="upload-container">
<div
:style="styleObject"
class="drop drop-profile"
id="2"
#dragover.prevent="onDragOver()"
#dragleave.prevent="onDragLeave()"
#drop="onDropFile($event)"
:class="{ 'loading-image': loading }">
<label v-if="!profile_image" class="label-text label-text-profile">
Choose or drag
<br> and drop your
profile image
here
<br>
<input
type="file"
name="profile_image"
#change="onChangeFile($event)">
</label>
<div v-else class="hidden">
<img :src="profile_image" alt="Profile image" class="image-profile" />
<div v-if="!loading" class="lc-loupe-trash-container">
<div #click="removeFile" class="lc-trash"></div>
</div>
</div>
</div>
<div v-if="loading" class="spinner-container">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>

Your question isn't so clear, can you try editing it to be a little clearer? Do you want to automatically upload onDrop into drop area or you want to upload onClick of submit button?

Related

VUE(NUXT), upload button:, How it must not refresh when taking picture in IOS webview?

I have a Vue Project that will take photo from Gallery,.. the project is being also used in IOS and Android Webview,. the problem is on the IOS,.. when after taking a picture it will refresh the page. But photo library and other selection are working. Does anyone know how should be solve this?
this is the takephoto in IOS:
this is the code:
<div class="style_value text-left">
<input ref="ImageFileHiddenInput" accept="image/x-png,image/gif,image/jpeg" #change="onFileChange" type="file" name="image_file" style="display: none" />
<button #click="$refs.ImageFileHiddenInput.click()" class="m-1" type="button" size="mini"><i class="fas fa-cloud-upload-alt"></i> Upload</button>
</div>
onFileChange(e) {
const file = e.target.files[0];
this.imageFile = file;
this.uploadImage();
},
uploadImage() {
if (this.imageFile) {
var bodyFormData = new FormData();
bodyFormData.append("UploadFile", this.imageFile);
this.$axios
.post(`/upload-photo-file-url`, bodyFormData)
.then((res) => {
console.log('success')
})
.catch((err) => {
console.error(err);
});
}
},

Page reload on a form submit! Rails API backend Javascript frontend

I'm having trouble figuring out my javascript. The e.preventDefault() is not working. I've tried changing the submit input to a button as well. I know with a form and using rails that it has an automatic rage reload but I thought e.preventDefault was suppose to stop that. Is there some hidden feature in the backend that I need to turn off? I set my project up to be an api by using an api flag. It also has all the right info for cors. My server is showing my data correctly ...it's just the frontend I cant get up.
I'm going to post a sample code I followed.
<html lang="en" dir="ltr">
<head>
<title>Problems</title>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
<script type="application/javascript" src="src/user.js" charset="UTF-8"></script>
<script type="application/javascript" src="src/problem.js" charset="UTF-8"></script>
</head>
<body>
<div class="container" id="container">
<h1>Everyone Has Problems</h1>
<div id="new-user-and-new-problem-container">
<form id="new-user-form">
<label>Your name:</label>
<input type="text" id="new-user-body"/>
<input type="submit"/>
</form>
</div>
</div>
<div id="problems-container" class="problems-container">
</div>
</body>
</html>```
src/user.js
```document.addEventListener('DOMContentLoaded', function(){
User.createUser()
})
class User {
constructor(user){
this.id = user.id
this.name = user.name
this.problems = user.problems
}
static createUser(){
let newUserForm = document.getElementById('new-user-form')
newUserForm.addEventListener('submit', function(e){
e.preventDefault()
console.log(e);
fetch('http://localhost:3000/api/v1/users', {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(
{
user: {
name: e.target.children[1].value
}
})
})
.then(resp => {
return resp.json()
})
.then(user => {
let newUser = new User(user)
newUser.displayUser()
})
})
}
displayUser() {
let body = document.getElementById('container')
body.innerHTML = ''
let userGreeting = document.createElement('p')
userGreeting.setAttribute('data-id', this.id)
let id = userGreeting.dataset.id
userGreeting.innerHTML = `<h1>Hey, ${this.name}!</h1>`
body.append(userGreeting)
if (this.problems) {
this.problems.forEach(function(problem){
let newProblem = new Problem(problem)
newProblem.appendProblem()
})
}
Problem.newProblemForm(this.id)
}
}```
src/problem.js
```class Problem {
constructor(problem){
this.id = problem.id
this.name = problem.name
this.description = problem.description
}
static newProblemForm(user_id) {
let body = document.getElementById('container')
let form =
`
<form id="new-problem-form">
<label>What's your problem?:</label>
<input type="text" id="problem-name"/>
<label>Describe it:</label>
<input type="text" id="problem-description"/>
<input type="submit"/>
<h4>Your current problems:</h4>
</form>
`
body.insertAdjacentHTML('beforeend', form)
Problem.postProblem(user_id)
}
//is it appropriate for this to be a static method?
static postProblem(user_id) {
let newForm = document.getElementById('new-problem-form')
newForm.addEventListener('submit', function(e){
e.preventDefault()
fetch('http://localhost:3000/api/v1/problems', {
method: "POST",
headers:{
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(
{
problem: {
name: e.target.children[1].value,
description: e.target.children[3].value,
user_id: user_id
}
}
)
})
.then(resp => resp.json())
.then(json => {
let newProblem = new Problem(json)
newForm.reset()
newProblem.appendProblem()
})
})
}
appendProblem(){
let problems = document.getElementsByClassName('problems-container')
let li = document.createElement('li')
li.setAttribute('data-id', this.id)
li.setAttribute('style', "list-style-type:none")
li.innerHTML = `${this.name} ~~ ${this.description}`
let solveForm = `<button type="button" id="${this.id}" class="solve-problem"> Solve </button>`
li.insertAdjacentHTML('beforeend', solveForm)
problems[0].append(li)
let button = document.getElementById(`${this.id}`)
this.solve(button)
}
solve(button){
button.addEventListener('click', function(e){
e.preventDefault()
fetch(`http://localhost:3000/api/v1/problems/${e.target.parentNode.dataset.id}`, {
method: "DELETE"
})
e.target.parentElement.remove();
})
}
}```
Try not splitting the element up.
document.getElementById('new-problem-form').
addEventListener('submit', function(e){
e.preventDefault()
}
even Jquery
$('#new-problem-form').addEventListener('submit', function(e){
e.preventDefault()
});
The preventDefault is working on the event..
Take this for example:
$('#message').keydown(function (e) {
if (e.keyCode == 13) {
e.preventDefault();
return false;
}
});
This is preventing the enter key from defaulting the submit based on the keydown function. Is this option the actual 'default' you're trying to stop?

FormData Object not receiving file

I am trying to create an avatar editor following the Build a Forum video series.
I am on Laravel 5.8.34.
The console.log in the method #handleFileUpload(e)# shows the file uploaded.
The uploaded image appears on the page.
The console.log in the method #persist(file)# shows an empty object.
DATA FormData {}
The upload does not persist.
My Controller Method:
public function avatar_upload($id)
{
$validate = request()->validate([
'avatar' => ['required', 'image']
]);
$emp = Employee::with('user')->where('user_id', $id)->first();
$avatar = $emp->user->firstName . $emp->user->lastName . '.png';
Storage::disk('spaces')
->putFileAs('avatars', request()->file('avatar'), $avatar, 'public');
$emp->avatar = $avatar;
$emp->save();
return response([], 204);
} // end function
My Component:
<template>
<div>
<div class="text-center mb-4">
<div class="flex justify-center font-thin text-grey-dark text-2xl">
{{user.office}}
</div>
<div class="text-center">
<img class="relative rounded-lg"
:src="avatar">
</div>
<form #submit.prevent="handleFileUpload"
enctype="multipart/form-data"
v-if="canEdit">
<input
type="file"
name="avatar"
ref="file"
accept="image/png"
class="tw-input"
#change="handleFileUpload">
</form>
</div>
</div>
</template>
<script type="text/babel">
export default {
name: 'AvatarReplace',
data() {
return {
canEdit: true,
avatar: this.user.avatar
};
},
props: ['user'],
methods: {
handleFileUpload(e) {
if(! e.target.files.length) { return; } // end if
let file = e.target.files[0];
console.log('FILE', file);
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = e => {
this.avatar = e.target.result;
};
this.persist(file);
},
persist(file) {
let data = new FormData();
data.append('avatar', file);
console.log('DATA', data);
let path = `/api/staff/avatar_upload/${this.user.id}`;
axios.post(path, data)
.then((rsp) => {
//console.log(rsp);
//this.$toastr.s('File Uploaded');
});
}
}
};
</script>
This is not a normal form, Make axios knows that content-type is multipart/form-data
axios.post(path, data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then((response) => {
//
});

Rendering a dynamic array of input

I'm trying to render a dynamic FormArray (When "+" is clicked it should add a new), but always when I put some file in the input box the Message ("Nenhum Arquivo Selecionado" which means "File Doesn't Exist") stays on the screen.
However, if I check the info on this.filterForm.get('Documents'), the row is filled correctly.
Does anyone have a sugestion to fix this error?
protocolo.component.ts
items: FormArray;
filterForm = new FormGroup({
IdProtocolo: new FormControl(),
Documentos: this.formBuilder.array([ this.createItem() ]
);
ngOnInit() {
this.items = this.filterForm.get('Documentos') as FormArray;
}
createItem(): FormGroup{
return this.formBuilder.group({
filename: '',
filetype: '',
value: ''
})
}
addItem(){
this.items.push(this.createItem());
}
removeItem(index){
if(this.items.length > 1) {
this.items.removeAt(index);
}
}
onFileChange(event: any, index: any) {
let reader = new FileReader();
if(event.target.files && event.target.files.length > 0) {
let file = event.target.files[0];
reader.readAsDataURL(file);
this.items.at(index).patchValue({
filename: file.name,
filetype: file.type,
value: (reader.result as string).split(',')[1]
})
}
}
protocolo.component.html
<div *ngFor="let item of filterForm.value.Documentos; let i = index;">
<div class="row" style="margin-bottom: 10px;">
<div class="col-md-4">
<input type="file" formControlName="Documentos" (change)="onFileChange($event, i)">
</div>
<div class="col-md-8">
<button class="btn btn-success-tce" (click)="addItem()">+</button>
<button class="btn btn-success-tce" (click)="removeItem(i)"style="margin-left: 5px">-</button>
</div>
</div>
[Updated] Possibly wrong implementation of formArray. I cannot see a formArrayName in your template. I would have implemented this like
In your template
<p> Dynamic File Form </p>
<form [formGroup]="someForm" (submit)="formSubmit()">
<div formArrayName="documents">
<div *ngFor="let item of files?.controls; let i = index;">
<input type="file" placeholder="Upload file" [formControlName]="i" (change)="onFileChange($event, i)"/>
</div>
</div>
<button type="submit"> Submit </button>
</form>
<button type="button" (click)="addFileControl()"> Add File </button>
In your component.
initForm() {
this.someForm = this.fb.group({
documents: this.fb.array([this.fileControl])
})
}
get files() {
return this.someForm.get('documents') as FormArray;
}
get fileControl() {
return this.fb.group({
file_item: [null]
})
}
addFileControl() {
this.files.push(this.fileControl);
}
formSubmit() {
console.log(this.someForm.value);
}
onFileChange(event, i) {
let reader = new FileReader();
if (event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.files.controls[i].get('file_item').setValue(reader.result);
// need to run CD since file load runs outside of zone
this.cd.markForCheck();
};
}
}
Here is the stackblitz example. This will give you the output in base64 format but you can also get it in file format by modifying.
onFileChange(event, i) {
if (event.target.files && event.target.files.length) {
this.files.controls[i].get('file_item').setValue(event.target.files;);
}
}
Note:- It is just a rough code but does the job :).

How to delete uploaded files from specific user

i'm using this http://www.dropzonejs.com/ in my create form
When user click "Click here to add files" the files are stored in Files/TempFile
but when user click submit on my create method i want to move all files from Files/TempFile to Files/TicketFile uploaded from the user, or if user click cancel to delete all files from Files/TempFile.
The problem is what if there are several user that trying to upload files in the same time. If one of the user click cancel or submit how to know which files to move or delete.
CREATE VIEW
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm("Create", "Ticket", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Ticket</legend>
<div class="editor-label">
#Html.LabelFor(model => model.idTicket)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.idTicket)
#Html.ValidationMessageFor(model => model.idTicket)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.idProject, "Project")
</div>
<div class="editor-field">
#Html.DropDownList("idProject", String.Empty)
#Html.ValidationMessageFor(model => model.idProject)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.tickettDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.tickettDescription)
#Html.ValidationMessageFor(model => model.tickettDescription)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.assignment, "User")
</div>
<div class="editor-field">
#Html.DropDownList("assignment")
#Html.ValidationMessageFor(model => model.assignment)
</div>
<div class="jumbotron">
<div class="dropzone" id="dropzoneForm" style="width: 50px; background: none; border: none;">
<div class="fallback">
<input type="file" id="fileInput" name="files" multiple="multiple" >
<input type="submit" id="submit" value="Upload" />
</div>
</div>
</div>
<div class="clear-fix"></div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
//File Upload response from the server
Dropzone.options.dropzoneForm = {
init: function () {
this.on("maxfilesexceeded", function (data) {
$.ajax({
url: '#Url.Action("SaveUploadedFile", "File", new { id=1})',
})
var res = eval('(' + data.xhr.responseText + ')');
});
this.on("addedfile", function (file) {
// Create the remove button
var removeButton = Dropzone.createElement("<button>Remove file</button>");
// Capture the Dropzone instance as closure.
var _this = this;
// Listen to the click event
removeButton.addEventListener("click", function (e) {
// Make sure the button click doesn't submit the form:
e.preventDefault();
e.stopPropagation();
// Remove the file preview.
$.ajax({
type: "POST",
url: '#Url.Action("RemoveFile","File")',
contentType: "application/json; charset=utf-8",
data: "{name:" + JSON.stringify(file.name) + "}",
dataType: "json",
success: function () { _this.removeFile(file); }
});
})
// Add the button to the file preview element.
file.previewElement.appendChild(removeButton);
});
}
};
</script>
Save Method
public ActionResult SaveUploadedFile()
{
bool isSavedSuccessfully = true;
string fName = "";
try
{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
//Save file content goes here
fName = file.FileName;
if (file != null && file.ContentLength > 0)
{
string path = Server.MapPath("~/Files/TempFile/") + file.FileName;
file.SaveAs(path);
}
}
}
catch (Exception ex)
{
isSavedSuccessfully = false;
}
if (isSavedSuccessfully)
{
return Json(new { Message = fName });
}
else
{
return Json(new { Message = "Error in saving file" });
}
}
i tried not to store to TempFile and when i click create to get all the files with
foreach (string fileName in Request.Files)
but Request.Files is always null.
While uploading your file to Files/TempFile add dummmy suffix to it to identify the user who is uploading the file eg. if user say "ABC" is uploading file "File1" then in your code for uploading file rename file as "File1_ABC". Similarly if user "PQR" is uploading "File1" then uploaded file in the folder should be "File1_PQR" now when user "ABC" click submit on your create method move file from Files/TempFile to Files/TicketFile having suffix as "_ABC".

Categories

Resources