Keep modal open if any validation error exists laravel - ajax

I am trying to upload a csv and store the data accordingly in database. Form is in the modal. I want the modal to open if there exists any validation error message.
Here is the modal and ajax query:
$('#formSubmit').click(function(e) {
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('input[name="_token"]').val()
}
});
$.ajax({
url: "{{ url('/resellers') }}",
type: 'POST',
contentType: false,
processData: false,
data: {
csv_file: $('#csv_file').val(),
},
success: function(result) {
if (result.errors) {
$('.alert-danger').html('');
$.each(result.errors, function(key, value) {
$('.alert-danger').show();
$('.alert-danger').append('<li>' + value + '</li>');
});
} else {
$('.alert-danger').hide();
$('#reseller_modal').modal('hide');
}
}
});
});
<div class="col-sm-6">
<button type="button" id="csv-import" class="btn btn-secondary m-2 csv-import" data- toggle="modal" data-target="#reseller_modal">Import Csv</button>
</div>
<!-- Bootstrap modal -->
<div class="modal fade" id="reseller_modal" tabindex="-1" role="dialog" aria- labelledby="reseller_modal" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="demoModalLabel">CSV import</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="alert alert-danger" style="display:none"></div>
<div class="modal-body">
<div class="row">
<form class="form-horizontal" method="POST" action="{{ route('processImport') }}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<input id="csv_file" type="file" class="form-control" name="csv_file" required>
#if ($errors->has('csv_file'))
<span class="help-block">
<strong>{{ $errors->first('csv_file') }}</strong>
</span>
#endif
</div>
<div class="form-check">
</div>
<button type="submit" class="btn btn-primary" id="formSubmit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
And here is the controller:
public function processImport(Request $request)
{
$validator = Validator::make($request->all(), [
'csv_file' => 'required|file|mimes:csv,txt'
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()->all()]);
}
$rows = importCsv($request->file('csv_file'));
foreach ($rows as $data) {
$validator = Validator::make($data, [
'name' => ['required', 'string'],
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
]);
$status = User::where('email', '=', $data['email'])->exists();
if (!$validator->fails()) {
if (!$status) {
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password'])
]);
} else {
$user = User::where('email', '=', $data['email'])->first();
$user->update([
'password' => $data['password']
]);
}
} else {
Log::channel('import_fail')->info($data['email'] . ' Couldnot be stored . Has the validation message" : ' . $validator->errors()->first());
}
}
return redirect()->route('resellers')->with('success', 'Resellers imported successfully');
Even though I have csv_field in form, I get this error The csv_file field is required. It keeps the modal open.

I guess problem is here.
data: {
csv_file: $('#csv_file').val(),
},
You are sending text value i.e. name of file instead of actual file. and validating file.
Refer this to upload file using ajax. https://makitweb.com/how-to-upload-a-file-using-jquery-ajax-in-laravel-8/

Related

Laravel livewire google recaptcha validation problem

I have a livewire component where i am trying to implement google recaptcha using a package https://github.com/anhskohbo/no-captcha. but getting validation error even when i complete the captcha validation process.
Below is my code livewire blade code.
<div class="col-md-6">
<div wire:ignore>
{!! NoCaptcha::renderJs() !!}
{!! NoCaptcha::display() !!}
</div>
</div>
<div class="form-inline justify-content-center text-center">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1"><i class="far fa-envelope"></i></span>
</div>
<input type="email" class="form-control align-self-center" placeholder="Enter email" aria-label="newsletter_email" aria-describedby="basic-addon1" name="newsletter_email" wire:model.defer="newsletter_email">
</div>
<div class="form-group ml-3">
<button class="btn" style="background-color: #fff!important; color: #000!important;" wire:click.defer="newsletterEmail">SUBSCRIBE</button>
</div>
</div>
#error('recaptcha')
<div style="color: #fff">{{ $message }}</div>
#enderror
#error('newsletter_email')
<div style="color: #fff">{{ $message }}</div>
#enderror
#section('js')
<script type="text/javascript">
var onCallback = function () {
#this.set('recaptcha', grecaptcha.getResponse());
}
</script>
#endsection
and below is my validation code in livewire controller.
public $newsletter_email;
public $hascaptcha = 0;
public $captcha;
protected $rules = [
'newsletter_email' => 'required|email',
'recaptcha' => 'required|captcha',
];
protected $messages = [
'newsletter_email.required' => 'The Email Address cannot be empty.',
'newsletter_email.email' => 'The Email Address format is not valid.',
'recaptcha.required' => 'Please verify that you are not a robot.',
'recaptcha.captcha' => 'Captcha error! try again later or contact site admin.',
];
public function newsletterEmail()
{
$this->resetErrorBag();
$this->validate();
$current_date_time = Carbon::now()->toDateTimeString();
DB::table('news_letter')->insert([
'email' => $this->newsletter_email,
'created_at' => $current_date_time,
]);
$this->newsletter_email = "";
session()->flash('newsletter_message', 'Great!! You have subscribed for newsletter.');
}
No Package Needed...
Incase one needs Laravel Livewire - G Recaptcha V2,
In Your Component :-
<x-jet-form-section submit="submit(grecaptcha.getResponse(widgetId1))" method="POST">
<div class="col-span-6 sm:col-span-4"><div id="g-recaptcha"></div><x-jet-input-error for="g-recaptcha-response" class="mt-2" /></div>.
In Your Script :-
#section('scripts') <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer> </script> <script> var widgetId1; var onloadCallback = function() { widgetId1 = grecaptcha.render('g-recaptcha', { 'sitekey' : "{{ \Config::get('recaptcha.G_RECAPTCHA_SITE_KEY') }}", 'theme' : 'light' }); }; </script> #endsection
Your Component Class
public function submit($recaptcha)
Rest Of The Verification Code :-
`$url = 'https://www.google.com/recaptcha/api/siteverify';
$parameters = [
'secret' => \Config::get('recaptcha.G_RECAPTCHA_SITE_SECRET'),
'response' => $recaptcha
];
$qs = http_build_query($parameters);
$curl_request = "{$url}?{$qs}";
$curl = curl_init();
curl_setopt_array($curl, array(CURLOPT_URL => $curl_request, CURLOPT_RETURNTRANSFER => 1));
$response = curl_exec($curl);
$responseData = json_decode($response);
curl_close($curl);
if($responseData->success){ }else{ throw ValidationException::withMessages(['g-recaptcha-response' => 'ReCaptcha validation failed.']); }`

Ajax script to update record does not work, Laravel

I wrote a small script that updates the information on the page when editing. Everything basically works as it should, but I just can’t update the image. I don’t understand what the matter is. Without a script, with a page reload, everything works as it should.
Ajax script
<script type="text/javascript">
$("document").ready(function() {
$("#editPostButton{{$post->id}}").click(function() {
var formData = $("#EditPostForm{{$post->id}}").serialize();
$.ajax({
url: "{{route('editPost', ['id' => $user->id, 'postId' => $post->id])}}",
type: "POST",
data: formData,
success: function(data) {
$("#textpostdata{{$post->id}}").html($(data).find("#textpostdata{{$post->id}}").html());
$("#closeButton{{$post->id}}").click();
}
});
});
});
</script>
My Controller
public function editPost(Request $request, $id, $postId) {
$validator = $this->validate($request,[
'title' => 'max:100',
'message' => 'max:5000',
'img' => 'mimes:jpeg,png,gif,jpg|max:5000',
'videoPost' => 'max:100'
]);
if($validator) {
$user = User::find($id);
if(!$user && $user != Auth::user()->id) {
return abort(404);
}
$post = Profile::find($postId);
if(!$post) {
return abort(404);
}
$post->user_id = Auth::user()->id;
$post->title = $request->title;
$post->message = $request->message;
$post->videoPost = str_replace('watch?v=', 'embed/', $request->videoPost);
if($request->file('img')) {
$path = Storage::putFile('public/'.Auth::user()->id.'/post', $request->file('img'));
$url = Storage::url($path);
$post->img = $url;
}
$post->update();
return redirect()->back();
}
}
And update form
<form action="{{route('editPost', ['id' => $user->id, 'postId' => $post->id])}}" method="post" enctype="multipart/form-data" id="EditPostForm{{$post->id}}" name="postForm">
#csrf #method('PATCH')
<div class="form-group">
<textarea maxlength="100" name="title" class="form-control" rows="1">{{$post->title}}</textarea>
</div>
<div class="form-group">
<textarea id="message" maxlength="5000" name="message" class="form-control" rows="10">{{$post->message}}</textarea>
</div>
<div class="form-group">
<textarea maxlength="100" class="form-control mt-1" id="videoPost" name="videoPost" cols="100" rows="1">{{$post->videoPost}}</textarea>
</div>
<h6>Current image</h6>
<img src="{{$post->img}}" class="img-fluid mb-2" width="230">
<div class="form-group">
<input type="file" id="img" name="img" accept="image/*">
</div>
<button type="button" class="btn btn-sm btn-primary" id="editPostButton{{$post->id}}">Edit</button>
</form>

Ajax not displaying error message itself, box only

For some reason AJAX is not passing the error message. Whatever I try to submit in my form, I get red line (error message style) but without error message init, which makes hard for me to debug. Any ideas what is causing error message not to be displayed?
My AJAX function, pointing to store method in TicketCategory controller:
$(document).ready(function() {
$("#btn-add").click(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: '/ticket-category/store',
data: {
name: $("#frmAddTicketCategory input[name=name]").val(),
},
dataType: 'json',
$('#frmAddTicketCategory').trigger("reset");
$("#frmAddTicketCategory .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#add-ticket-category-errors').html('');
$.each(errors.messages, function(key, value) {
$('#add-ticket-category-errors').append('<li>' + value + '</li>');
});
$("#add-error-bag").show();
}
});
});
My view:
<div class="modal fade" id="addTicketCategoryModal">
<div class="modal-dialog">
<div class="modal-content">
<form id="frmAddTicketCategory">
<div class="modal-header">
<h4 class="modal-title">
Add New Task
</h4>
<button aria-hidden="true" class="close" data-dismiss="modal" type="button">
×
</button>
</div>
<div class="modal-body">
<div class="alert alert-danger" id="add-error-bag">
<ul id="add-ticket-category-errors">
</ul>
</div>
<div class="form-group">
<label>
Name
</label>
<input class="form-control" id="name" name="name" type="text">
</input>
</div>
</div>
<div class="modal-footer">
<input class="btn btn-default" data-dismiss="modal" type="button" value="Cancel">
<button class="btn btn-info" id="btn-add" type="button" value="add">
Add New Task
</button>
</input>
</div>
</form>
</div>
</div>
</div>
Controller:
public function create()
{
return view('ticket_category/ticket_cat',[
'tickets' => TicketCategory::all()
]);
}
public function store(Request $request)
{
$validator = Validator::make($request->input(), array(
'name' => 'required'
));
if ($validator->fails()) {
return response()->json([
'error' => true,
'messages' => $validator->errors(),
], 422);
}
$ticket_category = TicketCategory::create([$request->name]);
return response()->json([
'error' => false,
'ticket_category' => $ticket_category,
], 200);
}
see the error issue
I think value is an array of errors for a field that is why you are not able to display the errors. Try this
$('#add-ticket-category-errors').append('<li>' + value[0] + '</li>')

Ajax post request- Unresolvable dependency resolving and error 500

I'm trying to create a multi-step form using jQuery anad AJAX. But Im getting this error when "go to step 2" is clicked:
jquery.min.js:4 POST http://store.test/product/1/product-test/payment/storeUserInfo 500 (Internal Server Error)
Also when clicking in network tab and then click in "storeUserInfo" it appears:
exception
:
"Illuminate\Contracts\Container\BindingResolutionException"
file
:
"/Users/jakeB/projects/store/vendor/laravel/framework/src/Illuminate/Container/Container.php"
line
:
933
message
:
"Unresolvable dependency resolving [Parameter #1 [ <required> array $data ]] in class Illuminate\Validation\Validator"
Do you know where is the error?
In the 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:255|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->fails()) {
if($request->ajax())
{
return response('test');
}
$this->throwValidationException(
$request, $validator
);
}
}
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>
<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);
}
});
});
});
Use Validator facade class in your PaymentController
use Validator;
class PaymentController extends Controller
{
public function storeUserInfo(Request $request, $id, $slug = null){
$validator = Validator::make($request->all(),[
'buyer_name' => 'required|max:255|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->fails()) {
if($request->ajax())
{
return response('test');
}
$this->throwValidationException(
$request, $validator
);
}
}
}

Creating default object from empty value error on Laravel 5.2

I am building an application using Laravel 5.2. I'm trying to create an Edit modal using jquery. However I am getting a 500 internal server error, every time I try to update a record in the database. On further investigation using Firebug I get the error:
"Creating default object from empty value"...
These are the relevant code blocks.
Route.php - The edit route is what I'm trying to access from my modal
<?php
Route::group(['middleware' => ['web']], function () {
Route::get('/', function () {
return view('welcome');
})->name('home');
Route::post('/signup', [
'uses' => 'UserController#postSignup',
'as' => 'signup']);
Route::post('/signin', [
'uses' => 'UserController#postSignin',
'as' => 'signin']);
Route::get('/logout', [
'uses' => 'UserController#getLogout',
'as' => 'logout']);
Route::get('/dashboard', [
'uses' => 'PostController#getDashboard',
'as' => 'dashboard',
'middleware' => 'auth'
]);
Route::post('/createpost', [
'uses' => 'PostController#CreatePost',
'as' => 'createpost',
'middleware' => 'auth']);
Route::get('/delete-post/{post_id}', [
'uses' => 'PostController#getDeletePost',
'as' => 'post.delete',
'middleware' => 'auth']);
Route::post('/edit', [
'uses' => 'PostController#getEditPost',
'as' => 'edit'
]);
});
PostController.php
public function getEditPost(Request $request)
{
$this->validate($request, [
'body' => 'required'
]);
$post = Post::find($request['postid']);
$post->body = $request['body'];
$post->update();
return response()->json(['new_body' => $post->body], 200);
}
The Javascript file with the click event, app.js. I am printing a message to the console upon successful update of the database
var postId = 0;
$('.post').find('.interaction').find('.edit').on('click', function (event) {
event.preventDefault();
var postBody = event.target.parentNode.parentNode.childNodes[1].textContent;
postId = event.target.parentNode.dataset['postid'];
$('#post-body').val(postBody);
$('#edit-modal').modal();
});
$('#modal-save').on('click', function () {
$.ajax({
method: 'POST',
url: url,
data: {body: $('#post-body').val(), postId: postId, _token: token}
}).done(function (msg) {
console.log(JSON.stringify(msg));
});
});
This is my view page
dashboard.blade.php
#extends('layouts.master')
#section('content')
#include('includes.message-block')
<section class="row new-post">
<div class="col-md-6 col-md-offset-3">
<header><h3>What do you have to say?</h3></header>
<form action="{{ route('createpost') }}" method="post">
<div class="form-group">
<textarea class="form-control" name="body" id="new-post" rows="5" placeholder="Your Post"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Post</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
</div>
</section>
<section class="row posts">
<div class="col-md-6 col-md-offset-3">
<header><h3>What other people say...</h3></header>
#foreach($posts as $post)
<article class="post" data-postid="{{ $post->id }}">
<p>{{ $post->body }}</p>
<div class="info">
Posted by {{ $post->user->first_name }} on {{ $post->created_at }}
</div>
<div class="interaction">
Like |
Dislike
#if(Auth::user() == $post->user)
|
Edit |
Delete
#endif
</div>
</article>
#endforeach
</div>
</section>
<div class="modal fade" tabindex="-1" role="dialog" id="edit-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Edit Post</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="post-body">Edit the Post</label>
<textarea class="form-control" name="post-body" id="post-body" rows="5"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="modal-save">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
var token = '{{ Session::token() }}';
var url = '{{ route('edit') }}';
</script>
#endsection
Please can anyone help me to see what I'm missing here? Thanks
It looks like you get null on $post = Post::find($request['postid']);.
Do some checks before trying to update the model.
You can use ::findOrFail() or check if !is_null($post).
Also you should use $request->input('postid').

Resources