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.
Related
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.
I want to save the ajax response I get into my database. The problem is that my ajax function doesn't allow my to put a insert query. When I Insert the insert query, my response doesn't work anymore and vice versa.
where ajax file is
public function submit() {
$data = array(
'user_id' => '1',
'swipedpicture' => $this->input->post()
);
$this->db->insert('tbl_results', $data);
print json_encode($data);
}
Ajax Jquery
var pic = $(this).find('input[name="inputcountry"]').attr('value');
jQuery.ajax({
type: "POST",
url: window.location.origin +"/swipr/index.php/preferences/submit",
dataType: 'json',
data: {swipedpic: pic},
success: function(res) {
if (res) {
console.log(res.swipedpicture);
}
}
});
Your javascript is setting a data element for posting that the submit function is not using.
The submit function should look like this.
$data = array(
'user_id' => '1',
'swipedpicture' => $this->security->xss_clean($this->input->post('swipedpicture'))
);
$this->db->insert('tbl_results', $data);
$response_array['status'] = 'success';
echo json_encode($response_array);
The javascript should look more like this. I used an form id of form1 and a form element of swipedpicture.
$('#form1').submit(function(e){
e.preventDefault();
$.ajax({
url: 'example_answer_submit',
type: 'POST',
data: $('#form1').serialize(),
success: function (msg) {
if (!msg) {
console.log('error');
} else {
console.log('success');
}
}
});
return false;
});
The form I used.
<h1 class="page-header text-center">Test Form</h1>
<form id="form1" class="form-horizontal" role="form" method="post" action="">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Swiped Picture</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="swipedpicture" name="swipedpicture" placeholder="Pic" value="">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<input id="submit" name="submit" type="submit" value="Send" class="btn btn-primary">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<?php echo $result; ?>
</div>
</div>
</form>
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"}"
I've my call to ajax
$("#box-modal").on("shown",function(event)
{
$("#selectproductname").change(function(){
var valueProduct = $(this).val();
event.preventDefault();
$.ajax({
type:'GET',
url:'/ajax/products_ajax.php?idProducto='+valueProduct+'&opcion=2',
async:true,
datatype:'text',
success: function(data)
{
$("#editor-panel").load("/ajax/order.html");
$("#editor-actions").removeClass("hidden");
var inputs = document.getElementById('editor-panel').getElementsByTagName('input');
if(debug)
{
inputs[0].value="holaaa";
}
}
first I get the data with php, I get
1#jeans*1.00**0#100
after I want to assign this data a my order.html,
example:
inputs[1].value = jeans
inputs[2].value = 1.00
inputs[3].value = null
I get with console.log(inputs)
[item: function, namedItem: function]
0: input#inputnombre
1: input#inputidproducto
2: input#inputprecio.form-control
3: input#inputcantidad.form-control
4: input#inputdescatalogado.form-control
inputcantidad: input#inputcantidad.form-control
inputdescatalogado: input#inputdescatalogado.form-control
inputidproducto: input#inputidproducto
inputnombre: input#inputnombre
inputprecio: input#inputprecio.form-control
length: 5
When I do inputs[0].value="hello";
I get the error:
Uncaught TypeError: Cannot set property 'value' of undefined
In ajax order I have:
<div class="panel panel-body">
<form role="form" class="form-horizontal" id="form_order">
<div class="form-group">
<label for="inputnombre" class="col-md-4 col-xs-4 control-label">Nombre producto</label>
<div class="col-md-4 col-xs-4 control-label">
<input id="inputnombre" name="inputnombre" required type="text" />
<input type="hidden" name="inputidproducto" id="inputidproducto"/>
</div>
</div>
<div class="form-group">
<label for="descripciontext" class="col-md-4 col-xs-4 control-label">Descripcion</label>
<div class="col-md-4 col-xs-4 control-label">
<textarea cols="30" rows="10" id="descripciontext" name="descripciontext"></textarea>
</div>
</div>
<div class="form-group">
<label for="inputprecio" class="col-md-4 col-xs-4 control-label">Precio</label>
<div class="col-md-4 col-xs-4 control-label">
<input id="inputprecio" name="inputprecio" class="form-control" required type="text" />
</div>
How could I make the code easier?
Ajax .load takes time, you need to assign your values when .load is completed
$("#box-modal").on("shown", function(event) {
$("#selectproductname").change(function() {
var valueProduct = $(this).val();
event.preventDefault();
$.ajax({
type: 'GET',
url: '/ajax/products_ajax.php?idProducto=' + valueProduct + '&opcion=2',
async: true,
datatype: 'text',
success: function(data) {
// Ajax load takes time, you need a complete function here
$("#editor-panel").load("/ajax/order.html", function() {
// do below when "/ajax/order.html" is loaded
$("#editor-actions").removeClass("hidden");
var inputs = document.getElementById('editor-panel').getElementsByTagName('input');
if (debug) {
inputs[0].value = "holaaa";
}
});
}
});
});
});
var inputs = document.getElementById('editor-panel').getElementsByTagName('input');
jquery
var inputs = $("#editor-panel input").eq(0).val("hello");