Hi, I'm trying to make an image upload via laravel, everything is working but now I want to change the upload to an jquery upload instead but then I get an 500 internal server error
so when I handle things with Jquery it fails. Anyone knows what the problem might be?
html:
{{ Form::open(array('url' => '../public/posts/add', 'class'=>'form-horizontal', 'role' => 'form', 'id' => 'addPin', 'files' => true)) }}
<div id="validation-errors" class="alert alert-danger" hidden>
<p>Some errors occured</p>
<ul></ul>
</div>
<!-- Image Type -->
<span id="type-image" class="type-media">
<div class="form-group">
<label class="col-sm-3 control-label">Title</label>
<div class="col-sm-9">
{{ Form::text('Image-title', null, array('class' => 'form-control', 'placeholder' => '')) }}
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Choose file</label>
<div class="col-sm-9">
{{ Form::file('Image-file') }}
<p class="help-block">Only .jpg, .png, .gif, .bmp allowed.</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Description</label>
<div class="col-sm-9">
{{ Form::textarea('Image-description', null, array('class' => 'form-control', 'rows' => '3')) }}
</div>
</div>
</span>
<div class="modal-footer">
{{ Form::submit('Close', array('class' => 'btn btn-default', 'data-dismiss' => 'modal')) }}
{{ Form::submit('Pin it, babe!', array('class' => 'btn btn-info')) }}
</div>
{{ Form::close() }}
Jquery
addPin.on('submit', function() {
event.preventDefault();
var errorForm = addPin.find('div#validation-errors');
$.ajax({
url: '../public/posts/add',
type: 'post',
cache: false,
data: addPin.serialize(),
beforeSend: function() {
errorForm.hide();
errorForm.find("ul").empty();
},
success: function(data) {
if(data.success == false) {
var arr = data.errors;
console.log(arr);
$.each(arr, function(index, value){
if (value.length != 0){
errorForm.find("ul").append('<li>'+ value +'</li>');
}
});
errorForm.show();
} else {
location.reload();
}
},
error: function() {
alert('Something went to wrong.Please Try again later...');
}
});
return false;
} );
PHP
public function postAdd(){
if (Auth::check()){
$rules = array(
'Image-title' => 'Required|Min:3|Max:255|alpha_spaces',
'Image-description' => 'Required|Min:3',
'Image-file' => 'image',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return \Response::json(['success' => false, 'errors' => $validator->getMessageBag()->toArray()]);
} else {
$post = Post::create(array(
'user_id' => Auth::user()->id,
'title' => Input::get('Image-title'),
'description' => Input::get('Image-description'),
'type' => 'Image',
));
$file = Input::file('Image-file');
$destinationPath = 'img/';
$extension = $file->getClientOriginalExtension();
$filename = 'usr_'. Auth::user()->id . '_post'.$post->id .'.'. $extension;
$file->move($destinationPath, $filename);
$post->imgLocation = $filename;
$post->save();
DB::table('board_post')->insert(['board_id' => 2, 'post_id' => $post->id]);
return \Response::json(['success' => true]);//*/
}
}
}
You should have an error in your app/storage/logs/laravel.log file stating the exact error. Setting PHP to show all errors is preferable in a development environment tho, so you might want to consider turning those on, so you'll get a more descriptive message than just "500 Internal Server Error".
Check you upload_max_filesize in php.ini
Echo ini_get ("upload_max_filesize");
See this
The problem was due the fact that Jquery/JS don't really support Image upload
I fixed the problem by when you click on the button, the form get's validated (via ajax) and show the errors when there are, otherwise it does the normal form sending (the one if I wouldn't do the event.prefentdefault())
this works for now, prehaps I'll have a second look at it to make it completly AJax, but probably not :)
Related
I am new to Ajax I was following tutorial to send data to db using Ajax
here is my form
{!! Form::open(array('url'=>'admin/blog', 'method'=>'post', 'files'=>'true')) !!}
<div class="box-body">
<div class="form-group">
{!! Form::label('title', 'Title') !!}
{!! Form::text('title', '', array('placeholder'=>'Blog title', 'class'=>'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('paragraph', 'Blog Content') !!}
{!! Form::textarea('paragraph', '', array('class'=>'form-control', 'placeholder'=>'Enter Paragraph...', 'rows'=>3)) !!}
<script>
CKEDITOR.replace('paragraph', {
uiColor: '#9AB8F3',
stylesSet: 'my_custom_style'
});
</script>
</div>
<div class="form-group">
{!! Form::label('image', 'Main Image') !!}
{!! Form::file('image') !!}
<p class="help-block">Please review the upload instructions in 'Reminder!'</p>
</div>
</div>
<div class="box-footer">
{!! Form::submit('Add', array('class'=>'btn btn-primary', 'onClick'=>'send(event)')) !!}
</div>
{!! Form::close() !!}
and this is the Ajax I used
<script type="text/javascript">
function send(event) {
event.preventDefault();
$.ajax({
type: "POST",
url: "{{ 'admin/blog' }}",
data: {
title: $("#title").val(),
paragraph: $("#paragraph").val(),
image: $("#image").val(),
_token: "{{ Session::token() }}"
},
success:function(result)//we got the response
{
alert('Successfully called');
},
error:function(exception){alert('Exeption:'+exception);}
})
}
</script>
and here is the controller
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required',
'paragraph' => 'required|min:100',
'image' => 'required|image|mimes:jpeg,png',
]);
$add = new Blog();
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
Image::make($image)->resize(600, 390)->save(public_path('images/blog/' . $filename));
Image::make($image)->fit(335, 219)->save(public_path('images/blog/thumbs-' . $filename));
$add->image = $filename;
}
$add->title = $request->title;
$add->paragraph = $request->paragraph;
$add->addBy = \Auth::user()->name;
$add->save();
if ($request->ajax()) {
return response()->json();
}
return \Redirect::back();
}
when I try to click add I got
Error Exeption:[object Object]
Edit
In my routes I was using resource add new Route with POST method
Route::resource('blog', 'BlogController');
Route::post('blog', 'BlogController#store');
Changed the Ajax URL and the error results
url: "{{ url('admin/blog/store') }}",
error:function(exception){console.log(exception)}
in my console got this error
Object { readyState: 4, getResponseHeader:
.ajax/x.getResponseHeader(), getAllResponseHeaders:
.ajax/x.getAllResponseHeaders(), setRequestHeader:
.ajax/x.setRequestHeader(), overrideMimeType:
.ajax/x.overrideMimeType(), statusCode: .ajax/x.statusCode(), abort:
.ajax/x.abort(), state: .Deferred/d.state(), always:
.Deferred/d.always(), then: .Deferred/d.then(), 11 more… }
I had the same issue, solved by JSON.stringify(dataObject) before sending AJAX request.
I have a problem here. I am developing my web application and I want it to connect to my API through ajax. I am trying to send an image to my api through ajax from my form in the client side, which is the web.
So, here's my form in the client side..
{{ Form::open(['enctype' => "multipart/form-data", 'id' => 'addplant', 'method' => 'POST', 'files' => true, 'class' => 'col s12']) }}
{{ csrf_field() }}
<div class="row" style="margin-top:10%;">
<div class="col s12 center">
<img class="circle" id="image_url" src=""></a>
{!! Form::file('image_url', array('id' => 'image', 'class' => 'form-control')) !!}
</div>
</div>
<div class="row">
<div class="input-field col s6">
{{ Form::text('herbal_name', null, array('id' => 'herbal_name', 'class' => 'form-control validate')) }}
{{ Form::label('herbal_name', 'Herbal Name') }}
</div>
<div class="input-field col s6">
{{ Form::text('scientific_name', null, array('id' => 'scientific_name', 'class' => 'form-control validate')) }}
{{ Form::label('scientific_name', 'Scientific Name') }}
</div>
</div>
{{ Form::submit('Add plant', array('class' => 'btn btn-primary right add')) }}
{{ Form::close() }}
Here's my ajax, still in the client side
<script type="text/javascript">
$(".add").click(function() {
$.ajax({
url: 'http://127.0.0.1/identificare_api/public/api/plants',
data: new FormData($("#addplant")[0]),
type: "POST",
success: function( msg ) {
console.log(msg);
},
error: function(){
alert('pangit');
}
});
});
</script>
EDIT: and in my api, I just have this one
return json_encode($request->file('image_url'));
What am I missing here? Did I missed something?
UPDATE: I tried to apply the answer of #bfcior but when I try to console.log(base64img), it will return this very long string and it's longer than you expected.
click for image
I'm not entirely sure if this is the issue but aren't you supposed to be using a button instead of a submit? I'd imagine using a submit is preventing the ajax from working because the form is being submitted to the server for processing.
EDIT: What happens when you click the submit button? Telling us will help stackoverflow users diagnose the problem.
You handle the file by using:
$request->file('image_url');
https://laravel.com/docs/5.3/requests#files
Another approach is to convert img into base64 and pass it as a param. Then in your controller/route you can decode the base64 and save to a file (if is needed).
{{ Form::open(['enctype' => "multipart/form-data", 'id' => 'addplant', 'method' => 'POST', 'files' => true, 'class' => 'col s12']) }}
<div class="row" style="margin-top:10%;">
<div class="col s12 center">
<img class="circle" id="image_url" src=""></a>
{!! Form::file('image_url', array('id' => 'image', 'class' => 'form-control')) !!}
</div>
</div>
<div class="row">
<div class="input-field col s6">
{{ Form::text('herbal_name', null, array('id' => 'herbal_name', 'class' => 'form-control validate')) }}
{{ Form::label('herbal_name', 'Herbal Name') }}
</div>
<div class="input-field col s6">
{{ Form::text('scientific_name', null, array('id' => 'scientific_name', 'class' => 'form-control validate')) }}
{{ Form::label('scientific_name', 'Scientific Name') }}
</div>
</div>
{{ Form::submit('Add plant', array('class' => 'btn btn-primary right add')) }}
{{ Form::close() }}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
});
var base64img = null;
$(document).ready(function() {
$('#image').change(function(){
var file = this.files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
base64img = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
});
$(".add").click(function(e) {
e.preventDefault();
$.ajax({
url: 'http://127.0.0.1:8000/identificare_api/public/api/plants',
data: $("#addplant").serialize() + '&image_url=' + base64img,
type: "POST",
success: function( msg ) {
console.log(msg);
},
error: function(){
alert('pangit');
}
});
});
});
</script>
and route
Route::post('identificare_api/public/api/plants', function (Request $request) {
return json_encode($request->all());
});
I have this weird issue that I have never came across before ever since I started learning laravel.
I have a contact form: contact.blade.php
{!! Form::open(['url' => '/contact-form', 'id' => 'formContact']) !!}
<div class="col-md-12 col-sm-12 form-group">
{!! Form::label('full_name', 'Full Name:', ['class' => 'fw_400']) !!}
{!! Form::text('full_name', null, ['class' => 'form-control input-sm']) !!}
</div>
<div class="col-md-6 col-sm-6 form-group">
{!! Form::label('email', 'Email:', ['class' => 'fw_400']) !!}
{!! Form::text('email', null, ['class' => 'form-control input-sm']) !!}
</div>
<div class="col-md-6 col-sm-6 form-group">
{!! Form::label('contact', 'Contact Number:', ['class' => 'fw_400']) !!}
{!! Form::text('contact', null, ['class' => 'form-control input-sm']) !!}
</div>
<div class="col-md-12 col-sm-12 form-group">
{!! Form::label('contact_message', 'Contact Message:', ['class' => 'fw_400']) !!}
{!! Form::textarea('contact_message', null, ['class' => 'form-control input-sm', 'rows' => 5]) !!}
</div>
<div class="col-md-12 col-sm-12 form-group">
{!! Form::submit('Submit', ['class' => 'btn btn-primary btn-block btnContactOnContactPage']) !!}
</div>
{!! Form::close() !!}
When I click on the submit button, AJAX call is made.. Here's the ajax handler:
(function() {
$('#formContact').submit(function(e) {
$('.btnContactOnContactPage').prop('disabled', true);
var inputData = $('#formContact').serialize();
$.ajax({
url: $('#formContact').attr('action'),
type: 'POST',
data: inputData,
success: function(m) {
$('.btnContactOnContactPage').prop('disabled', false);
if (m.status === 'success') {
toastr.success(m.msg);
setTimeout(function() {
window.location.reload();
}, 3000)
}
},
error: function(e) {
if (e.status === 422) {
$('.btnContactOnContactPage').prop('disabled', false);
var errors = e.responseJSON;
var errorsHtml = '<div class="alert alert-danger"><ul>';
errorsHtml += '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>';
$.each(errors, function(key, value) {
errorsHtml += '<li class="text-danger">' + value[0] + '</li>';
});
errorsHtml += '</ul></div>';
$('.errors').html(errorsHtml);
}
}
});
return false;
});
})();
And the controller method:
public function postContact(Request $request)
{
$this->validate($request, [
'full_name' => 'required',
'email' => 'required|email',
'contact' => 'required|regex:/^[0-9+\-]+$/',
'contact_message' => 'required'
]);
if ($request->ajax()) {
$prevContactCode = DB::table('contact_messages')->latest()->limit(1)->pluck('cont_code');
if ($prevContactCode == "" || empty($prevContactCode)) {
$request['cont_code'] = 'CON-000001';
}
else {
$request['cont_code'] = ++$prevContactCode;
}
$contactMessage = ContactMessage::create($request->all());
$dataToMail = [
'cont_code' => $contactMessage->cont_code,
'full_name' => $contactMessage->full_name,
'email' => $contactMessage->email,
'contact' => $contactMessage->contact,
'contact_message' => $contactMessage->contact_message
];
$mail = Mail::send('emails.contact', $dataToMail, function ($message) use($dataToMail)
{
$message->from($dataToMail['email'], $dataToMail['full_name']);
$message->to('contact#example.com', 'Example Contact')
->subject('Contact Form Details from example.com (Form No.:' . $dataToMail['cont_code'] . ')')
->cc(['ex#example.net', 'exam#hotmail.com'])
->bcc(['examp#gmail.com', 'esmap#example.net']);
});
var_dump($mail); // displays **int 5** in chrome console
dd($mail); // displays **5** in chrome console
if ($mail) {
return response(['status' => 'success', 'msg' => 'Contact form details has been successfully submitted.']);
}
}
return response(['status' => 'failed', 'msg' => 'Something went wrong. Please try again later.']);
}
The issue is that, the mail is sent thrice instead of just once. I don't know what is happening here. Earlier [maybe 5 months back], it was working correctly, and now, all of a sudden, it started doing this. I am trying to figure out what is the reason behind this, but to no success. I have also updated the framework using composer update but the issue still exists.
EDIT 1: I was playing trial and error with the Mail facade, and I guess the issue is in bcc method, because I tried no bcc and cc, it worked as expected. Then again I tried with just cc and no bcc, this time also it worked correctly as expected but when added bcc with cc, I received the same mail thrice.
Where I have made the mistake ? Kindly help me out.
Some mail drivers, usually Mandrill, sends CC'ed & BCC'ed emails as separate emails instead of treating them as a single email.
I haven't used mailtrap, but same thing might be happening in your case too.
Common cause of this issue could be that click propogation is not prevented. Which means that even if you interact with other control placed on top could possibly send the request.
Another cause is that click method binding is happening more that one time. It happens when you are binding the click event once server response comes. In such case this is a common issue.
It would be great if you could try add console.log on click events which initializes request. And see how many times it gets logged.
Still if you can't narrow it down would be great if you could extract subset of code and post it on JSfiddle or something so others can take a look.
Hope it will help.
I'm still learning Laravel and trying to build some sort of an article management system. As part of form for inserting new articles I want to also upload multiple pictures of them. The upload shows success, yet there is no file in uploads folder. Here is my form code:
{!! Form::open(['route' => 'admin_artikli.store', 'class' => 'dropzone', 'id' => 'create_artikal', 'enctype' => 'multipart/form-data' ]) !!}
<div class="form-group">
{!! Form::label('Firma', 'Firma') !!}
{!! Form::text('firma_id', Input::old('firma_id'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('Naziv', 'Naziv') !!}
{!! Form::text('naziv', Input::old('naziv'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('Opis', 'Opis') !!}
{!! Form::text('opis', Input::old('opis'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('Cijena', 'Cijena') !!}
{!! Form::text('cijena', Input::old('cijena'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('kolicina', 'kolicina') !!}
{!! Form::text('kolicina', Input::old('kolicina'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::label('dostupnost', 'dostupnost') !!}
{!! Form::text('dostupnost', Input::old('dostupnost'), array('class' => 'form-control')) !!}
</div>
<div class="form-group">
{!! Form::select('aktivan', array('D' => 'Aktivan', 'N' => 'Neaktivan'), 'D') !!}
</div>
<div class="form-group">
{!! Form::select('aktivan', array('D' => 'Aktivan', 'N' => 'Neaktivan'), 'D') !!}
</div>
{!! Form::submit('Kreiraj artikal', array('class' => 'btn btn-primary', 'id' => 'create_artikal_submit')) !!}
{!! Form::close() !!}
My routes.php(showing only relevant):
Route::post('/upload', 'ArtikalAdminController#upload');
Route::resource('admin_artikli', 'ArtikalAdminController');
My controller methods for store and upload:
public function upload(){
$input = Input::all();
$rules = array(
'file' => 'image|max:3000'
);
echo "eldaaaaaaaaaaaaaaaaaaaaaaaaar";
$validation = Validator::make($input, $rules);
if ($validation->fails())
{
return Response::make($validation->errors->first(), 400);
}
$file = Input::file('file');
$extension = File::extension($file['name']);
$directory = public_path().'uploads/'.sha1(time());
$filename = sha1(time().time()).".{$extension}";
$file->move($directory, $filename);
$upload_success = Input::file('file', $directory, $filename)->move($directory, $filename);;
echo $directory;
if( $upload_success ) {
return Response::json('success', 200);
} else {
return Response::json('error', 400);
}
}
public function store(Request $request)
{
$artikal = new Artikal;
$artikal->firma_id = Input::get('firma_id');
$artikal->naziv = Input::get('naziv');
$artikal->sifra = Input::get('sifra');
$artikal->opis = Input::get('opis');
$artikal->cijena = Input::get('cijena');
$artikal->kolicina = Input::get('kolicina');
$artikal->dostupnost = Input::get('dostupnost');
$artikal->aktivan = Input::get('aktivan');
$artikal->save();
Session::flash('flash_message', 'Uspješno unesen artikal!');
//return redirect()->back();
}
Finally, dropzone options I am currently using:
Dropzone.options.createArtikal = { // The camelized version of the ID of the form element
// The configuration we've talked about above
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 10,
maxFiles: 10,
// The setting up of the dropzone
init: function() {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
var element = document.getElementById('create_artikal_submit');
var form = document.getElementById('create_artikal');
element.addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function() {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function(files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
form.submit();
});
this.on("errormultiple", function(files, response) {
// Gets triggered when there was an error sending the files.
// Maybe show form again, and notify user of error
});
}
}
I know this is lacking many things, but I'm trying to go on step at a time and I'm stuck here. When I check the network tab of dev tools I see XHR requests are 200 OK, but yet I see no file.
You forgot to write 'files' => true in form, update form & try.
{!! Form::open(['route' => 'admin_artikli.store', 'class' => 'dropzone', 'id' => 'create_artikal', 'files'=>true, 'enctype' => 'multipart/form-data' ]) !!}
I am trying to make a loginbox with jquery using the laravel framework. I have rules in Laravel which i want it to follow. here the code for that:
$rules = array(
'username' => 'required|alphaNum|min:6|max:16',
'password' => 'required|alphaNum|min:6'
);
They work fine, and when you fail with your login the following code is run:
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('index')
->withErrors($validator)
->withInput(Input::except('password'));
The problem is that the log in-box pops up when called by pressing a button, which becomes a problem when I redirected to another page, because the error messages are written inside the log in box. This is good, however i cant get the log in box to pop up automatically once redirected, so you have to click the log in button again to see the error message and try again.
Here is the jQuery i use:
$(function(){
$('#loginform').submit(function(e){
return false;
});
$('#modaltrigger').leanModal({ top: 110, overlay: 0.45, closeButton: ".hidemodal" });
});
And here is the HTML log in form:
<div id="loginmodal" style="display:none;">
<h1>Logga in</h1>
{{ Form::open(array('url' => 'login')) }}
<p>
{{ $errors->first('username') }}
{{ $errors->first('password') }}
</p>
<div class="row">
<div class="col-md-12">
{{ Form::label('username', 'Username', array('class' => 'label')) }}
{{ Form::text('username', Input::old('username'), array('placeholder' => 'BTH Akronym',
'class' => 'textfield',
'id' => 'login-margin',
))
}}
</div>
<div class="col-md-12">
{{ Form::label('password', 'Password', array('class' => 'label')) }}
{{ Form::password('password', array('placeholder' => 'Lösenord',
'class' => 'textfield'
)) }}
</div>
</div>
<div class="center">
{{ Form::submit('Logga in', array('class' => 'login-knapp')) }}
</div>
{{ Form::close() }}
</div>
This is untested, but something like this should work for you...
PHP
if ($validator->fails()) {
if(Request::ajax()) {
return Response::json($validator->getMessages());
} else {
return Redirect::to('index')->withErrors($validator)->withInput(Input::except('password'));
}
}
The idea here is if the request is an ajax request, it will just return some json which we will be able to use on the success function of an ajax request on your template.
jQuery
$("#form").submit(function(e) {
$.ajax({
type: "POST",
url: "{{ route('ajax.form_submit') }}",
data: $("#form").serialize(), // serializes the form's elements.
success: function(data) {
if(data.length > 0) {
console.log(data); // Can set your messages on your modal.
e.preventDefault(); // Stop the form from submitting.
}
}
});
});
If there are any error messages, it will log them to the console and give you a good idea of what else needs to be done. If there are no error messages, it should just continue on with the form submission.
On $validator->fails(), I'd probably put an else on there for a success which would actually log the user in. This way because the function will run twice if it was a successful attempt (once by ajax, once by the form actually submitting), it wouldn't have to run the validator or check the database again (I'm assuming you already have a filter in place on these so it won't run if the user is logged in).