Pagination Laravel AJAX? - ajax

By default Laravel pagination refresh page every time. I don't want this to happen
public function getPaginate($n)
{
return $this->model->with('professional')
->orderBy('extras.created_at', 'desc')
->paginate($n);
}
In the controller :
$extras = $this->extraRepository->getPaginate(3);
$links = $extras->render();
And i send $link to the view.
<div class="pagination">{!! $links !!}</div>
</div>
</div>
<div class="row">
<div class="small-12 columns">
<ul class="large-block-grid-3 medium-block-grid-2 small-block-grid-1">
#if(empty($extras))
<p class="empty-notice">Sorry, no extra available at the moment. Come back later</p>
#else
#foreach ($extras as $extra)
<li class="extra-available">#include('user.card', ["description" => $extra->professional->company_name." in ".
$extra->type.
' for '.$extra->date.' at '.$extra->date_time,
"title" => $extra->professional->company_name,
"image" => asset("../resources/assets/images/extra-card-example.png"),
"id" => $extra->id])
</li>
#endforeach
#endif
</ul>
</div>
</div>
I tried to implement an AJAX request like so :
$(".pagination a").click(function(e){
e.preventDefault();
var url = $(this).attr('href');
//alert(url);
$.ajax({
url: url,
type: "GET",
success: function(data){
$('.extra-available').html(data);
}
});
});
but it returns me an entire html doc, i just want what's in .extra-available.
Any ideas ?

I think it is better to prepare API to be called by your ajax in json format. The json return is very useful to do paginate. You will get as below data (in laravel 5.2).
{
"total": 18,
"per_page": 15,
"current_page": 1,
"last_page": 2,
"next_page_url": "http://example.com/products?page=2",
"prev_page_url": null,
"from": 1,
"to": 15,
"data": [] // a list of your data here
}
You API controller will be look like this. Dont need to use the $n. Laravel will get the current page from the page GET parameter
$data = Model::orderBy('extras.created_at', 'desc')->paginate();
return response()->json($data);
So your ajax code can call the next page data based in the next_page_url, as well as the previous page using prev_page_url if it exist. All about paging is there including total records, current page and total records display in page

Try this:
$(document).on('click', '.pagination a', function (e) { ...

Related

using axios data from Laravel pagination array

ok I am stumped and I know its going to be something stupid. So let me explain more in detail. The code above is what I believe should work for pagination from a Laravel controller to a vue component. I get that I am not fully accounting for pagination and I can handle that later but the first results are not available for use when I do this and I do not understand where my syntax is wrong.
Vue:
<ul role="list" class="space-y-4">
<li
v-for="item in allActivities"
:key="item.id"
class="bg-gray-800 px-4 py-6 shadow sm:p-6 sm:rounded-lg"
>
{{ item.description }}
</li>
</ul>
Mounted:
mounted() {
axios
.get("/activity")
.then((response) => (this.allActivities = response.data));
},
Controller
public function index()
{
$activity = Activity::paginate(10);
return $activity;
}
If in the v-if I change it to allActivities.data it refreshes to show the data until I reload the page and get id not found.
If I change the axios to response.data.data it works, but I lose pagination.
IM stuck
response.data is the result from laravel
response.data.data if the data key in the result which is a list of your models
response.data will contain these keys if using
current_page
data
first_page_url
from
last_page
last_page_url
links
next_page_url
path
per_page
prev_page_url
to
total
I did not fully understand the problem. If you want to change page, send the value of the page you want to display to the fetchActivities() method.
EDIT!
<script>
export default {
data() {
return {
allActivities: {
data: [],
total: null
}
}
},
methods: {
async fetchActivities(page = 1){
const {data:activities} = await axios.get(`/activity?page=${page}`)
this.allActivities.data.push(activities.data)
this.allActivities.total = activities.total
}
},
created() {
this.fetchActivities()
}
}
</script>
<template>
<div v-if="allActivities.data.length > 0">
<ul role="list" class="space-y-4">
<li
v-for="(item, index) in allActivities.data"
:key="index"
class="bg-gray-800 px-4 py-6 shadow sm:p-6 sm:rounded-lg"
>
{{ item.description }}
</li>
</ul>
</div>
</template>

Updates the data in vue with laravel without refreshing the page or overlapping the div

I have a problem in sight.
I just started to learn, but I'm confused about something, why when I update the data I send with axios.post and update them, the devil disappears for 2 seconds and refreshes the page.
Look how I thought
<li v-for="question in questions" :key="question.id" class="list-group-item">
{{ question.questiontype }}
<br>
<button v-on:click="addVote(question.id)">Add 1</button>
<br>
<span class="badge badge-primary"><strong>{{ question.votes }}</strong></span>
</li>
data() {
return {
success: false,
questions:[],
percentages:[],
}
},
created() {
this.getQuestions(),
this.getPercentages()
},
methods: {
getQuestions(){
axios.get('/api/questionlist')
.then((response)=>{
this.questions = response.data.question
})
},
getPercentages(){
axios.get('/api/getpercentage')
.then((response)=>{
this.percentages = response.data.percentage
})
},
addVote(id) {
axios.post('api/vote/' + id)
.then((response) => {
this.questions = response.data.question
console.log(response.data)
this.getQuestions()
})
}
So I'm interested in the data I sent with the post.
I would like the page to update without refresh or to overlap the div for 2 seconds.
What exactly am I doing wrong?
I tried a few ways on stackoverflow but they didn't help
If your button is inside a form, you probably want to add type="button" attribute to it or prevent the form submission action.
<button type="button" v-on:click="addVote(question.id)">Add 1</button>
OR:
<button v-on:click.prevent="addVote(question.id)">Add 1</button>
I'm guessing that's probably why you're seeing the page refresh. If you want to display the updated data, you either need to make another axios call to fetch or you need to return the new entry from your API endpoint and push/add it to your list.
So modify your code as follows:
addVote(id) {
axios.post('api/vote/' + id)
.then((response) => this.getQuestions());
}

MVC Partial View Returns Whole Page Instead of Just the Partial

I have the following partial view named "_transactions":
<div id="section-transactions" class="documentsanchor">
</div>
<div>
<div class="row">
<div class="col-lg-12">
<div>
<h4 class="company-headings">#ViewBag.SecSymbol Transactions</h4>
</div>
<div>
</div>
</div>
I render it using
#{Html.RenderAction("Transactions", "Company");}
and this is the Transactions method from the Company controller:
public async Task<PartialViewResult> Transactions()
{
ViewBag.SecSymbol = "test";
return PartialView("_transactions");
}
It's on a page with other partial views.
This works fine. However, I have a button on the page that should get a new partial view and replace the current one. It makes an ajax call as follows
$("#btn_transactions").click(function (e) {
var url = "Company/Transactions";
$.ajax({
url: url,
success: function (result) {
alert(result);
$('#transTarget').html(result);
},
error: function () {
alert("Error occured");
}
});
})
The issue is that the whole page is returned in "result", that is, all partials as well as the layout, when all I want is the transactions partial. What am I doing wrong?
Add this code in partial view
#{
Layout=null;
}
Make sure you have the route set up in your configs -
routes.MapRoute("CompanyTransactions", "company/transactions", new { controller = "Company", action = "Transactions" });

Laravel 5.1 Ajax to get html from Blade View

I have a myitems($filter) method in a ItemsController that loads the myitems.blade view.
The view has list of items as label and text box to get number of items ($items is passed from myitems method to myitems view and there is a model form binding on items model as well)
I have a select box that has options 1. All, 2. Expired and 3.New
When I change the selection I want to have get new $items from the controller and recreate the form with new items list.
I am using using jquery to alert that the selection is changed. but I am not able to figure out how will I be able to call myitems($filter) from ajax and redirect to create the items.blade page.
Route
//Note the ? in parameter, it says parameter is optional
Route::get('/myitems/{filter?}',
['as' => 'myitems.list', 'uses' => 'ItemController#myitems']
);
Controller
...
public function myitems(Request $request, $filter = null)
{
if (empty($filter)) $filter=1;
$items = Item::where('item_type', $filter)->get();
// if ajax call just return the partial that displays the list
if ($request->ajax()) {
return view('_itemlist', compact('items'));
}
// passed as options to input select
$filters= [
'All' => '0',
'New' => '1',
'Expired' => '2'
];
return view('itempagewith_defaultitemlist', compact('items','filters'));
}
...
View
view itempagewith_defaultitemlist.blade.php
<div class="container">
{!! Form::model($myitems, ['route' => 'myitems.list', 'class'=>'form-horizontal', 'files' => true]) !!}
<div id="filterselectbox">
<div class="form-group">
{!!Form::label('filterselectbox','*Filter:',['class'=>'control-label']) !!}
{!!Form::select('filterselectbox', $filters, null, ['class'=>'form-control ']) !!}
</div>
</div>
{!! Form::close() !!}
<div id="item-container">
#include('_itemlist')
</div>
<script>
$('#filterselectbox').change(function() {
var id = $('#filterselectbox').val();
var ajaxurl = '{{route('myitems', ':id')}}';
ajaxurl = ajaxurl.replace(':id', id);
$.ajax({
url: ajaxurl,
type: "GET",
success: function(data){
$data = $(data); // the HTML content that controller has produced
$('#item-container').hide().html($data).fadeIn();
}
});
});
</script>
</div>
partial view _itemlist.blade.php
<ul>
#foreach ($items as $item)
<li>{{ $item->name }}</li>
#endforeach
</ul>

laravel 5 and Ajax get data from database:

I have simple form:
{{ Form::open(array('id' => 'frm')) }}
<div class="form-group">
{!! Form::label('id','id:'); !!}
{!! Form::text('id',null,['class' => 'form-control']); !!}
</div>
<div class="form-group">
{!! Form::submit('Update',['class' => 'btn btn-primary form-control']); !!}
{!! Form::close() !!}
I want to post the values from the form input fields to the controller then in the controller mthod run a query on the database for the id value from the form. Finally, using ajax, show the results of the DB query and if there are no results show a message alerting the user.
I have tried this:
<script>
$("document").ready(function(){
$("#frm").submit(function(e){
e.preventDefault();
var customer = $("input[name=postal]").val();
$.ajax({
type: "POST",
url : "http://laravel.test/ajax",
data : dataString,
dataType : "json",
success : function(data){
}
}, "json");
});
});//end of document ready function
</script>
I have tried a couple of ways to get the post data in the controller but have had no success.
---Problem 1:
There is problem when I try to use this in route:
Route::post('ajax', function() { // callback instead of controller method
$user = App\User::find(\Input::get('id');
return $user; // Eloquent will automatically cast the data to json
});
I get sintax error,on second line for (;)
Also, I try to get data in controller and than print them:
if(Request::ajax()) {
$data = Input::all();
print_r($data);die;
}
ROUTES.PHP
Route::post('/',
['as' => 'first_form', 'uses' => 'TestController#find']);
Route::get('/', 'TestController#index');
Route::post('ajax', function() { // callback instead of controller method
$user = App\User::find(\Input::get('id');
return $user; // Eloquent will automatically cast the data to json
});
Function:
public function ajax()
{
//
// Getting all post data
if(Request::ajax()) {
$data = Input::all();
print_r($data);die;
}
}
I found a couple more ways to send data from view to controller,but even woant show posted data. I check with fire-bug,there is posted value in post request
It appears you're passing your ajax method a variable that doesn't exist. Try passing it the form data directly and see if that yields any results, you can do this with the serialize method:
$("#frm").submit(function(e){
e.preventDefault();
var form = $(this);
$.ajax({
type: "POST",
url : "http://laravel.test/ajax",
data : form.serialize(),
dataType : "json",
success : function(data){
if(data.length > 0) {
console.log(data);
} else {
console.log('Nothing in the DB');
}
}
}, "json");
});
The ajax call has console.log in it now so it will output anything returned to it in the console.
routes.php (an example)
Route::post('ajax', function() { // callback instead of controller method
$user = App\User::find(\Input::get('id'));
return $user; // Eloquent will automatically cast the data to json
});
Please bear in mind I am just putting the code as an example as you didn't put your controller code in the question.
EDIT
I'm going to make a really simple example that works for you. I have made a fresh install of laravel and coded this and it's working fine for me. Please follow along carefully.
app/Http/routes.php
<?php
// route for our form
Route::get('/', function() {
return view('form');
});
// route for our ajax post request
Route::post('ajax', function() {
// grab the id
$id = \Input::get('id');
// return it back to the user in json response
return response()->json([
'id' => 'The id is: ' . $id
]);
});
resources/views/form.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Ajax Example</title>
</head>
<body>
{!! Form::open(['url' => 'ajax', 'id' => 'myform']) !!}
<div class="form-group">
{!! Form::label('id','id:') !!}
{!! Form::text('id', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::submit('Update',['class' => 'btn btn-primary form-control']); !!}
</div>
{!! Form::close() !!}
<div id="response"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$("document").ready(function(){
// variable with references to form and a div where we'll display the response
$form = $('#myform');
$response = $('#response');
$form.submit(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url : $form.attr('action'), // get the form action
data : $form.serialize(), // get the form data serialized
dataType : "json",
success : function(data){
$response.html(data['id']); // on success spit out the data into response div
}
}).fail(function(data){
// on an error show us a warning and write errors to console
var errors = data.responseJSON;
alert('an error occured, check the console (f12)');
console.log(errors);
});
});
});
</script>
</body>
</html>

Resources