What should I do to enable pagination on Vue server-table from Laravel endpoint?
My component:
<template>
<div>
<v-server-table :columns="columns" url="/object/find" :options="options">
</v-server-table>
</div>
</template>
<script>
export default {
data () {
return {
columns: ['name', 'type', 'created_by', 'created_at'],
options: {
perPage: 5,
perPageValues: [5, 10, 15, 25, 50, 100],
pagination: {chunk: 5},
dateColumns: ['created_at'],
dateFormat: 'DD-MM-YYYY HH:mm',
datepickerOptions: {
showDropdowns: true,
autoUpdateInput: true,
}
filterable: ['name', 'type','created_by', 'created_at'],
sortable: ['name', 'type', 'created_by', 'created_at'],
requestAdapter (data) {
return {
sort: data.orderBy ? data.orderBy : 'name',
direction: data.ascending ? 'asc' : 'desc',
limit: data.limit ? data.limit : 5,
page: data.page,
name: data.query.name,
created_by: data.query.created_by,
type: data.query.type,
created_at: data.query.created_at
}
},
responseAdapter ({data}) {
return {
data,
count: data.length
}
},
}
}
},
}
</script>
Controller:
public function findObjects(Request $request)
{
$objects = Objects::withTrashed();
$sort = $request->get('sort');
$direction = $request->get('direction');
$name = $request->get('name');
$created_by = $request->get('created_by');
$type = $request->get('type');
$limit = (int)$request->get('limit');
$page = (int)$request->get('page');
$created_at = $request->get('created_at');
if ($sort !== null && $direction !== null) {
$objects->orderBy($sort, $direction);
}
if ($name !== null) {
$objects->where('name', 'like', '%' . $name . '%');
}
if ($created_by !== null) {
$objects->where('created_by', 'like', '%' . $created_by . '%');
}
if ($type !== null) {
$objects->where('type', 'like', '%' . $type . '%');
}
if ($created_at !== null) {
$date_range = json_decode($created_at);
$objects->whereBetween('created_at', [Carbon::parse($date_range->start), Carbon::parse($date_range->end)]);
}
return $objects->get();
}
All filters work fine. When I use LIMIT or TAKE or PAGINATE it will return 5 items and paginate links don't work in the component.
What should I do in my controller and in my component to display for example 5 items on page?
Please go through the documentaction carefully here
You need to return a JSON object with two properties:
data : array - An array of row objects with identical keys.
count: number - Total count before limit.
For example your JSON should look like this:
[
"data": [
{
"name": "Name1",
"created_at": "01-01-2019 00:00:01,
"updated_at": "02-01-2019 10:12:13",
"pushed_at" : "01-01-2019 00:00:05"
},
{
"name": "Name2",
"created_at": "01-01-2019 00:00:01,
"updated_at": "02-01-2019 10:12:13",
"pushed_at" : "01-01-2019 00:00:05"
},
{
"name": "Name3",
"created_at": "01-01-2019 00:00:01,
"updated_at": "02-01-2019 10:12:13",
"pushed_at" : "01-01-2019 00:00:05"
}
],
"count":100
]
In your controller you are not returning total row count for vue-table-2 pagination. Add count in your response will solve your issue
Change you controller code with following code:
public function findObjects(Request $request)
{
$objects = Objects::withTrashed();
$sort = $request->get('sort');
$direction = $request->get('direction');
$name = $request->get('name');
$created_by = $request->get('created_by');
$type = $request->get('type');
$limit = (int)$request->get('limit');
$page = (int)$request->get('page');
$created_at = $request->get('created_at');
if ($sort !== null && $direction !== null) {
$objects->orderBy($sort, $direction);
}
if ($name !== null) {
$objects->where('name', 'like', '%' . $name . '%');
}
if ($created_by !== null) {
$objects->where('created_by', 'like', '%' . $created_by . '%');
}
if ($type !== null) {
$objects->where('type', 'like', '%' . $type . '%');
}
if ($created_at !== null) {
$date_range = json_decode($created_at);
$objects->whereBetween('created_at', [Carbon::parse($date_range->start), Carbon::parse($date_range->end)]);
}
$count = $objects->count();
$objects->offset($limit * ($page - 1))->limit($limit);
$data = $objects->get()->toArray();
return response()->json([
'data' => $data,
'count' => $count
]);
}
And Change Your vuejs code like this
<template>
<div>
<v-server-table :columns="columns" url="/object/find" :options="options">
</v-server-table>
</div>
</template>
<script>
export default {
data () {
return {
columns: ['name', 'type', 'created_by', 'created_at'],
options: {
perPage: 5,
perPageValues: [5, 10, 15, 25, 50, 100],
pagination: {chunk: 5},
dateColumns: ['created_at'],
dateFormat: 'DD-MM-YYYY HH:mm',
datepickerOptions: {
showDropdowns: true,
autoUpdateInput: true,
}
filterable: ['name', 'type','created_by', 'created_at'],
sortable: ['name', 'type', 'created_by', 'created_at'],
requestAdapter (data) {
return {
sort: data.orderBy ? data.orderBy : 'name',
direction: data.ascending ? 'asc' : 'desc',
limit: data.limit ? data.limit : 5,
page: data.page,
name: data.query.name,
created_by: data.query.created_by,
type: data.query.type,
created_at: data.query.created_at
}
}
}
}
},
}
</script>
In order to enable pagination you need to get it done in the SQL statement. If you are using SQL server use OFFSET/FETCH. If you using MYSQL use LIMIT/OFFSET. Use this link as reference:
What is the best way to paginate results in SQL Server
Related
I am struggling with a problem using axios.
Vue file:
<script>
export default {
name: 'npcs-list',
data () {
return {
data: '',
index: '',
dialogues: '',
input: {
npc_name: '',
},
npc_id: '',
npc_name: '',
npc_start_dialogues:'',
dialogues: [],
fields: [{
name: 'id',
callback: 'stringToInt'
},
{
name: 'name'
},
{
name: 'start_dialog'
},
{
name: 'actions', // <----
title: 'Akcje',
titleClass: 'center aligned',
dataClass: 'center aligned'
}
],
css: {
pagination: {
wrapperClass: 'pagination pull-right',
activeClass: 'btn-primary',
disabledClass: 'disabled',
pageClass: 'btn btn-border',
linkClass: 'btn btn-border',
icons: {
first: '',
prev: '',
next: '',
last: ''
}
}
}
}
},
components: {
Vuetable,
VuetablePagination,
VuetablePaginationInfo
},
methods: {
insertNPC () {
const data = this
if (this.input.npc_name != '' && this.npc_start_dialogues != '') {
axios.post('http://localhost/test/Quests/endpoints/insert.npc.php', {
npc_name: 'dupa',
npc_startdialog: 'dupa2'
})
.then((response) => {
data.status = response.data
})
.catch(function (error) {
console.log(error)
})
if (data.status == '1') {
alert('Działa!')
} else {
alert('Taki tag już istnieje!')
}
} else {
alert('Brak wystarczającej ilości danych')
}
},
showModal(data) {
this.$refs.myModalRef.show()
this.data = data,
this.npc_id = data.id,
this.npc_name = data.name,
this.npc_start_dialogues = data.start_dialog.split(";")
},
hideModal () {
this.$refs.myModalRef.hide()
},
onHidden (evt){
this.npc_id = '',
this.npc_name = '',
this.npc_start_dialogues = ''
},
log (data) {
console.log(data)
},
editDialogue (data) {
this.$router.push({
name: 'editDialogues',
params: {
id: data
}
})
},
editOption (data) {
this.$router.push({
name: 'editOptions',
params: {
id: data
}
})
},
}
</script>
PHP endpoint:
<?php
header('Content-Type: text/html');
include_once '../Checkers/CheckIfNPCExists.php';
include_once '../Inserts/InsertNPC.php';
$requestBody = file_get_contents('php://input');
$data = json_decode($requestBody);
$status = new CheckIfNPCExists();
var_dump($data);
$result = $status->uniqueTest($data->npc_name);
if($result == '0'){
$npc_class = new InsertNPC();
$npc_result = $npc_class->createNew($data->npc_name,$data->npc_startdialog);
echo $npc_result;
}
$result is giving me an error about getting non-object property of 'npc_name'.
var_dump of $data shows in Chrome Preview:
object(stdClass)[1]
public 'npc_name'
but in Response slightly more (xdebug log):
<pre class='xdebug-var-dump' dir='ltr'>
<small>C:\xampp\htdocs\test\Quests\endpoints\insert.npc.php:12:</small>
<b>object</b>(<i>stdClass</i>)[<i>1</i>]
<i>public</i> 'npc_name' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'dupa'</font> <i>(length=4)</i>
<i>public</i> 'npc_startdialog' <font color='#888a85'>=></font> <small>string</small> <font color='#cc0000'>'dupa2'</font> <i>(length=5)</i>
</pre>
I would appreciate any help, any tips are welcome as well. The text limit is so unhandy.
I have this boolean data of 1 = 'Active' and 0 = 'Inactive'.
I successfully rendered it to the datatable, but the problem if I trying to search 'Active' or 'Inactive' it shows No matching records found.
Is there any solution for this problem?
Here is my datatable js code
columns: [
{ data: 'photo', name: 'photo' },
{ data: 'full_name', name: 'full_name' },
{ data: 'm_lname', name: 'm_lname'},
{ data: 'm_fname', name: 'm_fname'},
{ data: 'm_mname', name: 'm_mname'},
{ data: 'm_gender', name: 'm_gender' },
{ data: 'm_datebaptized', name: 'm_datebaptized' },
{ data: 'm_isactive', name: 'm_isactive',
render: function ( data, type, full, meta ) {
return data ? "Active" : "Inactive" ;
}
},
{ data: 'action', name: 'action' },
],columnDefs: [
{ targets: [2,3,4], visible: false},
{ targets: '_all', visible: true },
{ searchable: true, targets: '_all'},
{ searchable: false, targets: [0,8]},
{ orderData: 2, targets: 1 },
],
Thank you.
try to move mapping to
return datatables()->of(User::all()->map(function ($item) {
$item->m_isactive = $item->m_isactive ? 'Active' : 'Inactive';
return $item;
})->toJson();
and delete
render: function ( data, type, full, meta ) {
return data ? "Active" : "Inactive" ;
}
I got problem with connecting bootstrap year calendar from bootstrap-year-calendar.com with my mysql base.
I make getEvents.php file, which is connecting with base and taking data of events. When I printing result from this file then all is ok and i see my events, but when I trying to include this result to DataSource in calendar script then I dont see any events.
Someone could send some examples how to do it?
My codes:
getEvents.php
<?php
require "bdd.php";
$result = $bdd->prepare("SELECT `id`, `title`, `start`, `end`, `color`, `dsc`, `zlec`, `stanowisko` FROM `events`");
$result->execute();
$event_array = array();
$result->setFetchMode(PDO::FETCH_ASSOC);
while ($record = $result->fetch()) {
$event_array[] = array(
'id' => $record['event_id'],
'title' => $record['event_name'],
'start' => $record['start_event'],
'end' => $record['end_event'],
);
}
echo json_encode($event_array);
?>
calendar script I change to
dataSource: ['getEvents.php']
ACTUALIZATION
#JeffHuijsmans Im not sure how to fix it.
Please tell me how to fetch into dataSource function result from my getEvents.php file ?
echo from getEvents file return
[{"event_id":"1","event_title":"XXX","event_start":"2017-10-04","event_end":"2017-10-06"}]
Default data in dataSource is looking like this:
dataSource: [
{
id: 0,
name: 'Google I/O',
location: 'San Francisco, CA',
startDate: new Date(currentYear, 4, 28),
endDate: new Date(currentYear, 4, 29)
}]
A "workaround" is iterate the data array and generate a string with data in calendar format.
Here works fine, hope helps.
Sample:
private function convertYearData(array $yearData) : string
{
if (empty($yearData)) {
return 'null';
}
$data = '';
foreach ($yearData as $event) {
if (empty($data)) {
$data = "[{id:{$event['id']}, name:'{$event['name']}', type:'{$event['type']}', startDate: new Date('{$event['startDate']}'), endDate: new Date('{$event['endDate']}')}";
} else {
$data .= ", {id:{$event['id']}, name:'{$event['name']}', type:'{$event['type']}', startDate: new Date('{$event['startDate']}'), endDate: new Date('{$event['endDate']}')}";
}
}
$data .= ']';
return $data;
}
$yearDataArr = [
[
'id' => '1',
'name' => 'Pesquisa Teste',
'type' => 'Pesquisa',
'color' => '#4da539',
'startDate' => '2017-04-28 02:00:00',
'endDate' => '2017-04-30 12:00:00',
],
[
'id' => '2',
'name' => 'Media Teste',
'type' => 'Media',
'color' => '#00afe8',
'startDate' => '2017-04-25 02:00:00',
'endDate' => '2017-05-12 12:00:00',
],
[
'id' => '3',
'name' => 'Email Marketing Teste',
'type' => 'Email Marketing',
'color' => '#af2828',
'startDate' => '2017-03-25 02:00:00',
'endDate' => '2017-05-17 12:00:00',
],
];
$yearData = $this->convertYearData($yearDataArr);
after, in your html just echo your var $yearDate:
$('#calendar').calendar({
language:'pt',
enableContextMenu: false,
enableRangeSelection: true,
selectRange: function(e) {
editEvent({ startDate: e.startDate, endDate: e.endDate });
},
mouseOnDay: function(e) {
if(e.events.length > 0) {
var content = '';
for(var i in e.events) {
content += '<div class="event-tooltip-content">'
+ '<div class="event-name" style="color:' + e.events[i].color + '">' + e.events[i].type + '</div>'
+ '<div class="event-type">' + e.events[i].name + '</div>'
+ '</div>';
}
$(e.element).popover({
trigger: 'manual',
container: 'body',
html:true,
content: content
});
$(e.element).popover('show');
}
},
mouseOutDay: function(e) {
if(e.events.length > 0) {
$(e.element).popover('hide');
}
},
dayContextMenu: function(e) {
$(e.element).popover('hide');
},
dataSource: <?php echo $this->yearData; ?>
});
I created a Datagrid with jTable, here is my JavaScript code in twig:
<script type="text/javascript">
$(document).ready(function () {
jQuery('#grid').jtable({
title: 'Table of product',
paging: true,
pageSize: 2,
sorting: true,
defaultSorting: 'Name ASC',
actions: {
listAction: '{{path("_db_show")}}',
createAction: '{{path("_serverproc")}}?action=create',
updateAction: '{{path("_serverproc")}}?action=update',
deleteAction: '{{path("_serverproc")}}?action=delete'
},
fields: {
id: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '40%'
},
Price: {
title: 'Price',
width: '20%'
},
Description: {
title: 'Description',
width: '30%',
}
}
});
//Load person list from server
$('#grid').jtable('load');
});
</script>
And the following is the php code in controller:
/**
* #Route("/show", name="_db_show")
* #Template()
*/
public function showAction()
{
$product = array({'id' => 1, 'Name' => "test",'Price' => "200",'Description' => "ok"});
$jTableResult = array();
$jTableResult['Result'] = "OK";
$jTableResult['Records'] = $product;
$JsonResponse = new JsonResponse($jTableResult);
return $JsonResponse;
}
The result I got is:
{"Result":"OK","Records":{"id":1,"Name":"test","Price":"200","Description":"ok"}}
Could someone kindly tell me what should I do to use jTable with Symfony? A working example will be great. Thank you very much.
try with:
$product = array('id' => 1, 'Name' => "test",'Price' => "200",'Description' => "ok");
without {} in array definition;
I have this grid
$("#email-grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "operations/get_emails_sales_reps.php?salesRepsId=" + salesRepsId,
type: "GET"
},
update: {
url: "operations/edit_email.php?salesRepsId=" + salesRepsId,
type: "POST",
complete: function (e) {
$("#email-grid").data("kendoGrid").dataSource.read();
}
},
destroy: {
url: "operations/delete_email.php",
type: "POST",
complete: function (e) {
$("#email-grid").data("kendoGrid").dataSource.read();
}
},
create: {
url: "operations/add_email.php?salesRepsId=" + salesRepsId,
type: "POST",
complete: function (e) {
$("#email-grid").data("kendoGrid").dataSource.read();
}
},
},
schema: {
data: "data",
total: "data.length", //total amount of records
model: {
id: "SalesRepId",
fields: {
EmailType: {
defaultValue: {
EmailTypeId: 2,
EmailTypeName: "Home"
}
},
EmailText: {
type: "string"
},
IsMainEmail: {
type: "boolean"
}
}
}
},
pageSize: 5,
},
height: 250,
filterable: true,
sortable: true,
pageable: true,
reorderable: false,
groupable: false,
batch: true,
navigatable: true,
toolbar: ["create", "save", "cancel"],
editable: true,
columns: [{
field: "EmailType",
title: "Type",
editor: EmailTypeDropDownEditor,
template: "#=EmailType.EmailTypeName#"
}, {
field: "EmailText",
title: "Email",
}, {
field: "IsMainEmail",
title: "Main?",
width: 65,
template: function (e) {
if (e.IsMainEmail == true) {
return '<img align="center" src ="images/check-icon.png" />';
} else {
return '';
}
}
// hidden: true
}, {
command: "destroy",
title: " ",
width: 90
},
]
});
the code in the server side (get_emails_sales_reps.php)
<?php
require_once ("../lib/salesrep.php");
require_once ("../lib/helper.php");
// add the header line to specify that the content type is JSON
header("Content-type: application/json");
$options = array();
$result = SalesRep::getRepEmails($_GET["salesRepsId"]);
if (isset($result) && $result != null) {
$result = _object_to_array($result);
if (isset($result[0]) && is_array($result)) {
for ($i = 0; $i < count($result); $i++) {
$result[$i]["EmailType"] = array("EmailTypeName" => $result[$i]["EmailType"], "EmailTypeId" => $result[$i]["EmailTypeId"]);
}
} else {
$result["EmailType"] = array("EmailTypeName" => $result["EmailType"], "EmailTypeId" => $result["EmailTypeId"]);
}
if (isset($result) || $result != null) {
echo "{\"data\":" . json_encode($result) . "}";
} else {
echo "{\"data\": {} }";
}
}
?>
when the grid has one record or more, I can add new record without any errors, but when there are no records the grid and try to add a new record. I get this error
Uncaught TypeError: Cannot read property 'length' of undefined
please, how can I fix this ??
I've solved this issue by editing the php file. when result is null ( empty) I have to return an empty json array like this
else {
// the result is null
echo "{\"data\": [] }";
}