Ajax get request laravel 5.4 resource controller - php

I've been searching for similar question in a while but I couldn't find what would actually help my issue.
Using Laravel 5.4.
So I have a resource controller and its index method that returns a view with some data attached to it.
Then I want to make an ajax request from the view returned which is a search request.
e.preventDefault();
let q = $('#inputserver').val();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "/servers",
type: 'GET',
data: {'data': q},
success: function(response){
console.log('Successo');
}
})
That, for how a resource controller's methods are structured should invoke the index method, in which I want to identify if I have an Ajax request incoming.
If I do, I'll search with a query in an Eloquent Model for the data retrieved by the search form and of course I want to show only the matching results.
This is my controller code:
if(!$request->ajax()){
$colonna = 'id';
$servers = Server::orderBy($colonna, 'desc')->paginate(10);
return view('servers.index', array('servers' => $servers));
}
else{
$servers= Server::where('name', '=', $request->data)->paginate(10);
return view('servers.index', array('servers' => $servers));
}
The issue is that nothing is happening, so the ajax request isn't even considered, can someone help me with this? I'm almost sure the issue is some obvious things I forgot or didn't consider.
Thank you in advance, I'll edit if you would need some more info about it.
EDIT:
This is the route I have Route::resource('servers', 'ServerController');
EDIT2:
I'm sorry ids are in Italian, but I of course select them correctly when using jQuery.
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
<div class="input-group-addon">
<span>
<i class="fa fa-search"></i>
</span>
</div>
{{Form::text('search', null, array('class' => 'form-control', 'id' => 'inputserver' , 'placeholder' => 'Cerca..'))}}
<span class="input-group-btn">
<button class="btn btn-default" type="button" id="cercaserver">Go!</button>
</span>

The blade file is messy.Try to create a form open and form close and make the button submit of type. And try to change your ajax to this:
$(document).ready(function() {
$('#cercaserver').on('submit', function (e) {
e.preventDefault();
var input = $('#inputserver').val();
$.ajax({
type: "GET",
url: './servers',
data: {input: input},
});
});
});
make sure you are loading jquery.

What do you mean by nothing's happening? What was shown in the console when the ajax request was fired?
Also, you're returning a view, you might want to return a json array of your results?
return $servers;
Laravel will automagically convert it into a JSON response
https://laravel.com/docs/5.4/responses#creating-responses
Or if you want to be specific:
return response()->json($servers);
https://laravel.com/docs/5.4/responses#json-responses
Edit:
I think I already know the problem, in your resource controller function index, is there a parameter called $request? It might be non existing and for sure will throw a 500 internal server error because you used it in your condition.

Related

Disable multiple button clicks works but is not updating my data

I am trying to prevent a button to be clicked multiple times to avoid resending requests. The disabling works but my data to be sent or updated is not executed.
<form class="detail_form" method="POST" action="{{ url('update', $id) }}" enctype="multipart/form-data">
#csrf
<button class="btn btn-update accntfrm_btn" type="submit" id="btn-update">Update</button>
</form>
$("#btn-update").on('click', function (event) {
event.preventDefault();
$(this).prop('disabled', true);
setTimeout(function(){el.prop('disabled', false); }, 3000);
});
How can I execute my updates and disallow the multiple clicks at the same time?
Use like this in action attribute of Form,
{{ route('update', ['id'=>$id]) }}
I guess it is your route,
Route::post('/update/{id}','YourController#your_function')->name('update');
and in your controller,
public function your_function(Request $request, $id){ // your code }
and if you want to go pure laravel,
use Form class
{!! Form::open(['route' => ['update', 'id'=>$id], 'files' => true, 'class' => 'detail_form']) !!}
event.preventDefault();
prevents default action of the form, this means that your form is not going to submit to the server. what you can do is use ajax or maybe axios if you have it installed to send your information to the server. Since you obviously have jquery, you can make an ajax request to your server to update your information like so
`const route = "{{ route('update', $id)}}";`
or
const route = "/route/to/your/server";
`$.post(route,
{//add a body if you need to send some information to the server
//it is optional},
function(data, status){// in this callback you can create a feedback
//from a successful trip to and from the server
//for your users
})`
.fail(function(error){
//in this callback you can handle errors from a failed trip
//to and from the server
});

How to populate view with database information after AJAX request

Hi there once again SO community. I've been developing a site and so far it's going pretty well. But today after a long day searching for a solution I can't understand nor find what the right path is...
I want to click on a button and a profile page where you can edit the fields appear. I can redirect to the page I want but I don't know how to send the user data so I can populate the fields.
Here is my button code on my view
<button class="btn btn-xs btn-warning dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false" style="border-color: black" id="dados_{{ $user->username }}"> Alterar Dados Pessoais
<i class="glyphicon glyphicon-cog"></i>
</button>
Here is the button AJAX request handler
if((this.id).indexOf("dados") != -1){
var content = this.id.replace("dados_", "");
$.get('callPermissions', {usernameSend:content, '_token': $('meta[name=csrf-token]').attr('content'),}, function(data){
window.location.replace('settings');
});
And here is my callPermission Controller
public function callPermissions(Request $request)
{
if($request->ajax()){
$usernames = Input::get('usernameSend');
if(isset($usernames)){
$user = User::Where('username', '=', $usernames)->first();
$returnHTML = view('userOptions.settings')->render();
return view('userOptions.settings');
}else{
Log::warning("Username não existe na base de dados.");
}
}
}
and here my Settings Controller
public function settings(Request $request)
{
return view('userOptions.settings');
}
And here is the route
Route::get('/callPermissions', 'SidebarController#callPermissions');
I know the controller is wrong and from what I've read I should verify if the AJAX is successful and if it is handle i on the AJAX request. But from what I've understand I'm not using the Controller at all (even though it goes there). How should I send the user information (in this case the username, then I can get everything from the database) and then send it to the view? I've been searching and trying out stuff that doesn't work...since the return view("your_view") on the Controller doesn't work.
Sorry if I've been confusing and if you need additional information feel free to ask!
Thanks for your help!!
Edit: If I return this on the controller
return view('userOptions.settings', compact('user'));
and do a replace with the Ajax request as show above and add this to the settings view
<p> {{ $user->name }} </p>
I get the following error Undefined variable: user (View: C:\wamp64\www\siteXL\ideiasxl\resources\views\userOptions\settings.blade.php)
Is there anyway to send the parameters with a compact alike or I need to send it through the link? Was avoiding to show the username on the url.
Edit2: For further clarification, this works as intended
<button onclick="window.location='{{url('/settings/' . $user->username)}}'" type="button" id="dadosPessoais" class="btn btn-default">Alterar Dados Pessoais
<i class="glyphicon glyphicon-wrench"></i>
</button>
but I was trying not to send id's and usernames through the URL.
If this is not achievable it's ok, but if there's a way I can't find it, that's why I'm asking
I think you have to add a parameter in the Route and receive the data in the controller function. I'd do something like this:
Route:
Route::get('/callPermissions/{user}', 'SidebarController#callPermissions');
Controller:
public function callPermissions(Request $request, $user)
{
//get data related to $user
}
Ajax call:
$.get('callPermissions/'+userIdVariable, {usernameSend:content, '_token': $('meta[name=csrf-token]').attr('content'),}, function(data){
window.location.replace('settings');
});
This would send the user id through the route.
To get the user id with JavaScript, you can make a hidden field in the Blade file and set the user id as the value. For example, if you using Form helper:
{{ Form::hidden('user_id', $user->id, array('id' => 'js-user-id')) }}
And then, in the JavaScript, you can get the value using something like this:
var userIdVariable = $('#js-user-id')->val();

Can't query JSON (Laravel + VueJS)

my problem exactly smiliar with this one cant't query json data in laravel 5.2
Already try to implement the right answer from it but still, no luck.
I don't know why....
Previous, i found this Laravel 5.2 Codeception functional test issue with PUT / PATCH requests too, already try to use suggestion from him, but no luck too.
Here's my Laravel Controller
public function update(Request $request, $id)
{
$phonebook = Phonebook::findOrFail($id);
$phonebook->update($request->all());
// even i try this
// Phonebook::findOrFail($id)->update($request->all());
// return Response::json() or return response()->json();
// No luck
}
My function in vue script for update data
editContact: function(id)
{
this.edit = true
var contactid = this.newContact.ID
this.$http.patch('/api/contact/' + contactid, this.newContact, function (data) {
console.log(data)
})
},
Change my vue script to be like the right answer from question above, same result. No effect.
And my button to do edit like this
<form action="#" #submit.prevent="addNewContact">
<div class="form-group">
<label for="contactName">Name : </label>
<input type="text" v-model="newContact.CONTACTNAME" class="form-control" id="contactName">
</div>
<div class="form-group">
<label for="phoneNumber">Phone number : </label>
<input type="text" v-model="newContact.PHONENUMBER" class="form-control" id="phoneNumber">
</div>
<div class="form-group">
<button class="btn btn-primary btn-sm" type="submit" v-if="!edit">Add new Contact</button>
<button class="btn btn-primary btn-sm" type="submit" v-if="edit" #click="editContact(newContact.ID)">Edit Contact</button>
</div>
</form>
Note :
My route file using resource or manual route always same
Route::resource('/api/contact/', 'PhonebookController');
or
patch('/api/contact/{id}', ['uses' => 'PhoneboookController#update']);
And then, there something strange.
(Maybe i am wrong) there no issue or error if we look the detail. But, if we change to response tab the result was empty
After all that process, nothing happen with the data.
CONTACTNAME should be "Mizukiaaaaaaaa" like first screenshot instead of "Mizuki"
Am I missing something??
Any advise?
Thanks
As I suggested to you, try to invert the params in your update method in your controller.
And to get a response, you have to send it back (with code 200, 400, 401, whatever you want).
public function update($id, Request $request)
{
$phonebook = Phonebook::findOrFail($id);
$phonebook->update($request->all());
// your treatment
return Response::json([
'param' => 'value'
], 200);
}
If you want to debug and see it in you response, you can make a dd('debug')in your method, you'll see it in the Ajax request response.
That should work for you !
After browsing and ask so much people about this, finally found it! There's nothing wrong with the request or response. My mistakes are mutator update that i used and my model.
Updated answer
Reason answered here and then I just changed update function on controller. Here the result
public function update(Phonebook $phonebook, Request $request, $id)
{
// You can add any fields that you won't updated, usually primary key
$input = $request->except(['ID']);
// Update query
$saveToDatabase = $phonebook->where('ID', '=', $id)->update($input);
return $saveToDatabase;
}
My previous answer updated all fields including the primary key, somehow it successful update data, but it leave error for sure (duplicate primary key). The query looks like UPDATE SET field = 'value' without condition.
This case is for model that doesn't have any relation with other models (tables), or the model act as master.

Ajax on JQuery drag event

I'm creating a nested list with data from database. On this list, I'm using the JQuery UI Drag effect. What I need to do is when the drag is over, it will update the database.
The list coints Professor's name and his ID, it has as sub-list with his classes, like:
John teaches Math & physics, Dwayne teaches English.
John
*Physics
*Math
Dwayne
*English
Let's say I want to give Math class to Dwayne. So I'll drag Math from John and drop it on Dwayne sub-list. It's working fine.
What I can't do is to make the update on database, because John no longer teaches Math instead John is going to teach it. So I need to make an update there or a delete+insert.
Obs: I'm using laravel
Here is my Code:
#extends('app')
#section('assets')
<script type="text/javascript" src="{{ URL::to('/js/jquery.mjs.nestedSortable.js') }}"></script>
#stop
#section('content')
<ol>
#foreach($professores as $prof)
<li data-id=" {{ $prof->id }}">
{{ $prof->nome }}
<ol class="list-disc">
#foreach($prof->disc as $disc)
<li data-id="{{ $disc->id }}">{{ $disc->nome }}</li>
#endforeach
</ol>
</li>
#endforeach
</ol>
<script type="text/javascript">
$(function(){
var old_teacher;
$('.list-disc').sortable({
connectWith: '.list-disc',
start: function (event, ui){
old_teacher = ui.item.parent().parent().attr('data-id');
},
stop: function (event, ui){
$.ajax({
type: "POST",
url: '{{ URL::to("/professor") }}',
data: {disc: ui.item.attr('data-id'), professor: ui.item.parent().parent().attr('data-id'), old: old_teacher},
success: function(data){
console.log(data);
}
});
}
});
})
</script>
#stop
With this currently code, When I drop the item I get:
Internal Server Error (500)
UPDATE
Route File:
Route::post('professor', [
'uses' => 'ProfessorController#postProfessorList'
]);
Controller File:
public function postProfessorList()
{
Professor::submit(Input::post('disciplina'), input::post('professor'), input::post('old'));
}
Log file: Update
local.ERROR: exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Call to undefined method Illuminate\Http\Request::post()' in F:\PathToProject\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:210
Internal Server Error (500) means that something is wrong with your server-side (laravel) code.
Can you provide us with the code which is used in POST: /professor ?
EDIT
You might want to check your logs in app/storage or storage/ (depending on the laravel version). They should give you a better description of the error that occurs.
Also, you should replace Input::post('...') with Input::get('...') laravel takes care of $_GET and $_POST variables automatically.
EDIT 2
The error you get is due to Laravels CSRF protection.
You will need to set the csrf token in your ajax request like that:
data: {disc: ....., _token: '{{csrf_token()}}' }

How to post data to database using Ajax call in Laravel?

I have a subscribe box :
My goal is when the user enter the email, I want to save it to my database.
I already know how to achieve this using form post via Laravel.
Form POST via Laravel
public function postSubscribe() {
// 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');
}
}
Now, I want to achieve this using Ajax call to avoid the page load and also to learn more about Ajax. Here are what I've tried :
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"><input type="submit" value="Subscribe" name="subscribe" id="subscribe" class="btn btn-primary btn-block"></div>
{!! Form::close() !!}
Ajax Call
<script type="text/javascript">
$(document).ready(function(){
$('#subscribe').click(function(){
$.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);
});
});
});
</script>
Controller
public function postSubscribeAjax() {
// Getting all post data
if(Request::ajax()) {
$data = Input::all();
die;
}
dd($data);
}
Route
Route::post('/subscribe','SubscribeController#postSubscribeAjax');
Result
I keep getting:
Undefined variable: data
Which mean my Request::ajax() is not containing anything? Why is that?
How can I achieve this using an Ajax call?
This was resolved in Chat
We had to fix a couple syntax errors and change the input button to a html button so that it would prevent the form from submitting. There are other ways we could have done this, but this worked.
So I'm going to address a few things here. Starting from bottom moving on up!!
Route
You can do this without the slash.
Route::post('subscribe','SubscribeController#postSubscribeAjax');
Controller
Your Controller is good enough, but you need to actually display the result from the ajax. We will handle that.
Remove the die in your check if there is an Ajax request.
Ajax
<script type="text/javascript">
$(document).ready(function(){
$('#subscribe').click(function(e){
e.preventDefault(); // this prevents the form from submitting
$.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>
Form
Pretty sure the form is good.
Assuming the "Undefined variable" error is happening in your postSubscribeAjax method, it looks like you have a problem with scope. Specifically, when the PHP interpreter gets to the line dd($data), the variable $data has not been defined yet.
This is not surprising, since $data is assigned inside the block of code following an if statement - it is not available outside that block.
You can solve this problem by adding $data = null; before the if statement, BUT... this is only going to show you that you have a different problem. Here's why:
You're getting an "undefined variable" error. The means that your code is skipping the if block (how do I know this? because if it didn't skip it, it would execute the die statement and you'd never see the error). This means that your code is not correctly identifying the request as an AJAX request.
What I would do is this: skip the if block entirely. Simply get your data and process it.
It's been a while since I looked at this stuff, but IIRC, there is no reliable way to detect AJAX requests. To the server, an AJAX request is just like any other request. Some Javascript libraries (jQuery included, if I'm not mistaken) set a header on the request to identify it as AJAX, but it is neither universally required nor universally detected.
The only benefit to this AJAX detection is to prevent your users from accessing the AJAX URL directly from a browser. And, ultimately, if someone really wants to do that, you can't stop them since they can (with a little work) spoof any request.

Categories