Now that I got my Ajax call to post the email, I'm still struggling trying to retrieve it, validate it, and insert it to my database.
Here is what I've got :
Controller
public function postSubscribe() {
if(Request::ajax()) {
$data = Input::all();
}
dd(json_decode($data));
// Validation
$validator = Validator::make( Input::only('subscribe_email'),
array(
'subscribe_email' => 'email|unique:subscribes,email',
)
);
if ($validator->fails()) {
return Redirect::to('/#footer')
->with('subscribe_error','This email is already subscribed to us.')
->withErrors($validator)->withInput();
}else{
$subscribe = new Subscribe;
$subscribe->email = Input::get('subscribe_email');
$subscribe->save();
return Redirect::to('/thank-you');
}
}
Route
Route::post('/subscribe','SubscribeController#postSubscribe');
Since that a post request, I don't where can I see my dd(json_decode($data)); ? Am I doing it right ? Please correct me.
Form
{!! Form::open(array('url' => '/subscribe', 'class' => 'subscribe-form', 'role' =>'form')) !!}
<div class="form-group col-lg-7 col-md-8 col-sm-8 col-lg-offset-1">
<label class="sr-only" for="mce-EMAIL">Email address</label>
<input type="email" name="subscribe_email" class="form-control" id="mce-EMAIL" placeholder="Enter email" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input type="text" name="b_168a366a98d3248fbc35c0b67_73d49e0d23" value=""></div>
</div>
<div class="form-group col-lg-3 col-md-4 col-sm-4">
<button type="button" name="subscribe" class="btn btn-primary btn-block" id="subscribe">Subscribe</button>
</div>
{!! Form::close() !!}
Ajax
<script type="text/javascript">
$(document).ready(function(){
$('#subscribe').click(function(e){
e.preventDefault();
$.ajax({
url: '/subscribe',
type: "post",
data: {'subscribe_email':$('input[name=subscribe_email]').val(), '_token': $('input[name=_token]').val()},
dataType: 'JSON',
success: function (data) {
console.log(data);
} // this is good
});
});
});
</script>
Posting data successfully
Questions
How do I debug something like that on my own in the future ?
What is the most practical way to retrieve data from Ajax call in PHP Laravel ?
thanks to #Pawel Bieszczad
change : dd(json_decode($data));
to : dd(json_encode($data));
and open up console > Network Tab > Response
Now I see my response as expected.
"{"subscribe_email":"bheng#outlook.com","_token":"S3lWmNn6gkkHrYY6nPmupCtrlRqWF6au7b0Mywy7"}"
Related
I use ajax to submit a form without having to reload the page after, but I really don't know how to get the forms errors, especially for the required fields.
Here is my form, it's a simple form with two datepicker:
<form>
<div class="form-group row">
<label for="date_debut" class="col-md-4 col-form-label text-md-right">Date de début</label>
<div class="col-md-6">
<input type="text" id="date_debut" name="date_debut" class="datepicker-here form-control" data-timepicker="true" data-language='fr' placeholder="Choisir une date" />
</div>
</div>
<div class="form-group row">
<label for="date_fin" class="col-md-4 col-form-label text-md-right">Date de fin</label>
<div class="col-md-6">
<input type="text" id="date_fin" name="date_fin" class="datepicker-here form-control" data-timepicker="true" data-language='fr' placeholder="Choisir une date" />
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button id="ajoutDispoButton" onclick="myfunction()" type="button" class="btn btn-primary">
Ajouter
</button>
</div>
</div>
<input type="hidden" id="user_id" name="user_id" class="form-control" value="{{$user->id}}" required>
</form>
And here is my Ajax call :
function myfunction(param){
var date_debut = $('#date_debut').val();
console.log(date_debut);
var date_fin = $('#date_fin').val();
var user_id = $('#user_id').val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{ route('createDispo') }}',
type: 'POST',
dataType: "json",
data: {
user_id: user_id,
date_debut: date_debut,
date_fin: date_fin,
},
success: function (data) {
$("#centralModalSuccess").modal();
$("#date_fin").val("");
$("#date_debut").val("");
},
error: function (data) {
var errors = data.responseJSON;
console.log(errors);
}
});
}
And here my controller :
public function createDispo(Request $request){
$user = User::find($request->user_id);
$disponibilite = new Disponibilite();
$disponibilite->date_debut = Carbon::createFromFormat('d/m/Y H:i',$request->date_debut);
$disponibilite->date_fin = Carbon::createFromFormat('d/m/Y H:i',$request->date_fin);
$user->disponibilites()->save($disponibilite);
return response()->json(['ok' => 'ok']); // Return OK to user's browser
}
I think this is not the right way to proceed, but this work. The problem is that I want to handle the validations errors, my fields are required but I can send the ajax call even if they are empty.
Anyone know how to do that?
you can make form validation with jquery instead of laravel validation
Look at this question : A simple jQuery form validation script
Add validation in controller function
public function createDispo(Request $request){
$request->validate([
'date_debut' => 'required',
'date_fin' => 'required',
]);
// your code
}
and display the errors in html.
I downloaded a web application and i found out that it is created using Smarty Template Engine. I want to add an avatar field when creating new company so i added enctype="multipart/form-data" and <input type="file" name="avatar"> to the existing <form> and i also added avatar to my companies table in my database. Here is the HTML code:
<form class="form-horizontal" id="ib_modal_form" enctype="multipart/form-data">
<div class="form-group"><label class="col-lg-4 control-label" for="company_name">{$_L['Company Name']}<small class="red">*</small></label>
<div class="col-lg-8"><input type="text" id="company_name" name="company_name" class="form-control" value="{$val['company_name']}"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="avatar">{$_L['Avatar']}</label>
<div class="col-lg-8"><input type="file" name="avatar"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="email">{$_L['Email']}</label>
<div class="col-lg-8"><input type="text" id="email" name="email" class="form-control" value="{$val['email']}"> </div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-danger">{$_L['Cancel']}</button>
<button class="btn btn-primary modal_submit" type="submit" id="modal_submit"><i class="fa fa-check"></i> {$_L['Save']}</button>
</div>
I found out that the form goes to this javascript code when clicking the Save Button:
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
$.post( _url + "contacts/add_company_post/", $("#ib_modal_form").serialize())
.done(function( data ) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
});
});
Here is the code in the Controller:
case 'add_company_post':
$data = ib_posted_data();
$company = Model::factory('Models_Company')->create();
$company->company_name = $data['company_name'];
$company->url = $data['url'];
$company->email = $data['email'];
$company->phone = $data['phone'];
$company->logo_url = $data['logo_url'];
$company->avatar = $_FILES['avatar']['name'];
$company->save();
break;
The problem is that it does not recognize $_FILES['avatar']['name']; in the Controller Whenever i add a new company, i get a NULL value in my database. I cant seem to solve this problem. Any help would be appreciated. Thanks.
Change
From
$("#ib_modal_form").serialize()
To
new FormData($("#ib_modal_form")[0])
You should use FormData for uploading files using ajax. $(form).serialize() will give you just key and value.
Can you change your ajax call below way
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
var formData = new FormData($("#ib_modal_form")[0]);
$.ajax({
url: _url + "contacts/add_company_post/",
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (data) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
},
});
});
Register form:
{!! Form::open(['route' => 'api.register', 'method' => 'post', 'id' => 'register_form']) !!}
<div class="form-group">
<div class="inputer">
<div class="input-wrapper">
<input id="register_name" type="text" class="form-control" placeholder="Enter your full name">
</div>
</div>
</div>
<!--.form-group-->
<div class="form-group">
<div class="inputer">
<div class="input-wrapper">
<input id="register_email" type="email" class="form-control" placeholder="Enter your email address">
</div>
</div>
</div>
<!--.form-group-->
<div class="form-group">
<div class="inputer">
<div class="input-wrapper">
<input id="register_pass" type="password" class="form-control" placeholder="Enter your password">
</div>
</div>
</div>
<!--.form-group-->
<div class="form-group">
<div class="inputer">
<div class="input-wrapper">
<input id="register_confirm" type="password" class="form-control" placeholder="Enter your password again">
</div>
</div>
</div>
<!--.form-group-->
<div class="form-group">
<label>
<input type="checkbox" name="remember" value="1"> I have read and agree to the term of use.
</label>
</div>
<div class="form-buttons clearfix">
<button class="btn btn-white pull-left show-pane-login">Cancel</button>
<button id="register_submit" class="btn btn-success pull-right">Sign Up</button>
</div>
<!--.form-buttons-->
{!! Form::close() !!}
JS:
$("#register_form").submit(function(e) {
e.preventDefault();
});
$('#register_submit').click(function()
{
var address = $('#register_form').attr('action');
var method = $('#register_form').attr('method');
var user_name = $('#register_name').val();
var mail = $('#register_email').val();
var pass = $('#register_pass').val();
var pass_confirm = $('#register_confirm').val();
var name = $("input[name=_token]").val();
$.ajax({
url: address,
type: method,
data:
{
name: user_name,
email: mail,
password: pass,
password_confirm : pass_confirm,
_token: name
},
success:function(response) {
alert(response);
},
error:function(response) {
alert(response);
},
});
});
Route:
Route::post('/processregister', ['as' => 'api.register', 'uses' => 'AuthController#register']);
Register function:
public function register(Request $request)
{
return $request->name;
}
At webportal.dev/processregister it gives blank page. It means request parameters sends remains null. Where I am going wrong?
(Maybe conflicts? There is also a login form on same page but it is submitted by seperate function and that login form works correctly.)
It's due to a very common mistake in Submit button.
A button <button> with type=submit will submit the form by default, unless you stop the default behavior via event.preventDefault() in your $('#register_submit').click() function. The default behavior runs before your AJAX call is responded and forwarded to the URL in action attribute specified in <form> tag (i.e. http://webportal.dev/processregister)
In your case, you can also change the type of the button to button to avoid this form submission behavior.
Remove type="submit" in this line:
<button id="register_submit" type="submit" class="btn btn-success pull-right">Sign Up</button>
Also be sure that your ajax code is really called.
Based on the comments the issue was due to your view being cached. Since i was able to run the exact same code to generate the result intended. Next time try to run php artisan view:clear to clear the cached views as the first step in debugging view errors. Also always post the code used when seeking help and not the code being generated.
Another tip is to assign names instead of id to the form inputs and then serialize the form data in the ajax request. You save all the work of fetching the value of each input by it's id and then using it.
Why not moving all your code inside your .submit function, and just add return false; at the end?
$("#register_form").submit(function(e) {
var address = $('#register_form').attr('action');
var method = $('#register_form').attr('method');
var user_name = $('#register_name').val();
var mail = $('#register_email').val();
var pass = $('#register_pass').val();
var pass_confirm = $('#register_confirm').val();
var name = $("input[name=_token]").val();
$.ajax({
url: address,
type: method,
data:
{
name: user_name,
email: mail,
password: pass,
password_confirm : pass_confirm,
_token: name
},
success:function(response) {
alert(response);
},
error:function(response) {
alert(response);
},
});
return false;
});
Please then watch what happens with your ajax request in the Developer Tools (F12) > Network tab. Perhaps there is an error on the server side.
this is my registration form..
<?php echo form_open('reg_ctrl/send_validation_email', array('class' => 'form-horizontal','role' => 'form'));?>
<div class="form-group has-feedback">
<label for="inputUserName" class="col-sm-4 control-label">User Name <span class="text-danger small">*</span></label>
<div class="col-sm-8">
<?php echo form_input(array('class'=>'form-control','type'=>'text','required'=>'email', 'id' => 'user_name', 'name' => 'user_name', 'placeholder' => 'User Name')); ?><i class="fa fa-user form-control-feedback"></i>
</div>
</div>
<div class="form-group has-feedback">
<label for="inputEmail" class="col-sm-4 control-label">Email <span class="text-danger small">*</span></label>
<div class="col-sm-8">
<?php echo form_input(array('class'=>'form-control','type'=>'email','required'=>'email', 'id' => 'email', 'name' => 'email', 'placeholder' => 'Email')); ?><i class="fa fa-envelope form-control-feedback"></i>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-group btn-default btn-animated">Sign Up <i class="fa fa-check"></i></button>
</div>
</div>
<?php echo form_close(); ?>
which accept username and email and in my case both unique so i want to display an existence that username and email in available or not before press the submit button like gmail registration.
I think i should have to integrate ajax in this and i am new to ajax please help me..
1) tablename:- registration 2) column name:- user_name and email
Thank You
Try something like this.
This should call a script to your server, which could create a response after checking the database.
$("#user_name").change(function(event){
$.ajax({
type: "POST",
url: "CheckUsername.php",
data: { 'username': $("#user_name").val() },
success: function(data){
if(data == "available") //this you would be your response
//do something
},
error: function (httpRequest, status, error) {
return false;
}
});
});
The php file would just contain something like this
<?php
//the username you send with
$username = $_POST['username'];
//check username in database.
//When you are done, you echo the result out.
echo $result;
?>
i hope this gives some clarity, otherwise you are welcome to ask for clarification.
EDIT: I just realised that you were talking about the event firing every time the user presses a button, in which case, this should work, although i haven't had the chance to test it.
Although this may not be good for low bandwidth users/servers as it calls the server every time you make a change.
$(document).ready(function() {
$("#user_name").on('keyup change', function() {
$.ajax({
type: "POST",
url: "CheckUsername.php",
data: { 'username': $("#user_name").val() },
success: function(data){
if(data == "available") //this you would be your response
//do something
},
error: function (httpRequest, status, error) {
return false;
}
});
});
})
I'm trying to submit data to the database via ajax. The submit article page works fine without ajax. I've added console.log() just to see if anything is going through, but instead I'm getting this error:
POST http://localhost/laravel-5/public/articles/create 500 (Internal Server Error)
What's wrong with my code? Is it the javascript or the controller?
EDIT: I'm getting this in laravel.log
exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53
Route
Route::resource('articles', 'ArticlesController');
Controller
public function store(Requests\ArticleRequest $request)
{
$article = new Article($request->all());
Auth::user()->articles()->save($article);
$response = array(
'status' => 'success',
'msg' => 'Article has been posted.',
);
return \Response::json($response);
}
jQuery
$(document).ready(function() {
$('#frm').on('submit', function (e) {
e.preventDefault();
var title = $('#title').val();
var body = $('#body').val();
var published_at = $('#published_at').val();
$.ajax({
type: "POST",
url: 'http://localhost/laravel-5/public/articles/create',
dataType: 'JSON',
data: {title: title, body: body, published_at: published_at},
success: function( data ) {
$("#ajaxResponse").append(data.msg);
console.log(data);
}
});
});
View
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<h1>Write a New Article</h1>
<hr>
{!! Form::open(['url' => 'articles', 'id' => 'frm']) !!}
<p>
{!! Form::label('title', 'Title:') !!}
{!! Form::text('title') !!}
</p>
<p>
{!! Form::label('body', 'Body:') !!}
{!! Form::textarea('body') !!}
</p>
<p>
{!! Form::label('published_at', 'Date:') !!}
{!! Form::input('date', 'published_at', date('Y-m-d'), ['class' => 'form-control']) !!}
</p>
<p>
{!! Form::submit('Submit Article', ['id' => 'submit']) !!}
</p>
{!! Form::close() !!}
<h3 id="ajaxResponse"></h3>
#if($errors->any())
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="{{ URL::asset('assets/js/ArticleCreate.js') }}"></script>
});
When you make a request via POST to a resource controller, it automatically calls store method:
Verb Path Action Route Name
----------------------------------
POST /articles store articles.store
So, you just need to change ajax url to:
$.ajax({
type: "POST",
url: 'http://localhost/laravel-5/public/articles',
When you need to send the session token, you can add a global meta-tag like this is you website:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then, just add the token via ajax's headers:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
If you are using Form::open() function (LaravelCollective) it adds a hidden input with the token as value with the name _token. So, you can remove the meta-tag and edit your ajax's headers like this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
}
});
That's what I got exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53
You're hitting Laravel's CSRF protection.
http://laravel.com/docs/5.1/routing#csrf-protection
You need to pass the hidden _token field's value. This can be done automatically on all jQuery-initiated AJAX requests by doing this in your application's JS:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('input[name="_token"]').value()
}
});
Or, you can manually fetch and pass the value of the _token hidden field in each of your AJAX calls.
I like to share this code to help someone to need ajax post and get with laravel
<<<<<<<<
POST
<<<<
<<look after #extends<<
<<look beforeSend: function (xhr) <<
<<look use Illuminate\Http\Request in Routes<<
<<<------<<views\login\login.blade.php<<<<-----------<<<
#extends('cuerpito.web')
<meta name="csrf_token" content="{{ csrf_token() }}" />
#section('content')
<form action="#" id="logForm" method="post" class="form-horizontal">
<div class="form-group">
<div class="col-xs-12">
<div class="input-group">
<input type="email" id="email" name="email" class="form-control input-lg" placeholder="Ingresa tu Email." autocomplete="off">
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<div class="input-group">
<input type="password" id="password" name="password" class="form-control input-lg" placeholder="Ingresa tu Contraseña." autocomplete="off">
</div>
</div>
</div>
<div class="form-group formSubmit">
<div class="col-xs-12">
<div class="input-group">
<button type="submit" name="feedbackSubmit" id="feedbackSubmit" class="btn btn-success btn-lg" style="display: block; margin-top: 10px;">Ingresar</button>
</div>
</div>
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
$("#feedbackSubmit").click(function () {
$.ajax({
url: '{{URL::route('login4')}}',
type: "post",
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: $("#logForm").serialize(),
success: function (data)
{
if (data) {
alert(data);
console.log(data);
} else {
console.log(data);
}//else
}//success
});//ajax
return false;
});//feedbacksubmit
});//document ready
</script>
-------------0----------------------
-------------0----------------------
<<<----<<app\Http\routes.php<<<<-----------<<<
<?php
use Illuminate\Http\Request;
Route::post('login4', function()
{
return 'Success! POST Ajax in laravel 5';
})->name('login4');
------------------0----------------------
------------------0----------------------
<<<<
Get
<<look after #extends<<
<<look beforeSend: function (xhr) <<
<<look use Illuminate\Http\Request in Routes<<
<<<------<<views\login\login.blade.php<<<<-----------<<<
#extends('cuerpito.web')
<meta name="csrf_token" content="{{ csrf_token() }}" />
#section('content')
<form action="#" id="logForm" method="post" class="form-horizontal">
<div class="form-group">
<div class="col-xs-12">
<div class="input-group">
<input type="email" id="email" name="email" class="form-control input-lg" placeholder="Ingresa tu Email." autocomplete="off">
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<div class="input-group">
<input type="password" id="password" name="password" class="form-control input-lg" placeholder="Ingresa tu Contraseña." autocomplete="off">
</div>
</div>
</div>
<div class="form-group formSubmit">
<div class="col-xs-12">
<div class="input-group">
<button type="submit" name="feedbackSubmit" id="feedbackSubmit" class="btn btn-success btn-lg" style="display: block; margin-top: 10px;">Ingresar</button>
</div>
</div>
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
$("#feedbackSubmit").click(function () {
$.ajax({
url: '{{URL::route('login2')}}',
type: "get",
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
data: $("#logForm").serialize(),
success: function (data)
{
if (data) {
obj = JSON.stringify(data, null, " ");
var datito = JSON.parse(obj);
console.log(datito.response);
alert(datito.response);
} else {
console.log(data);
}//else
}//success
});//ajax
return false;
});//feedbacksubmit
});//document ready
</script>
-------------0----------------------
-------------0----------------------
<<<----<<app\Http\routes.php<<<<-----------<<<
<?php
use Illuminate\Http\Request;
Route::get('login2', 'WebController#login2')->name('login2');
-------------0----------------------
-------------0----------------------
<<<----<<Http\Controllers\WebController.php<<<<-----------<<<
public function login2(Request $datos) {
if ($datos->isMethod('get')) {
return response()->json(['response' => 'This is get method']);
}
return response()->json(['response' => 'This is post method']);
}
-------------0----------------------
-------------0----------------------
You can add your URLs to the VerifyCsrfToken.php middleware. The URLs will be excluded from CSRF verification:
protected $except = [ "your url", "your url/abc" ];
Well if you are looking for the sure shot answer ,here it is :
This error particularly occurs if you are missing csrf_token() in your code
Here is what I did,
<h6>ITEMS ORDERED:CLICK HERE</h6>
<input type="hidden" id="token" value="{{ csrf_token() }}">
Now With Ajax
<script type="text/javascript">
function getcart(val) {
var alpha=val;
var token=document.getElementById('token').value;
$.ajax({
type:'post',
url:'/private/getcart',
data:{'alpha':alpha,'_token': token},//this _token should be as it is
success:function (result) {
alert(result);
}
});
}
</script>
In my laravel controller
public function getcart(Request $req)
{
return response ("its");
}