Laravel: Dropzone js, getting [object Object], but why? - laravel

I'm trying to upload an image using Dropzone.js in Laravel, but I'm getting an error showing [object Object] on my thumbnails after uploading a photo. I can't find my error and I don't understand what the cause is.
Here is my code and an image of the error. Why is this happening? What can I do?
View:
<div class="container col-md-8 col-12 mx-auto">
<div class="row">
<div class="col-sm-10 offset-sm-1">
<h2 class="page-heading">Upload your Images <span id="counter"></span></h2>
<form method="post" action="{{ url('/addimage') }}"
enctype="multipart/form-data" class="dropzone" id="my-dropzone">
{{ csrf_field() }}
<div class="dz-message">
<div class="col-xs-8">
<div class="message">
<p>Drop files here or Click to Upload</p>
</div>
</div>
</div>
<div class="fallback">
<input type="file" name="file" multiple>
<input type="hidden" name="id" value="{{$id}}" >
</div>
</form>
</div>
</div>
</div>
Route:
Route::group(['middleware'=>'auth'], function (){
...
Route::post('/addimage', 'FrontendController#addimage');
Route::post('/adddeleteimage', 'FrontendController#adddeleteimage');
...
});
Controller:
public function addimage(Request $request){
$file = $request->file('file');
$filename = uniqid().".".$file->clientExtension();
$file->move('img/product', $filename);
$dropzone = new Imagedb;
$dropzone->product_id = $request->id;
$dropzone->url = 'img/product'.$filename;
$dropzone->save();
}
JS:
var total_photos_counter = 0;
Dropzone.options.myDropzone = {
uploadMultiple: true,
parallelUploads: 2,
maxFilesize: 16,
acceptedFiles: "image/*",
resizeWidth: 360,
previewTemplate: document.querySelector('#preview').innerHTML,
addRemoveLinks: true,
dictRemoveFile: 'Remove file',
dictFileTooBig: 'Image is larger than 16MB',
timeout: 10000,
init: function () {
this.on("removedfile", function (file) {
$.post({
url: '/adddeleteimage',
data: {id: file.name, _token: $('[name="_token"]').val()},
dataType: 'json',
success: function (data) {
total_photos_counter--;
$("#counter").text("# " + total_photos_counter);
}
});
});
},
success: function (file, done) {
total_photos_counter++;
$("#counter").text("# " + total_photos_counter);
}
};

Firstly, try
$('meta[name="csrf-token"]').attr('content')
as token

I fixed this error by adding in head tag
<meta name="csrf-token" content="{{ csrf_token() }}">
and in dropzone initialization config
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
Example:
autoProcessQueue:false,
required:true,
acceptedFiles: ".png,.jpg,.gif,.bmp,.jpeg",
addRemoveLinks: true,
maxFiles:8,
parallelUploads : 100,
maxFilesize:5,
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }

Related

How get quill and other form to JS submit function?

I wanna use quill rich editor and other fields on my form. But cant get access to quill innerHTML from JS function. I am using Laravel with Alpinejs and my code is
<form x-data="contactForm()" #submit.prevent="submit">
<div class="col-12">
<div class="mt-2 w-100 bg-white" wire:ignore>
<div
x-data
x-ref="quillEditor"
x-init="
quill = new Quill($refs.quillEditor, {
theme: 'snow',
modules: {toolbar: '#toolbar'}
});
quill.on('text-change', function () {
$dispatch('input', quill.root.innerHTML);
});"
wire:model.debounce.2000ms="description"
class="sign__textarea"
style="height: 300px;"
>{{ old('description', $services_users->description) }}
</div>
</div>
</div>
<div class="col-12">
<input name="message" x-model="data.title">
</div>
<div class="col-12 col-xl-3 mt-5">
<button type="submit" x-text="buttonText" :disabled="loading"></button>
</div>
</form>
<script>
function contactForm() {
return {
data: {
title: "",
myQuill: quill.root.innerHTML,
},
buttonText: "Save",
loading: false,
submit() {
this.buttonText = "Saving...";
this.loading = true;
fetch('myurl.endpoint', {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify(this.data),
}).then(() => {
alert("Form submitted");
}).catch(() => {
alert("Something went wrong");
}).finally(() => {
this.data.title = ""
this.buttonText = "Save";
this.loading = false;
});
},
};
}
</scirpt>
Now i have an error Can't find variable: quill how can i get all fields from form and send to backend event if quill is not a form field?
It doesn't work because you're calling the variable "quill" in the parent and you're declaring it in the child. To fix it declare the x-init directive in the form.
listening to the "text-change" event is not necessary. A good option is to add the content of the container before submitting the form.
see : https://alpinejs.dev/directives/data#scope
<form x-data="contactForm()" x-init="
quill = new Quill($refs.quillEditor, {
theme: 'snow'
});
quill.on('text-change', function () {
$dispatch('input', quill.root.innerHTML);
});" #submit.prevent="submit">
<div class="col-12">
<div class="mt-2 w-100 bg-white" wire:ignore>
<div
x-ref="quillEditor"
wire:model.debounce.2000ms="description"
class="sign__textarea"
style="height: 300px;"
>{{ old('description', $services_users->description) }}
</div>
</div>
</div>
<div class="col-12">
<input name="message" x-model="data.title">
</div>
<div class="col-12 col-xl-3 mt-5">
<button type="submit" x-text="buttonText" :disabled="loading"></button>
</div>
</form>
<script>
function contactForm() {
return {
quill:null,
data: {
title: "",
// myQuill: function(){ return this.quill.root.innerHTML}
},
buttonText: "Save",
loading: false,
submit() {
this.buttonText = "Saving...";
//add content quill here
this.data.myQuill = this.quill.root.innerHTML;
this.loading = true;
fetch('myurl.endpoint', {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify(this.data),
}).then(() => {
alert("Form submitted");
}).catch(() => {
alert("Something went wrong");
}).finally(() => {
this.data.title = ""
this.buttonText = "Save";
this.loading = false;
});
},
};
}
</script>
Ok this is what i did
<form x-data="contactForm()" x-init="initQuill()" x-on:submit="submit()" method="POST" action="target.url">
<div x-ref="editor"></div>
<input x-ref="editorValue" type="hidden" name="hidden_input">
<button>Save</button>
</form>
<script>
function contactForm(){
return {
initQuill(){
new Quill(this.$refs. editor, {theme: 'snow'});
},
submit(){
console.log(this.$refs. editor.__quill.root.innerHTML);
this.$refs.editorValue.value = this.$refs.editor.__quill.root.innerHTML;
}
}
}
</script>
Now is ok and works with basic. You can extend function with new features etc. Thx for help guys.

Why my page gets refresh while deleting image on 'product edit page'?

VIEW FILE
<div class="col-sm-4">
<label>Other Images</label>
<div class="input-group control-group img_div form-group" >
<input type="file" name="image[]" class="form-control">
<div class="input-group-btn">
<button class="btn btn-success btn-add-more" type="button">Add</button>
</div>
</div>
</div>
<div>#foreach($image as $image)
<p><img src="{{asset('/files/'.$image->images)}}" height="50px" id="{{$image->id}}" class="photo"/>
<button class="removeimg" data-id="{{$image->id}}" data-token="{{ csrf_token() }}">Remove</button></p>
#endforeach
</div>
AJAX
$(document).ready( function () {
$(document).on('click', '.removeimg',function(){
var confirmation = confirm("are you sure to remove this record?");
if (confirmation) {
var id = $(this).data("id");
// console.log(id)
var token = $(this).data("token");
var $obj = $(this);
$.ajax(
{
url: "{{ url('image/delete') }}/"+id,
type: 'post',
dataType: "JSON",
data: {
"id": id,
"_token": token,
},
success: function (res)
{
// $(this).parents('.photo').remove();
$obj.parents('.photo').remove();
console.log("it Work", res);
}
});
console.log("It failed");
}
});
});
CONTROLLER
public function imgdelete($id){
Image::find($id)->delete($id);
return response()->json([
'success'=> 'Image deleted successfully!'
]);
}
When I delete the image, page gets redirected to product listing. Page should not get refresh when I delete the image. Can you please help me with correction?? NOTE: This process takes place on editproduct page.
You can prevent the default event for the button:
$(document).on('click', '.removeimg',function(event){
event.preventDefault();
.....
});

Laravel How to handle file upload: Can't save image filename

So I want to upload a picture but it only store its description correctly. The file is stored as "noimage.jpg" which means the filename isn't read. I'm using modal btw. My database is named galleries and the migration contains these:
$table->id();
$table->timestamps();
$table->string('upload');
$table->longtext('description')->nullable();
CONTROLLER:
public function store(Request $request)
{
$galleries=new Gallery;
// Handle File Upload
if($request->hasFile('upload')){
// Get filename with the extension
$filenameWithExt = $request->file('upload')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('upload')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.$extension;
// Upload Image
$path = $request->upload('upload')->storeAs('public/upload', $fileNameToStore);
// make thumbnails
$thumbStore = 'thumb.'.$filename.'_'.time().'.'.$extension;
$thumb = Image::make($request->file('upload')->getRealPath());
$thumb->save('storage/upload/'.$thumbStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
$galleries->description = $request->input('description');
$galleries->upload = $fileNameToStore;
$galleries->save();
}
FORM:
<form id="uploadForm">
<div class="modal-body">
<input type="hidden" name="id" id="id">
<!-- Upload image input-->
<div class="input-group mb-3 px-2 py-2 rounded-pill bg-secondary shadow-sm">
<input type="file" name="upload" id="upload" onchange="readURL(this);" class="form-control border-0">
<label id="upload-label" for="upload" class="font-weight-light text-muted">Choose file</label>
<div class="input-group-append">
<label for="upload" class="btn btn-light m-0 rounded-pill px-4"> <i class="fa fa-cloud-upload mr-2 text-muted"></i><small class="text-uppercase font-weight-bold text-muted">Choose file</small></label>
</div>
</div>
<!-- Uploaded image area-->
<p class="font-italic text-white text-center">The image uploaded will be rendered inside the box below.</p>
<div class="image-area mt-4 bg-white"><img id="imageResult" src="#" alt="" class="img-fluid rounded shadow-sm mx-auto d-block"></div>
<label>Caption</label>
<input type="textarea" class="form-control text-white" name="description" id="description">
</div>
</form>
AJAX
<script>
$(document).ready(function(){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//ADD PICTURE
$('#btnUpload').click(function(){
$('#uploadModal').modal('show');
});
$('#btnSave').click(function(){
$.ajax({
data: $('#uploadForm').serialize(),
url: "{{ route('home.store') }}",
type: "POST",
dataType: 'json',
success: function(data){
$('#uploadModal').modal('hide');
},
error: function(data){
console.log('Error:', data);
}
});
});
//Image reader to show pic when selected
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#imageResult')
.attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}
$(function () {
$('#upload').on('change', function () {
readURL(input);
});
});
var input = document.getElementById( 'upload' );
var infoArea = document.getElementById( 'upload-label' );
input.addEventListener( 'change', showFileName );
function showFileName( event ) {
var input = event.srcElement;
var fileName = input.files[0].name;
infoArea.textContent = 'File name: ' + fileName;
}
});
</script>
Assuming you're using ajax to upload the file, you'll need to use a FormData object instead of .serialize()
$.ajax({
data: new FormData($('#uploadForm').get(0)), // use formdata object
url: "{{ route('home.store') }}",
type: "POST",
dataType: 'json',
contentType: false, // required for
processData: false, // jquery ajax file upload
success: function(data){
$('#uploadModal').modal('hide');
},
error: function(data){
console.log('Error:', data);
}
});
You don't add "enctype" in form tag.
Change your code:
<form id="uploadForm">
with:
<form id="uploadForm" enctype='multipart/form-data'>
If this above not working then:
1.install this package by following command:
composer require "laravelcollective/html":"^5.2.0"
2.In config/app add this line:
'providers' => [
// ...
**Collective\Html\HtmlServiceProvider::class,**
// ...
],
and
'aliases' => [
// ...
**'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,**
// ...
],
3.Change Form:
{!! Form::open([ 'action'=> 'NameofController#store', 'method' => 'POST','enctype' => 'multipart/form-data' ]) !!}
<div class="form-group">
{{Form::text('name','' , ['class' =>'form-control'])}}
</div>
<div class="form-group">
{{Form::text('phone','' , ['class' =>'form-control', 'placeholder' => 'phone' ])}}
</div>
<div class="form-group">
{{Form::file('image_name')}}
</div>
{{Form::submit('Submit' , ['class' =>'btn btn-primary' ])}}
{!! Form::close() !!}
you can this way to store your file with custom name:
$path = $request->file('upload')->store('public/upload/' .$fileNameToStore);

Ajax request for delete image doesnt work in laravel

I want to delete the image in the preview box, as well as delete it in the database using ajax. Deleting the image in the preview box was successful, but deleting it from the database didn't work.
here my ajax:
$(document).ready(function() {
document.getElementById('pro-image').addEventListener('change', readImage, false);
$(".preview-images-zone").sortable();
$(document).on('click', '.image-cancel', function() {
let no = $(this).data('no');
let idData = $(this).data('id');
$(".preview-image.preview-show-" + no).remove();
$.ajax({
type: 'POST',
url: '{{url("unit/API/simpan")}}',
data: {
'id': idData
},
success: function(data) {
alert('success');
}
});
});
});
My Html:
<!-- Percobaan Preview -->
<fieldset class="form-group">
<div class="offset-md-2 col-md-6">
Upload Gambar
<input type="file" id="pro-image" name="gambarku[]" style="display: none;" class="form-control" multiple>
</div>
</fieldset>
<div class="preview-images-zone offset-md-2 col-md-8">
<!-- Gambar Utama -->
<div class="preview-image preview-show-1">
<div class="image-cancel" data-no="1">x</div>
<div class="image-zone"><img id="pro-img-1" src="{{asset('storage/rumah/'.$rumahku->gambar_rumah)}}"></div>
</div>
<!-- Gambar Tambahan -->
<?php $counter = 2 ?>
#foreach($rumahku->gambar as $rows)
<div class="preview-image preview-show-{{$counter}}">
<div class="image-cancel" data-no="{{$counter}}" data-id="{{$rows->id_gambar}}">x</div>
<div class="image-zone"><img id="pro-img-{{$counter}}" src="{{asset('storage/rumah/'.$rows->gambar_unit)}}"></div>
</div>
<?php $counter++ ?>
#endforeach
</div>
<!-- /preview -->
my route
Route::post('unit/API/simpan/{id}', 'partner\UnitController#simpanGambar');
my controller
public function simpanGambar($id)
{
$gambar = Gambar::find($id);
$gambar->delete();
}
you can try this
Route::post('unit/API/simpan', 'partner\UnitController#simpanGambar');
and
public function simpanGambar(Request $request)
{
$gambar = Gambar::find($request->id);
$gambar->delete();
}
or in ajax
$.ajax({
type: 'POST',
url: '{{url("unit/API/simpan")}}' +'/'+ id, <---------- pass id here

Laravel Image Upload using ajax 500 Internal Server Error

I am trying to upload image using ajax in laravel 5.2.but still i am getting error 500 Internal Server Error in route.
when i am trying to upload image using ajax request the browser shown correct route path but still i am not getting reason why it still showing error to me.
HTML
<!-- CHANGE AVATAR TAB -->
<div class="tab-pane" id="tab_1_2">
<div class="uploadimagediv"></div>
{{ Form::open(array('url' => 'admin/avatar','method'=>'post','files'=>'true','id'=>'updateprofileimage')) }}
<div class="form-group">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt=""/>
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;">
</div>
<div>
<span class="btn default btn-file">
<span class="fileinput-new">
Select image </span>
<span class="fileinput-exists">
Change </span>
<p class="text-danger" id="error_image"></p>
<input type="file" id="picture" name="picture"/>
{{--{{ Form::file('picture') }}--}}
</span>
<span class="error alert-danger">{{ $errors->first('picture') }}</span>
<a href="javascript:;" class="btn default fileinput-exists" data-dismiss="fileinput">
Remove </a>
</div>
</div>
<div class="clearfix margin-top-10">
</div>
</div>
<div class="margin-top-10">
{{Form::hidden('id', 2, ["id"=>"id"])}}
{{ Form::button('Upload',['id'=> 'updatepicture','class'=>'btn green-haze']) }}
{{--{{ Form::submit('Submit',['class' => 'btn green-haze','name'=>'changeImage']) }}--}}
<a href="javascript:;" class="btn default">
Cancel </a>
</div>
{{ Form::close() }}
</div>
<!-- END CHANGE AVATAR TAB -->
Route
Route::group(['prefix' => 'admin'], function ()
{
Route::controller('/','DashboardController');
});
Ajax
$(document).on('click', '#updatepicture', function($e)
{
$e.preventDefault();
// send an ajax request
$("#error_image").empty();
$.ajax(
{
url: 'avatar',
processData: false,
contentType: false,
type: "post",//use for update
data: new FormData($("#updateprofileimage")[0]),
success: function(data)
{
if(data.status)
{
$("#uploadimagediv").html('<div class="alert alert-success"><button type="button" class="close">×</button>'+data.message+'</div>');
window.setTimeout(function()
{
$(".alert").fadeTo(500, 0).slideUp(500, function()
{
$(this).remove();
});
}, 5000);
$('.alert .close').on("click", function(e)
{
$(this).parent().fadeTo(500, 0).slideUp(500);
});
//console.log(data);
//$("#updateprofileimage")[0].reset();
//window.location.href = "http://localhost/laravel/admin/profile";
}
else
{
errors = data.errors;
for(error in errors)
{
$("#error_"+error.title).html(error.message);
}
}
},
error: function(xhr)
{
if(xhr.status == 422)
{
errors = xhr.responseJSON;
for(error in errors)
{
$("#error_"+error).html(errors[error][0]);
}
}
}
});
});
Error is :"NetworkError: 500 Internal Server Error - http://localhost/laravel/admin/avatar"
please suggest me where i am getting wrong.
Controller is
public function postAvatar(ImageUploadRequest $request)
{
---
}
Add the below line inside <head>
<meta name="csrf-token" content="{{ csrf_token() }}">
And add the below lines before your ajax call in javascript function
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
And don't forget to give permission to your storage folder
sudo chmod -R 777 storage
In your ajax setup you have to provide x-csrf-token with the request. For your ajax request , also there is a problem with your url:
$(document).on('click', '#updatepicture', function($e)
{
$e.preventDefault();
// send an ajax request
$("#error_image").empty();
$.ajax(
{
url: "{{url('avatar')}}",
processData: false,
contentType: false,
type: "post",//use for update
data: new FormData($("#updateprofileimage")[0]),
headers: {
'X-CSRF-TOKEN': "{{ csrf_token() }}"
},
success: function(data)
{
if(data.status)
{
$("#uploadimagediv").html('<div class="alert alert-success"><button type="button" class="close">×</button>'+data.message+'</div>');
window.setTimeout(function()
{
$(".alert").fadeTo(500, 0).slideUp(500, function()
{
$(this).remove();
});
}, 5000);
$('.alert .close').on("click", function(e)
{
$(this).parent().fadeTo(500, 0).slideUp(500);
});
//console.log(data);
//$("#updateprofileimage")[0].reset();
//window.location.href = "http://localhost/laravel/admin/profile";
}
else
{
errors = data.errors;
for(error in errors)
{
$("#error_"+error.title).html(error.message);
}
}
},
error: function(xhr)
{
if(xhr.status == 422)
{
errors = xhr.responseJSON;
for(error in errors)
{
$("#error_"+error).html(errors[error][0]);
}
}
}
});
});

Resources