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

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

Related

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

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 5.5 Multilanguage validation

Please tell me, I ran into a problem. There is a site based on Laravel 5.5. The site has a multilanguage (two languages en/ru). For multilanguage I'm using:
dimsav/laravel-translatable
mcamara/laravel-localization
Added language files to the directory resources/lang/ru. The problem is the validation of the form. The site has a feedback form in the modal window, working with ajax (sending and validating), error messages are displayed only in the default language, the default language is en. I tried to send data from the form without the help of ajax, everything works well, messages are displayed in both Russian and English.
reoutes/web.php
Route::group(['prefix' => LaravelLocalization::setLocale()], function(){
Route::get('/', 'PagesController#getProfile')->name('profile');
Route::get('/skills', 'PagesController#getSkills')->name('skills');
Route::get('/portfolio', 'PagesController#getPortfolio')->name('portfolio');
Route::get('/resume', 'PagesController#getResume')->name('resume');
Route::post('/contact', 'PagesController#contact');
});
controller
public function contact(Request $request){
$validator = Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'message' => 'required'
]);
if ($validator->passes()) {
Mail::to('mycontactform#mail.ru')->send(new Contact($request));
return response()->json(['success'=>'Message sent successfully!']);
}
return response()->json(['error'=>$validator->errors()->all()]);
}
js
$(document).ready(function() {
$(".btn-send-message").click(function(e){
e.preventDefault();
$.ajax({
url: "/contact",
type:'POST',
data: $('#contact-form').serialize(),
beforeSend: function() {
$("#loading").show();
$(".fa-paper-plane").hide();
},
complete: function() {
$("#loading").hide();
$(".fa-paper-plane").show();
},
success: function(data) {
if($.isEmptyObject(data.error)){
printSuccessMsg();
}else{
printErrorMsg(data.error);
}
}
});
});
var $success_msg = $(".print-success-msg");
var $error_msg = $(".print-error-msg");
function printSuccessMsg() {
$success_msg.html('Message sent successfully!');
$success_msg.css('display','block');
$success_msg.delay(5000).fadeOut(350);
$('#contact-form')[0].reset();
}
function printErrorMsg (msg) {
$error_msg.find("ul").html('');
$error_msg.css('display','block');
$.each( msg, function( key, value ) {
$error_msg.find("ul").append('<li>'+value+'</li>');
});
$error_msg.delay(5000).fadeOut(350);
}
});
form
<div class="modal-body col-md-8 offset-md-2">
<div class="alert alert-danger print-error-msg" style="display:none">
<strong>Errors:</strong>
<ul></ul>
</div>
<div class="alert alert-success print-success-msg" style="display:none"></div>
{!! Form::open(['id'=>'contact-form']) !!}
<div class="form-group">
<input class="form-control" type="text" name="name" id="name" placeholder="Your Name">
</div>
<div class="form-group">
<input class="form-control" type="email" name="email" id="email" placeholder="Your Email">
</div>
<div class="form-group">
<textarea class="form-control" name="message" id="message" rows="3"></textarea>
</div>
<button type="button" class="btn btn-success btn-send-message"><i class="fas fa-paper-plane"></i>
Send Message <span id="loading" style="display: none;"><img class="loader"
src="{{ asset('images/loading.gif') }}"></span>
</button>
{!! Form::close() !!}
</div>
Use LaravelLocalization::getLocalizedURL() which returns an URL adapted to $locale.
So your ajax code will be.
$.ajax({
url: "{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(),'/contact') }}",
type:'POST',
data: $('#contact-form').serialize(),
beforeSend: function() {
$("#loading").show();
$(".fa-paper-plane").hide();
},
complete: function() {
$("#loading").hide();
$(".fa-paper-plane").show();
},
success: function(data) {
if($.isEmptyObject(data.error)){
printSuccessMsg();
}else{
printErrorMsg(data.error);
}
}
});
When you return your response try to use this helper __('translated_string')
To use this helper, you have to create some translate.php file in those folders resources/lang/en and resources/lang/en
For example:
File resources/lang/en/translate.php should contain this array
return [
'success_message' => 'Message sent successfully!',
];
File:
resources/lang/ru/translate.php should contain this array
return [
'success_message' => 'Сообщение успешно отправлено!',
];
For example:
return response()->json(['success'=> __('translate.success_message') ]);
To get some translated string, use dot notation for this helper;
Laravel localization helper

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

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

Laravel AJAX Form 405 Error

I'm receiving this error when attempting to submit via AJAX. When not using AJAX, the form submits just fine to it's specified url. I've read this error can happen because the form is trying to submit in the browser along with the AJAX request. I've tried using onsubmit="event.preventDefault()".
ROUTE:
Route::post('/post/{id}', [
'uses' => '\App\Http\Controllers\PostController#postMessage',
'as' => 'post.message',
'middleware' => ['auth'],
]);
FORM:
<form id="post" role="form" action="{{ route('post.message', ['id' => $user->id]) }}" onsubmit="event.preventDefault()">
<div class="feed-post form-group{{ $errors->has('post') ? ' has-error' : ''}}">
<textarea class="form-control feed-post-input" rows="2" id="postbody" name="post" placeholder="What's up?"></textarea>
<div class="btn-bar">
<!-- <button type="button" class="btn btn-default btn-img btn-post" title="Attach an image"><span class="glyphicon glyphicon-picture"></span></button> -->
<!-- <input type="file" id="img-upload" style="display:none"/> -->
<button class="btn btn-default btn-post" title="Post your message"><span class="glyphicon glyphicon-ok"></span></button>
</div>
#if ($errors->has('post'))
<span class="help-block">{{ $errors->first('post') }}</span>
#endif
</div>
<input type="hidden" name="_token" value="{{ CSRF_token() }}">
</form>
CONTROLLER:
public function postMessage(Request $request, $id)
{
$this->validate($request, [
'post' => 'required|max:1000',
]);
if(Request::ajax()){
Auth::user()->posts()->create([
'body' => $request->input('post'),
'profile_id' => $id
]);
}
}
JS:
$('#post').submit(function(){
var body = $('#postbody').val();
var profileId = $('#user_id').text();
var postRoute = '/post/'+profileId;
var dataString = "body="+body+"&profile_Id="+profileId;
$.ajax({
type: "POST",
url: postRoute,
data: dataString,
success: function(data){
console.log(data);
}
});
});
try this, remove
onsubmit="....." attribute from form
and update your submit method like this
$('#post').submit(function(event){
var body = $('#postbody').val();
var profileId = $('#user_id').text();
var postRoute = '/post/'+profileId;
var dataString = "body="+body+"&profile_Id="+profileId;
$.ajax({
type: "POST",
url: postRoute,
data: dataString,
success: function(data){
console.log(data);
}
});
//this will prevent your default form submit
event.preventDefault();
});
I hope this will work for you

Resources