In a Laravel app, I need to update some data in the database after a button is clicked, without reloading the page, thus requiring ajax. No data needs to parsed, only a function in one of the controllers should be invoked, so it's the simplest kind of ajax request.
Based on this example, I set up the following, but nothing happens. No error, no response from the check alert('success!'), nothing.
QUESTION: why does nothing happen? Could it be that the Javascript is not recognized at al?
Head
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Routes - web.php
Route::post('/notificationsSeen','NotificationController#seen');
Controller - NotificationController.php
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => 'seen'));
return;
}
View
<button type="button" id="notifications"></button>
<script>
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data:'_token = <?php echo csrf_token() ?>',
success:function(data){
alert('success!');
}
});
});
</script>
EDIT: WORKING SOLUTION
Change the contents of the box above labeled "View" to the following:
<button type="button" id="notifications"></button>
<script>
(function ($) {
$(document).ready(function() {
$('#notifications').on('click', function() {
$.ajax({
url: '/notificationsSeen',
type: 'POST',
data: { _token: '{{ csrf_token() }}' },
success:function(){alert('success!');},
error: function (){alert('error');},
});
});
});
}(jQuery));
</script>
In your AJAX request, data is not a string. It is a key value pair. So use
data: { _token: '{{ csrf_token() }}' }
You shouldn't pass the csrf token like this:
data:'_token = <?php echo csrf_token() ?>',
You have to store it in a HTML meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then automatically add the token to all request headers:
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data: {status: 'seen'},
success:function(data){
alert('success!');
}
});
});
});
Controller:
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => request()->input('status')));
return ['success' => true];
}
Related
<script type="text/javascript">
$(document).ready(function(){
$('#mainmenu').change(function(){
var main_menu_id = $('#mainmenu').val();
$.ajax({
type: 'POST',
url: '/sub',
data: {"main_menu_id": main_menu_id,_token: '{{csrf_token()}}'
success: function (data) {
var submenus = data.submenus;
for(var i=0; i<submenus.length; i++){
$('#submenu').append('<option>'+submenus[i]+'</option>');
}
},
error: function () {
alert('what ever');
}
});
});
</script>
My route
Route::post('/sub','TicketController#sub');
And my controller
public function sub(Request $request)
{
dd($request->all());
return Response([
'submenus' => DB::connection("mysql2")->table('applicationsubmenu')
->join('applicationmenu', 'applicationmenu.Id', '=',
'applicationsubmenu.ApplicationMenuId')
->select('applicationsubmenu.*')
->where('applicationmenu.MainMenuId', '=', $request->main_menu_id)
->get()->toarray(),
]);
}
I am trying to populate an option submenu from depending from user option menu selection.To do that I tried building an ajax but it seems not to work at all.Neither the laravel function seems to be called at all!
Try to setup the ajax requests on the project properly:
In header
<meta name="csrf-token" content="{{ csrf_token() }}" />
In script
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
Did you use ajax middleware
Route::post('/sub','TicketController#sub')->middleware('ajax');;
Why are you dumping the $request in your controller?
dd($request->all());
Laravel docs:
The dd function dumps the given variables and ends execution of the script https://laravel.com/docs/5.6/helpers#method-dd
Also when getting values from $request... you are doing this:
->where('applicationmenu.MainMenuId', '=', $request->main_menu_id)
but you should get the values like this:
->where('applicationmenu.MainMenuId', '=', $request->input('main_menu_id')
or if you want an array of request then you should set first:
$input = $request->all();
and then call the value like this:
$input->main_menu_id
you forget to send the token
$.ajax({
type: 'POST',
url: '/sub',
data: {'_token':'{{csrf_token()}}',"main_menu_id": main_menu_id},
success: function (data) {
alert(data);
},
error: function () {
alert('what ever');
}
});
I am new to Laravel and am using Laravel 5.3. I want to make a text field where it will automatically suggest some data and when I select a data it will add it to an array. I want to send that array to a controller for further use. For this the
view file is as follows:
<head>
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
$(document).ready(function() {
var members = {!! json_encode($member) !!};
console.log(members);
var arr = [];
$("#tags").autocomplete({
source: members,
select: function (event, ui) {
arr.push(ui);
console.log(arr);
}
});
$("#submit").click(function(event){
$.ajax({
type: "POST",
url: '/storeresearch',
data: {selectedMembers: arr},
success: function( msg ) {
console.log(msg);
}
});
});
});
</script>
</head>
<body>
<form id="hu" action="/storeresearch" method="POST">
{!! csrf_field() !!}
<label>Research Author</label>
<input type="text" id="tags" name="researchsupervisor_1" value="">
<input type="submit" name="submit" id="submit" class="btn btn-primary" value="Add">
</form>
</body>
My Controller file is as follows:
public function store(Request $request){
if($request->ajax())
{
$mem = $request->all();
return response()->json($mem,200) ;
}
else{
return "not found";
}
And web.php is as followings:
Route::post('/storeresearch','ResearchController#store');
But it seems that there is no ajax call happening. In the controller it always enters the else section. What is the problem can anyone help?
Your code mostly looks good. But you are missing to send a csrf token with AJAX call as you are using POST request.
You can send csrf token with AJAX call in this way:
<meta name="csrf-token" content="{{ csrf_token() }}">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
More info: https://laravel.com/docs/5.3/csrf#csrf-x-csrf-token
When you hit the button, does it really fires an AJAX call? Please check that on network tab of browser.
I solved this problem by doing following
$.ajax({
type:'POST',
url:'your url',
data:{_token: "{{ csrf_token() }}"
},
success: function( msg ) {
}
});
Try some thing like this:
$.ajax({
url : '/login',
method : 'post',
data : {
login_username : userName,
password : password
},
headers:
{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success : function(response){
}
});
Route:
Route::post('/login',[
'uses' => 'AdminServiceController#login'
]);
Controller method:
public function login()
{
$userName = INPUT::get('login_username');
$password = INPUT::get('password');
// your logic
}
What's your namespace declaration for Request ?
If it is use Illuminate\Http\Request; try use Request;
Before marking it as duplicated, i tried the other solutions found on the web, including SO, and none of them solved my issue.
I'm using x-editable plugin to store a new record using a store route.
When the form is submitted, i get a 500 with TokenMismatchException error.
I know about setting the csrf token thing, but i tried it in several ways, and nothing is working.
That's my javascript code:
$.fn.editable.defaults.params = function (params) {
params._token = window.Laravel.csrfToken;
return params;
};
$('.editable').each(function () {
$(this).editable();
});
The html
<head>
[...]
<meta name="csrf-token" content="{{ csrf_token() }}">
[...]
<script>
window.Laravel = <?php
echo json_encode([
'csrfToken' => csrf_token(),
]);
?>
</script>
[...]
</head>
<button id="note-asl-text"
data-type="textarea"
data-placeholder="Aggiungi Nota"
data-url="{{route('ricettanota.store')}}"
data-title="Inserisci una nuova nota"
data-highlight="false"
data-mode="inline"
data-send="always"
data-showbuttons="bottom"
class="editable"
>Aggiungi nota</button>
The Route
Route::resource('ricettanota', 'RicettaNotaController');
I already tried all possible combinations of the following:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': window.Laravel.csrfToken
}
});
$('.editable').each(function () {
$(this).editable({
ajaxOptions: {contentType: 'application/json', dataType: 'json'},
params: function (params) {
params._token = window.Laravel.csrfToken;
return JSON.stringify(params);
}
});
});
note
$('meta[name="csrf-token"]').attr('content') and window.Laravel.csrfToken are the same
update
I found out that placing Route::resource('ricettanota', 'RicettaNotaController'); into the api routes file(api.php) causes the issue, while placing the routes into the web routes file (web.php) and using the code above works.
Why using the API i get token mismatch, is still a mystery.
Not sure if this is what you are looking for, but maybe you should not struggling in sending custom header with x-editable plugin, but sending custom parameters.
The following code works for me.
$(document).ready(function() {
$.fn.editable.defaults.mode = 'popup';
$('.node').editable(
{
params: function(params) {
var data = {};
data['_csrf_token'] = $(this).data("csrf");
return data;
},
}
);
});
Set csrf in your a-tag or somewhere else you like.
<a href="#" ... data-csrf="xxxxxxx" /a>
Hope this helps.
try this in your ajaxSetup
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
I also faced same issue in Laravel 5.8. Following code worked for me.
$.fn.editable.defaults.ajaxOptions = {
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
};
this is use code
$.ajax({
type: 'POST',
url: url,
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
dataType:'html',
data:data,
success:function(data){
}});
this Follow link
https://laravel.com/docs/5.3/csrf#csrf-x-csrf-token
Whats the correct way to pass data to ajax using jquery. I have the following method and I want to pass the CSRF token from a meta tag but it doesn't work.
<meta name="csrf-token" content="{{ csrf_token() }}">
<div class="fallback">
<input type="file" name="logo" id="logo" class="inputfile"/>
</div>
$(document).on("change", ".fallback .inputfile", function() {
$.ajax({
url: "/upload",
type: 'POST',
cache: false,
data: {
_token: $('meta[name="csrf-token"]').attr('content')
},
files: $(":file", this),
iframe: true,
processData: false
}).complete(function(data) {
console.log(data);
// $('#img-thumb').attr('src', data.path);
// $('input[name="job_logo"]').val(data.path);
});
});
Laravel method to process the file:
public function upload(Request $request) {
if($request->hasFile('logo')) {
//upload an image to the /img/tmp directory and return the filepath.
$file = $request->file('logo');
$tmpFileName = time() . '-' . $file->getClientOriginalName();
$tmpFilePath = '/img/tmp/';
$file = $file->move(public_path() . $tmpFilePath, $tmpFileName);
$path = $tmpFilePath . $tmpFileName;
return response()->json(['path'=> $path], 200);
} else {
return response()->json(false, 200);
}
}
I've followed the documentation from the following source https://cmlenz.github.io/jquery-iframe-transport/
I get tokenmismatch error. Note this is using Laravel 5.1
* UPDATE *
Should be able to add the token directly to data attribute as the csrf token is already in my meta tag. Below is an example done using backbone.js/ruby on rails, but I'm not an expert on backbone/rails so if any one can translate that into jquery it would be helpful. (http://estebanpastorino.com/2013/09/27/simple-file-uploads-with-backbone-dot-js/)
uploadFile: function(event) {
var values = {};
var csrf_param = $('meta[name=csrf-param]').attr('content');
var csrf_token = $('meta[name=csrf-token]').attr('content');
var values_with_csrf;
if(event){ event.preventDefault(); }
_.each(this.$('form').serializeArray(), function(input){
values[ input.name ] = input.value;
})
values_with_csrf = _.extend({}, values)
values_with_csrf[csrf_param] = csrf_token
this.model.save(values, { iframe: true,
files: this.$('form :file'),
data: values_with_csrf });
}
processData: false
You've told jQuery to not convert the object containing your data into a format suitable for transmitting over HTTP.
You need to add this to your page:
$(function() {
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN' : '{{ csrf_token() }}' } });
});
This is because the AJAX needs the X-CSRF-TOKEN everytime you send an AJAX request to the server (unless you turn it off, which I don't recommend).
SOURCE: my own experiences with Laravel.
I am trying to create a live search using jquery, ajax and laravel. I also use pjax on the same page, this might be an issue?. Quite simply it should query the database and filter through results as they type.
When using Ajax type:POST I am getting 500 errors in my console. I get zero errors using GET but instead of returning in #foreach it will a full page view (this might be because of pjax).
Where am I going wrong?
Route:
Route::post('retailers/{search}', array(
'as' => 'search-retailers', 'uses' => 'RetailersController#search'));
Controller:
public function search($keyword) {
if(isset($keyword)) {
$data = array('store_listings' => RetailersListings::search($keyword));
return $data;
} else {
return "no results";
}
}
Model:
public static function search($keyword)
{
$finder = DB::table('retailers_listings')
->Where('city', 'LIKE', "%{$keyword}%")
->orWhere('country', 'LIKE', "{$keyword}")
->orderBy('country', 'asc')
->get();
return $finder;
}
View (store.blade.php):
<div id="flash"></div> //loading
<div id="live"> // hide content
<div id="searchword"><span class="searchword"></span></div> //search word
<table class="table">
<tbody>
#foreach($store_listings as $store)
<tr>
<td></td> //echo out all fields eg: {{ $store->name }}
</tr>
#endforeach
</tbody>
</table>
</div>
Form:
<form method="get" action="">
<input type="text" class="search-retailers" id="search" name="search">
</form>
Ajax and JS:
$(function() {
$("#search").keyup(function() {
var keyword = $("#search").val();
var dataString = 'keyword='+ keyword;
if(keyword=='') {
} else {
$.ajax({
type: "GET",
url: "{{ URL::route('search-retailers') }}",
data: dataString,
cache: false,
beforeSend: function(html)
{
document.getElementById("live").innerHTML = '';
$("#flash").show();
$("#keyword").show();
$(".keyword").html(keyword);
$("#flash").html('Loading Results');
},
success: function(html)
{
$("#live").show();
$("#live").append(html);
$("#flash").hide();
}
});
} return false;
});
});
Additional, Here is my controller for pjax, It is important to note I am using the view store.blade.php foreach in for the search and for this store listing.
public function stores($city)
{
$this->layout->header = $city;
$content = View::make('retailers.stores', with(new RetailersService())->RetailersData())
->with('header', $this->layout->header)
->with('store_listings', RetailersListings::stores($city));
if (Request::header('X-PJAX')) {
return $content;
} else {
$this->layout->content = $content;
}
}
Your route is Route::post('retailers/{search}', [...]) and there you go. You pass data to your ajax-call. In GET you get something like url?key=value but using POST the data are added to the request body not to the url.
Knowing this your route is no longer valid since it only looks up for retailers/{search} and not for retailers only (which is the url POST is using).
Well maybe it could help somebody.
As a first problem you are defining the route as POST and then in the ajax request the type GET so it would not work
Also when making POST request Laravel has the csrf check so in order to work, provide it. The js function will be like
$(function() {
$("#search").keyup(function() {
var keyword = $("#search").val();
if(keyword=='') {
} else {
$.ajax({
type: "post",
url: "{{ URL::route('search-retailers') }}",
data: {
'keyword': keywork,
'_token': '{{ csrf_token() }}';
},
dataType: 'html',
cache: false,
beforeSend: function(html)
{
document.getElementById("live").innerHTML = '';
$("#flash").show();
$("#keyword").show();
$(".keyword").html(keyword);
$("#flash").html('Loading Results');
},
success: function(html)
{
$("#live").show();
$("#live").append(html);
$("#flash").hide();
}
});
} return false;
});
});
And you can test your PHP search method doing separate tests for it.