This is the view :
{{ Form::open([
'url' => '/contacts/create',
'files' => true
])}}
<div class="row">
<div class="collapse" id="collapseExample">
<div class="col-md-9">
{{ Form::label('group', 'group name')}}
{{ Form::text('group', null, [
'placeholder' => 'Enter group name here',
'class' => 'form-control'
])}}
</div>
<div class="col-md-3">
<button id="add-new-btn" class="btn btn-success"><i class="pe-7s-add-user"></i> Add</button>
</div>
</div>
</div>
{{ Form::close() }}
in my that view i have this script
$("#add-new-btn").click(function(e) {
e.preventDefault();
e.stopImmediatePropagation();
var newGroup = $('#group');
$.ajax({
url: "/groups/autocomplete",
method: "post",
data: {
name: $("#group").val(),
_token: $("input[name=_token]").val()
},
success: function(response) {
console.log(response);
},
error: function(xhr) {
var errors = xhr.responseJSON;
var error = errors.name[0];
if(error) {
newGroup.addClass('has-error');
var inputGroup = newGroup.closest('.col-md-9');
inputGroup.next('text-danger').remove();
inputGroup
.find('input')
.after('<p class="text-danger">' + error + '</p>');
}
}
});
});
and in store method of GroupsController i have a simple Validator that may returns these 2 values:
1.The name field is required
2.The name has already been taken
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|unique:groups'
]);
}
Now the problem is this :
Every time i try to submit the form, the browser returns this error "errors.name is undefined" in console.
where is the problem?
i had a mistake for accessing property of object, jsonData.errors
var data = xhr.responseText;
var jsonData = JSON.parse(data);
var msg = jsonData.errors.name[0];
console.log(msg);
or
var jsonData = xhr.responseJSON;
var msg = jsonData.errors.name[0];
console.log(msg);
Related
In his life, he only encountered an ajax 2 times and here again our paths intertwined with him and he gave me 422 errors. I googled and realized that 422 error is a validation error, but in what specific place the error, I just can not understand.
This is my script
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$( "#form" ).submit(function( e ) {
e.preventDefault();
var message = $('#message').val();
var img = $('#img').val();
var user_id = $('#user_id').val();
$.ajax({
type: "POST",
url: "{{route('profile.store', ['id' => Auth::user()->id])}}",
data: {message:message, img:img, user_id:user_id},
success: function (data) {
$("#textpost").html($(data).find("#textpost").html());
},
});
});
</script>
And my method
public function store(Request $request) {
$validator = $this->validate($request,[
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
if($validator ) {
$post = new Profile();
$post->message = $request->message;
$post->user_id = Auth::user()->id;
if($request->file('img')) {
$path = Storage::putFile('public', $request->file('img'));
$url = Storage::url($path);
$post->img = $url;
}
$post->save();
}
return redirect()->back();
}
And my form
<div class="card-header">
<div class="input-group">
<form action="{{route('profile.store', ['id' => Auth::user()->id])}}" method="post" enctype="multipart/form-data" id="form">
#csrf
<textarea class="form-control" id="message" name="message" cols="100" rows="4" placeholder="О чем думаешь?"></textarea>
<input type="file" id="img" name="img" value="Прикрепить изображение" class="mt-2">
<div class="text-right">
{{-- <input type="submit" id="btn" value="Отправить" class="btn btn-outline-dark btn-sm mt-4">--}}
<button type="submit" id="btn" class="btn btn-outline-dark btn-sm mt-4">Отправить</button>
</div>
</form>
</div>
</div>
$validator = $this->validate($request,[
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
This portion of your code throws a validation errors exception which returns 422.
If you wish to handle validation on your own, try this logic instead:
$validator = validator($request->all(), [
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
if($validator->fails()) {
// return as appropriate
return response()->son($validatior->errors(), 422);
}
// rest of your code
There is a problem with your Ajax call, because you are uploading text and file at the same time you can pass it through FormData. You were also missing
contentType: false,
processData: false,
Here is the updated ajax call:
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$( "#form" ).submit(function( e ) {
e.preventDefault();
var formData = new FormData(this); //set formData to selected instance
var message = $('#message').val();
var img = $('#img').val();
var user_id = $('#user_id').val();
$.ajax({
type: "POST",
url: "{{route('profile.store', ['id' => Auth::user()->id])}}",
data: formData, //pass to our Ajax data to send
success: function (data) {
$("#textpost").html($(data).find("#textpost").html());
},
contentType: false,
processData: false,
});
});
</script>
Setting processData makes it so your FormData is not converted to a string. Setting contentType to false is used for forms that pass files, when false, no header will be added to the request, which is exactly what we want when submitting multipart/form-data.
I'm trying to create a multi-step form using jQuery anad AJAX and I want to valdiate each step with an ajax post request.But Im getting this error when "go to step 2" is clicked and there are validation errors:
jquery.min.js:4
POST http://store.test/product/1/product-test/payment/storeUserInfo
422 (Unprocessable Entity)
But what I have to have when there is a validation error is show in the div "#response" the validation errors. Do you know why this is not working?
Relevant code for the question:
I have a PaymentController there is the storeUserInfo() Method that is the method for the step 1:
public function storeUserInfo(Request $request, $id, $slug = null, Validator $validator){
$validator = Validator::make($request->all(),[
'buyer_name' => 'required|max:1|string',
'buyer_surname' => 'required|max:255|string',
'buyer_email' => 'required|max:255|string',
'name_invoice' => 'required|max:255|string',
'country_invoice' => 'required|max:255|string',
]);
if($validator->passes())
{
return response()->json([
'success' => true,
'message' => 'success'
], 200);
}
$errors = $validator->errors();
$errors = json_decode($errors);
return response()->json([
'success' => false,
'message' => $errors
], 422);
}
Route:
Route::post('/product/{id}/{slug?}/payment/storeUserInfo', [
'uses' => 'PaymentController#storeUserInfo',
'as' =>'products.storeUserInfo'
]);
// step 1 and step 2 html
<div class="tab-pane fade show active clearfix" id="step1" role="tabpanel" aria-labelledby="home-tab">
<h6>User Info</h6>
<div id="response"></div> <!-- div to show errors -->
<form method="post" id="step1form" action="">
{{csrf_field()}}
<div class="form-group font-size-sm">
<label for="name" class="text-gray">Name</label>
<input name="name" type="text" required class="form-control" value="{{ (\Auth::check()) ? Auth::user()->name : old('name')}}">
</div>
<!-- other form fields -->
<input type="submit" id="goToStep2" href="#step2"
class="btn btn-primary btn float-right next-step" value="Go to step 2"/>
</form>
</div>
<div class="tab-pane fade clearfix tabs hide" id="step2" role="tabpanel" aria-labelledby="profile-tab">
<form method="post">
<h6>Payment method</h6>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="radio" name="paymentmethod1" value="option1" checked>
<label class="form-check-label d-flex align-items-center" for="exampleRadios1">
<span class="mr-auto">payment method 1</span>
</label>
</div>
<br>
<div class="form-check">
<input class="form-check-input" type="radio" name="credit_card" value="option1">
<label class="form-check-label d-flex align-items-center" for="exampleRadios1">
<span class="mr-auto">Stripe</span>
</label>
</div>
</div>
<div class="text-right">
<button type="button" href="#step3" data-toggle="tab" role="tab"
class="btn btn-outline-primary prev-step">
Go back to step 2
</button>
<button type="button" data-nexttab="#step3" href="#step3"
class="btn btn-primary btn ml-2 next-step">
Go to step 3
</button>
</div>
</form>
</div>
// ajax in payment.blade.php
$('#goToStep2').on('click', function (event) {
event.preventDefault();
var custom_form = $("#" + page_form_id);
$.ajax({
method: "POST",
url: '{{ route('products.storeUserInfo',compact('id','slug') ) }}',
data: custom_form.serialize(),
datatype: 'json',
success: function (data, textStatus, jqXHR) {
setTimeout(function () {
}, 3000);
},
error: function (data) {
console.log(data);
var errors = data.responseJSON;
var errorsHtml = '';
$.each(errors['errors'], function (index, value) {
errorsHtml += '<ul class="list-group"><li class="list-group-item alert alert-danger">' + value + '</li></ul>';
});
$('#response').show().html(errorsHtml);
}
});
});
});
// ajax in payment.blade.php
$('#goToStep2').on('click', function (event) {
event.preventDefault();
var custom_form = $("#" + page_form_id);
$.ajax({
method: "POST",
url: '{{ route('products.storeUserInfo',compact('id','slug') ) }}',
data: custom_form.serialize(),
datatype: 'json',
success: function (data, textStatus, jqXHR) {
setTimeout(function () {
}, 3000);
},
error: function (data) {
console.log(data);
var errors = data.responseJSON;
var errorsHtml = '';
$.each(errors['errors'], function (index, value) {
errorsHtml += '<ul class="list-group"><li class="list-group-item alert alert-danger">' + value + '</li></ul>';
});
$('#response').show().html(errorsHtml);
}
});
});
});
I'm not sure but I think you have to add value[0] to your errors instead of value. try this out maybe it can help:
error: function (data) {
var json = data.responseJSON;
if (json) {
var errors = json.errors;
var errorsHtml = '<ul class="list-group">';
$.each(errors, function (index, value) {
errorsHtml += '<li class="list-group-item
alert alert-danger">' + value[0] + '</li>';
});
errorHtml+='</ul>';
$('#response').show().html(errorsHtml);
}
}
Change your controller function to this:
public function storeUserInfo(Request $request, $id, $slug = null){
$this->validate($request,[
'buyer_name' => 'required|max:1|string',
'buyer_surname' => 'required|max:255|string',
'buyer_email' => 'required|max:255|string',
'name_invoice' => 'required|max:255|string',
'country_invoice' => 'required|max:255|string',
]);
return response()->json([
'success' => true,
'message' => 'success'
], 200);
}
I have this form in a page:
<div class="card-block">
{!! Form::open(array( 'autocomplete' => 'off', 'id' => 'AddModel', 'url' => 'model/useradd', 'files' => true)) !!}
<div class="form-group">
<label for="picture">Picture</label>
#if( (new Jenssegers\Agent\Agent)->isMobile() )
{!! Form::file('image', ['id' => 'modelpic', 'accept' => 'image/*', 'capture' => 'camera']) !!}
#else
{!! Form::file('image', ['id' => 'modelpic']) !!}
#endif
<br/>
</div>
<div id="imagePreview" style="display: none;"></div> /** here I show preview of the image through JS */
<div class="form-group">
{!! Form::submit('Submit', array('id' => 'AddBtn', 'class' => 'btn btn-default' )) !!}
{!! Form::close() !!}
</div>
in my controller:
public function preview(Request $request)
{
dd($request->file('image'));
}
result of dumping = NULL
I don't understand what's the catch here. I have an identical form in another page that is working normally.
by validating request I get the error "image is required"
$this->validate($request, [
'image' => 'required|mimes:jpeg,jpg,png,gif|image|image_size:>=640'
]);
new info:
There must be a problem with the javascript because removing it the controller works normally:
this is the JS
jQuery(function ($) {
$(document).ready(function () {
$("body").on("submit", "#AddModel", function (e) {
var form = $(this);
$.ajax({
url: form.prop('action'),
type: 'post',
dataType: 'json',
data: $(this).serialize(),
success: function (data) {
console.log(data);
},
error: function (textStatus) {
{
var json = JSON.parse(textStatus.responseText);
console.log (json);
}
}
});
e.preventDefault();
});
});
});
solved, thanks #sagar
jQuery(function ($) {
$(document).ready(function () {
$("body").on("submit", "#AddModel", function (e) {
var form = $(this);
var postData = new FormData($("#AddModel")[0]);
$.ajax({
type:'POST',
url:form.prop('action'),
processData: false,
contentType: false,
data : postData,
success:function(data){
console.log(data);
},
error: function (textStatus) {
{
var json = JSON.parse(textStatus.responseText);
console.log (json);
}
}
});
e.preventDefault();
});
});
});
To upload image using ajax:
Do it like:
You can upload the file using ajax like this.
In your form tag use attribute enctype and form html will be like below:
<form enctype="multipart/form-data" id="modal_form_id" method="POST" >
<input type="file" name="documents">
</form>
Js code:
var postData = new FormData($("#modal_form_id")[0]);
$.ajax({
type:'POST',
url:'your-post-url',
processData: false,
contentType: false,
data : postData,
success:function(data){
console.log("File Uploaded");
}
});
On your controller side you can do in the function like below to upload image.
if(Input::hasFile('documents')) {
$path = "directory where you wish to upload file";
$file_name= Input::file('documents');
$original_file_name = $file_name->getClientOriginalName();
$extension = $file_name->getClientOriginalExtension();
$fileWithoutExt = str_replace(".","",basename($original_file_name, $extension));
$updated_fileName = $fileWithoutExt."_".rand(0,99).".".$extension;
$uploaded = $file_name->move($path, $updated_fileName);
echo $updated_fileName;
}
More details :
File upload through a modal using Ajax
This code checks if request has a file if yes then names it and then moves the files to a folder in public dir.
if($request->hasFile('modelpic')) {
$file = Input::file('modelpic');
//get file extension
$name = 'image'.$file->getClientOriginalExtension();
//move file to public/images dir
$file->move(public_path().'/images/', $name);
}
Images are submitted with multiple part request due to size use (Multipart-form-data) in form tag.
Like this,
<div class="card-block">
{!! Form::open(array( 'autocomplete' => 'off', 'id' => 'AddModel', 'url' => 'model/useradd', 'files' => true,'enctype' => 'multipart/form-data')) !!}
<div class="form-group">
<label for="picture">Picture</label>
#if( (new Jenssegers\Agent\Agent)->isMobile() )
{!! Form::file('image', ['id' => 'modelpic', 'accept' => 'image/*', 'capture' => 'camera']) !!}
#else
{!! Form::file('image', ['id' => 'modelpic']) !!}
#endif
<br/>
</div>
<div id="imagePreview" style="display: none;"></div> /** here I show preview of the image through JS */
<div class="form-group">
{!! Form::submit('Submit', array('id' => 'AddBtn', 'class' => 'btn btn-default' )) !!}
{!! Form::close() !!}
</div>
I'm using resource controller , when i submit form through ajax , it is showing method not allowed exception.
View
{!! Form::open(array('route' => 'product.store','class' => 'form-horizontal','id' => 'productform','name' => 'productform','files' => true)) !!}
{!! csrf_field() !!}
<div class="form-group" style="padding-top: 20px">
<label for="productName" class="col-sm-3 control-label">Product name</label>
<div class="col-sm-9">
{!! Form::text('productName',null, array('id'=> 'productName','class'=>'form-control','placeholder'=>'Product name'))!!}
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
{!! Form::submit('Save', array('class' => 'btn btn-primary btn-block')) !!}
</div>
</div>
{!! Form::close() !!}
AJAX
$("#productform").submit(function () {
var token = $('[name=_token]').val();
$.ajax({
type: 'POST',
url: 'product/store',
data: {
id: '4',
_token: token,
},
success: function (data) {
alert('success');
return false;
}
})
return false;
});
routes.php
Route::resource('product', 'ProductController');
What is the problem here...Any help is much appreciated.
in jquery
var BASEURL = $("#baseURL").val()
in html
<input type="hidden" id="baseURL" value="{{ url('') }}" >
when you try to store data in laravel your URL must be.
url: 'product',
try to go on your CMD and type:
php artisan route:list
and check the URI of product.store Name then that will be you url in your AJAX.
in AJAX
try to set url in AJAX to be route
$("#productform").submit(function () {
var token = $('[name=_token]').val();
$.ajax({
type: 'POST',
url: '{{ route("product.store") }}',
data: {
id: '4',
_token: token,
},
success: function (data) {
alert('success');
return false;
}
});
return false;
});
when i try to upload my file with ajax, the $file is empty.
I tried with:
$file = Input::file('image');
$file= $request->file('image');
jQuery:
$(document).on('submit', '#update_form', function(e){
e.preventDefault(e);
$.ajax({
type: "POST",
url: '{{route('admin/users/update')}}',
data: $(this).serialize(),
dataType: 'json',
success: function (data) {
$('.error').fadeOut();
success(data);
load_data('{{route('admin/users/edit')}}', '{{ $user->id }}', '{{ $user->part }}');
},
error: function (data) {
$('.success').fadeOut();
errors(data);
}
})
});
Controller:
public function updateUser(Request $request){
//$file = Input::file('image');
$file= $request->file('image');
return \Response::json( $file );
}
Route:
Route::post('admin/users/update', ['as' => 'admin/users/update', 'uses' => 'admin\UserController#updateUser']);
Form:
{!! Form::model($user, ['id' => 'update_form', 'files' => true]) !!}
<div class="col-md-12">
<div class="form-group">
{{ Form::label(trans('User image')) }}
{!! Form::file('image', null,['class' => 'form-control', 'placeholder' => trans('Image')]) !!}
</div>
{{ Form::hidden('id') }}
{{ Form::hidden('part', app('request')->input('part')) }}
{!! Form::submit(trans('Save changes'), ['class' => 'pull-right btn btn-success submit', 'id' => 'submit' ]) !!}
</div>
{!! Form::close() !!}
Repsonse is empty or: {}
response image:
https://gyazo.com/04e431f16237dfada40c864df96ad412
Thank you!
param is your server method parameters
FormData fd =new FormData();
fd.append('param',$('input[type=file]').files[0]);
Laravel 6.x Ah finally nailed it down, for me the way its worked is first i have get the form by it's form id using jQuery then create a new FormData instance passing form through the constructor then if you need anything pass to server side as key value pair use append function.
<form id="form_id" enctype="multipart/form-data">
<div class="from-group">
<label for="title">App name:</label>
<input type="text" name="title" id ="title_id" class="form-control" placeholder="App name"><br>
</div>
<br>
<div class="form-group">
<input type="file" id="image" name="cover_image" autocomplete="off" class="form-control" />
</div>
<button type="button" onclick="WebApp.CategoryController.onClickAppSubmitButton()" class="btn btn-primary">Submit </button>
</form>
var form = $("#form_id")[0];
var formData = new FormData(form);
formData.append('parent_id','0');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: url_app_post,
method: "POST",
contentType: false,
processData: false,
data: formData,
success: function (result) {
var data_array = $.parseJSON(result);
if (data_array.status == "200") {
messageHtml += WebApp.CategoryController.getAlertMessage("alert-success", data_array.message);
} else {
messageHtml += WebApp.CategoryController.getAlertMessage("alert-danger", data_array.message);
}
$(messageView).html(messageHtml);
},
error: function (jqXHR, exception) {
messageHtml += WebApp.CategoryController.getAlertMessage("alert-danger",
WebApp.CategoryController.getjqXHRmessage(jqXHR, exception));
$(messageView).html(messageHtml);
}
})
function storeCategory(Request $request, $type){
try{
$fileNameToStore='no_image.jpg';
if($request->hasFile('cover_image')){
$fileNameWithExt = $request->file('cover_image')->getClientOriginalName();
$fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
$extension = $request->file('cover_image')->getClientOriginalExtension();
$fileNameToStore=$fileName.'_'.time().'.'.$extension;
$path = $request->file('cover_image')->storeAs('public/cover_images', $fileNameToStore);
}
$cat = new Category();
$cat->title = $request->title;
$cat->parent_id = $request->parent_id;
$cat->cover_image=$fileNameToStore;
$cat->user_id=auth()->user()->id;
$cat->save();
return json_encode(array("message"=>"This ".$type." successfully added", "status" => "200"));
}catch(Exception $e){
return json_encode(array("message"=>$type." failed to insert: ".$e->getMessage(), "status" => "403"));
}
}