PHP Datables not showing any rows - Server side - javascript

I am having trouble getting Datables to work.
No-matter what I try, I am getting the issue that there is no data.
The message exactly is: "No matching records found".
I am using the correct format found here on the official website but it doesn't seem to want to load.
I am not using MYSQL so haven't include any SPP, but am just returning the array of address's inside an array then encoding it in JSON.
In my frontend file, I am trying to load all address's from a certain router:
<script type="text/javascript">
$(document).ready(function() {
$('#table').DataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "<?=url('database/addresses');?>",
"dataSrc": "",
},
'columnDefs': [{
'targets': 1,
'checkboxes': {
'selectRow': true
}
}],
'select': {
'style': 'multi',
'selector': 'td:first-child'
},
'order': [[5, 'desc']],
"columns": [
{ "data": "id" },
{ "data": "id" },
{ "data": "input_address" },
{ "data": "destination_address" },
{ "data": "callback_url" },
{ "data": "dateCreated.date" },
{ "data": "id" }
],
'colReorder': true
});
} );
</script>
My html table:
<form method="post" id="deleteMulti" class="ajax-multi" action="<?=url('XhPCrvFtQuE7gPP6/addresses/delete/selected');?>">
<?= csrf() ?>
<div class="row">
<div class="col-xxl-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Addresses [ <?=$count;?> ]</h4>
<div class="right fr">
<button class="btn tooltip" style="display: inline;" name="deleteSelected" title="Delete Selected Addresses"><i class="fa fa-trash" style="color: black;"></i></button>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="table" class="display">
<thead>
<tr>
<th>#</th>
<th><input type="checkbox" class="" id="checkAl"></th>
<th>Input Address</th>
<th>Output Address</th>
<th>Callback Url</th>
<th>Created</th>
<th><i class="bi bi-archive-fill"></i></th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
**And in my database/addresses to load the database content:**
// This is used for when we need to load more address's to the admins /addresses page
public function getAddresses() {
define('PAGE_NAME', 'Admin Addresses');
// Skip 100 as we will start from the 100th row
// We set the limit to 100 in Admin page so the page loads 100 much faster
// We will push more and more using this function inside here for when they click load more
$addresses = \r\table('addresses')->orderBy(array('index' => \r\desc('dateCreated')))->skip(100)->limit(100)->run($this->conn);
$addresses = $addresses->toArray();
$count = count($addresses);
$theArr = array();
foreach ($addresses as $address) {
$theArr[] = $address;
}
$final = array(
'draw' => 1,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => array_values($theArr)
);
if($count > 0) {
echo json_encode($final, JSON_FORCE_OBJECT);
} else {
return false;
}
}
My issue is that it keeps showing me:
No matching records found eventhough I do have over 4k records in there.
Take a look at this picture here
Take a look at the format of the json returned from my getAddresses():
here

Related

How to append a select dropdown to a HTML DataTable?

I have created a website mainly using HTML, CSS, PHP and MYSQL and I added a select dropdown with roles for to users to choose from. I need it to be on every row of users in the table. I have successfully gotten tabledit working on the site, but I am not sure how to append this dropdown to the Roles column.
This is how the HTML is set up
<body>
<div class="panel panel-default">
<!-- <div class="panel-heading">Sample Data</div>-->
<div class="panel-body">
<div class="table-responsive">
<table id="sample_data" class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Approval</th>
<th>Roles</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<!--SELECT DROPDOWN LIST-->
<select id="test">
<?php
for ($a = 1; $a <= $count ; $a++){
?>
<option value="1"><?php echo($roles[($a-1)]);?></option>
<?php
}
?>
</select>
<!--//////////////-->
</body>
<script>
$(document).ready(function(){
var dataTable = $('#sample_data').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"ajax" : {
url:"FetchUserTable.php",
type:"POST"
}
});
$('#sample_data').on('draw.dt', function(){
$('#sample_data').Tabledit({
url:'ActionUserTable.php',
dataType:'json',
columns:{
identifier : [0, 'user_id'],
editable:[
[1, 'first_name'],
[2, 'last_name'],
[3, 'email'],
[4, 'admin_approved', '{"1":"Approved","2":"Disapproved"}']
// [5, 'role_id']
]
},
restoreButton:false,
onSuccess:function(data, textStatus, jqXHR)
{
if(data.action == 'delete')
{
$('#' + data.id).remove();
$('#sample_data').DataTable().ajax.reload();
}
}
});
});
});
You can use the render option on the column definitions to render what ever you want. In the render function you have access to the row and the entire data object.
$(function() {
let $tbl = $('#sample_data'), $select = $('#select-box')
let data = [
[
"Tiger Nixon",
"System Architect",
"Edinburgh",
"5421",
"2011/04/25",
"$3,120"
],
[
"Garrett Winters",
"Director",
"Edinburgh",
"8422",
"2011/07/25",
"$5,300"
]
]
$tbl.DataTable({
data: data,
columns: [
null, null, null, null, {
render: function(data, type, row, meta) {
return $select.html() + `Use this to select "${data}"`
}
},
{
render: function(data, type, row, meta) {
return $select.html() + `Use this to select "${data}"`
}
},
]
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.22/datatables.min.css" />
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.22/datatables.min.js"></script>
<body>
<div class="panel panel-default">
<!-- <div class="panel-heading">Sample Data</div>-->
<div class="panel-body">
<div class="table-responsive">
<table id="sample_data" class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Approval</th>
<th>Roles</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div style="display:none;" id="select-box">
<select>
<option>Role 1</option>
</select>
</div>
</body>
its not a proper solution but it will resolve your issue. First select your roles html
var emelnt = $('#test');
//now append to table td
$('table tbody td:nth-child(6)').html(emelnt);
//you can also use a function to first get role id from table each row then create your select here in js and the append it to html so then your roles drop down will be selected.
I'm not sure if you are using DataTable or Tabledit, you seem to be mixing them for some reason. I'm not sure if this is a good idea to start with. I suggest picking one over the other. This answer focuses on Tabledit.
Since the table is essentially created and managed by Tabledit you should provide the data there. You currently already use a select for admin approval:
[4, 'admin_approved', '{"1":"Approved","2":"Disapproved"}']
Your role select can be created in a similar manner. Since the structure of $roles is not shared I will assume that it is an array with string values. First create a variable roles within your <script> tags.
const roles = <?php echo json_encode($roles); ?>;
Then add the column to the columns.editable setting:
[4, 'admin_approved', '{"1":"Approved","2":"Disapproved"}'],
[5, 'role', JSON.stringify(roles)]
You might have to convert the structure of $roles to create the correct JSON output. Here are some example results:
Example #1
// assumed <?php echo json_encode($roles); ?> output
const roles = ["role A", "role B"];
Creates:
<option value="0">role A</option>
<option value="1">role B</option>
Example #2
// assumed <?php echo json_encode($roles); ?> output
const roles = {"role_a": "role A", "role_b": "role B"};
Creates:
<option value="role_a">role A</option>
<option value="role_b">role B</option>
Take a look at how to add a row in datatables.net...
var t = $('#example').DataTable();
t.row.add( [
counter +'.1',
counter +'.2',
counter +'.3',
counter +'.4',
counter +'.5'
] ).draw( false );
So, in your case, within onSuccess:function(data, textStatus, jqXHR), we should just be able to change this, $('#sample_data').DataTable().ajax.reload();, to....
var t = $('#sample_data').DataTable();
t.row.add([
$('#test').html()
]).draw(false);
t.ajax.reload();
This is basically doing what your code was doing before, but now you're also calling the .row.add() on the DataTable().

Adding delete button to bootstrapTable in MVC

I have a .Net MVC project that fills a table with data using a bootstrapTable from bootstrap v3. I want to add a delete button to each row.
The bootstrapTable takes json data and loads it. The json is built like this:
public virtual JsonResult Search(FormCollection searchArgument)
{
IEnumerable<MyData> myListData = GetMyListData(searchArgument);
var jsonResult = Json(myListData, JsonRequestBehavior.AllowGet);
return jsonResult;
}
So the jsonResult is just a list of all of my MyData. My view that shows the result looks like this:
#model MyNamespace.Web.Models.MyListViewModel
<div class="col-md-12">
#{
ViewBag.Title = "Index";
Layout = MVC.Shared.Views._Layout;
<div class="row">
<div class="col-md-12">
<form role="form" id="formsearch">
<input id="fromsearch" name="fromsearch" type="hidden" value="true" />
<div class="form-group">
#Html.LabelFor(m => m.Status, "Status:")<br />
#Html.DropDownList("status", new SelectList(Model.Status, "Value", "Key", Model.SelectedStatus), new { #class = "selectButton" })
</div>
<input type="button" id="btnsearch" value="Search" />
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
</tr>
</thead>
</table>
</div>
</div>
}
</div>
<script>
$("#btnsearch").click(function () {
$('#table').bootstrapTable('showLoading');
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Search, MVC.MyController.Name)",
data: $('#formsearch').serialize(),
dataType: "json",
success: function (data) {
$('#table').bootstrapTable('hideLoading');
$('#table').bootstrapTable({
data: data,
striped: true,
pagination: true,
pageSize: 25,
pageList: [10, 25, 50, 100, 200],
search: false
});
$('#table').bootstrapTable('load', data).on('click-row.bs.table', function (e, row, $element) {
Showdetail(JSON.stringify(row));
});
},
error: function (err) {
console.log(err)
}
});
});
function Showdetail(jsonrow) {
var obj = JSON.parse(jsonrow);
window.location = "#Url.Action(MVC.MyController.ActionNames.ShowMyData, MVC.MyData.Name)?myDataId=" + obj.Id;
}
</script>
#section AddToHead
{
#Styles.Render("~/bundles/bootstrap-table/css")
}
#section scripts
{
#Scripts.Render("~/bundles/bootstrap-table")
}
So the javascript function ("#btnsearch").click gets the json data from public virtual JsonResult Search and sends that to bootstrapTable which loads the data in the table. What I want to do is to add a new header in my table, like this:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th></th>
</tr>
</thead>
</table>
And then in the last column add a delete button that has the id of that row (#Model.Id for instance) so that I can call the controller to delete the row from the database and then reload the table so that the row also disappears from the GUI.
I could easily do it with an ActionLink but since I don't loop through all objects and then draw them out on the page, I can't just add an ActionLink to the page. All the rendering of the rows is done in the bootstrapTable.
I looked at this question and answer and it seemed promising but it's not quite what I'm doing and I can't get my head around what I would need to do to get it working for me: Bootstrap table - dynamic button in row.
According to documantation and examples here:
https://live.bootstrap-table.com/example/column-options/events.html
Add to your scripts:
<script>
var $table = $('#table')
function operateFormatter(value, row, index) {
return [
'<a class="remove" href="javascript:void(0)" title="Remove">',
'<i class="fa fa-trash"></i> Delete',
'</a>'
].join('')
}
window.operateEvents = {
'click .remove': function (e, value, row, index) {
//edit here for ajax request to delete row.id record
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Delete,MVC.MyController.Name)",
data: {id:row.id},
dataType: "json",
success: function (data) {
//when success remove row
$table.bootstrapTable('remove', {
field: 'id',
values: [row.id]
})
},
error: function (err) {
console.log(err)
}
});
}
}
</script>
and edit your html table:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th data-field="operate" data-formatter="operateFormatter" data-events="operateEvents">Actions</th> <!--add this col-->
</tr>
</thead>
</table>

My Ajax request only sent once

I have an ajax request for getting the purchased list of a user. I thought it was perfectly working because it returns the data that I need. But when I click the other user it seems the ajax request only send a request once. Becuase the data is the same, and when I look at the network tool of chrome, there is no another request was send.
This is my current Ajax request.
var purchased_list;
// $('#student_profile_purchased_item_list_tab').click(function(){
function createTablePurchasedList(id){
console.log("Start, student:"+id);
purchased_list= $('#purchased_item_list_table').DataTable({
// "processing": true,
// "paging": false,
// "ordering": true,
"ajax": {
url:'{{ route("student_item_list") }}?student_id='+id,
cache: true,
dataSrc: "",
},
columnDefs: [
{
className: "dt-center",
targets: [0],
},
],
"columns": [
{
data: "date_purchased"
},
{
data: "product_status_id",
render: function(data, type, row){
switch(data){
case 2:
return 'Purchased';
case 3:
return '<p style="color:red;">Consumed</p>';
case 6:
return '<p style="color:green;">Transferred</p>';
}
}
},
{
data: "name",
render: function(data, type, row){
return data;
}
},
]
});
console.log("End, student:"+id);
}
// });
Tab
<li>Purchased Item List</li>
Datatable
<div class="tab-pane fade in" id="student_profile_purchased_item_list">
<div style="position:relative;">
<div class="other_content_header">
Item List
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table width="100%" class="responsive table table-striped table-bordered table-hover purchase-item-table" id="purchased_item_list_table" style="font-size:12px; text-align:center;">
<thead>
<tr>
<th>Date</th>
<th>Item Status</th>
<th>Product Name</th>
{{-- <th>Quantity</th> --}}
{{-- <th> </th> --}}
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
every time I click a user the console.log result changes, At first I thought the ID is not changing when I click another user. But when I do the console log the result changes.
Hope someone can help me solve my problem.

How to access additional data in JSON requested by Dynatable AJAX call

I am using the dynatable.com plugin to create a table of of schools that are stored in our database. The table can be filtered so does not always show the total number of schools. We do not display a 'number of pupils' column but are trying to show a 'total number of pupils' summary at the bottom of the table.
html on the page is as follows:
<table id="dynatable">
<thead>
<tr>
<th data-dynatable-column="id">ID</th>
<th data-dynatable-column="schoolName">School Name</th>
<th data-dynatable-column="contactName">Contact Name</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="3"><span id="numPupils"></span> Pupils</td>
</tr>
</tfoot>
</table>
Followed by the JS:
<script>
$('#dynatable').dynatable({
dataset: {
ajax: true,
ajaxUrl: '/my/json/page.json',
ajaxOnLoad: true,
records: []
}
});
</script>
And a sample of the JSON retrieved (note the additional totalNumPupils field at the bottom):
{
"records": [
{
"id": "1",
"schoolName": "ABC School",
"contactName": "Terry"
},
{
"id": "17",
"schoolName": "DEF School",
"contactName": "Claire"
},
{
"id": "45",
"schoolName": "GHI School",
"contactName": "Barry"
}
],
"queryRecordCount": 3,
"totalRecordCount": 450,
"totalNumPupils": 794
}
I am trying to establish if there is a way to access the responseJSON.totalNumPupils that is requested by dynatable's ajax call or whether I would have to perform my own ajax call, ascertain the number of pupils, then pass in the JSON to the dynatable function afterwards?
Please see the code snippet. You can use normal AJAX to get the JSON payload, then populate the dynatable with the data from the AJAX response, while simultaneously accessing the unique totalNumPupils property.
$('#dynatable').dynatable({
dataset: {
ajax: true,
ajaxUrl: 'https://api.myjson.com/bins/1ezw8l',
ajaxOnLoad: true,
records: []
}
});
$.ajax({
url: 'https://api.myjson.com/bins/1ezw8l',
success: function(data) {
$('#dynatable').dynatable({
dataset: {
ajax: false,
records: data
}
});
$('#numPupils').text("Total Pupils: " + data.totalNumPupils);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Dynatable/0.3.1/jquery.dynatable.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/Dynatable/0.3.1/jquery.dynatable.css" rel="stylesheet" />
<table id="dynatable">
<thead>
<tr>
<th data-dynatable-column="id">ID</th>
<th data-dynatable-column="schoolName">School Name</th>
<th data-dynatable-column="contactName">Contact Name</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="3"><span id="numPupils"></span> Pupils</td>
</tr>
</tfoot>
</table>

How to change Ajax generated HTML-Content

Hi I have Problems to change HTML content, which is generated by AJAX
This is the code of the page:
#model IEnumerable<WE_SRW_PeerNissen.Models.Reservations>
#{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Übersicht Liste</h2>
<form method="post" action="List">
<div class="input-group">
<div class="input-group-btn">
<input type="text" class="form-control" name="searchbar" placeholder="Search">
<button class="btn btn-default" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
</form>
<table class="table" id="sorttable">
<thead bgcolor="white">
<tr>
<th>
#Html.DisplayNameFor(model => model.BookingNr)
</th>
<th>
#Html.DisplayNameFor(model => model.Arrival)
</th>
<th>
#Html.DisplayNameFor(model => model.Departure)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Appartment)
</th>
<th>
#Html.DisplayNameFor(model => model.Adult)
</th>
<th>
#Html.DisplayNameFor(model => model.Children)
</th>
<th>
#Html.DisplayNameFor(model => model.Total)
</th>
</tr>
</thead>
</table>
<link href="~/Content/DataTables/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="~/Scripts/DataTables/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#sorttable').DataTable({
"ajax": {
"url": "/OverView/loaddata",
"type": "GET",
"datatype": "json"
},
"columns": [
{ "data": "BookingNr", "autoWidth": true },
{ "data": "Arrival", "autoWidth": true },
{ "data": "Departure", "autoWidth": true },
{ "data": "Name", "autoWidth": true },
{ "data": "Appartment", "autoWidth": true },
{ "data": "Adult", "autoWidth": true },
{ "data": "Children", "autoWidth": true },
{ "data": "Total", "autoWidth": true },
]
});
});
</script>
An example what is generated:
<div class="dataTables_filter" id="sorttable_filter">
<label>Search:
<input aria-controls="sorttable" type="search" placeholder="">
</label>
</div>
And I think that was my best try:
<script>
$(document).ready(function () {
$(document).on(function () {
$('#sorttable_filter label:eq(1)').text('Suchen:');
});
});
</script>
which I set below the AJAX script, I also tried to put it in the same script-Tag below to make sure, that AJAX is Executed
A few comments...
jQuery on() method binds function to the specific event, like: $(something).on("click", doSomething) and you provide there only a function, thus it does not know what event to bind your function to.
Then, eq(1) is jQuery method, but not a CSS selector, thus you'd like to use "label:first-child" (if you need the first one). It will, however, destroy input field in your example HTML, due to it is inside a label element, so you (probably) would like to have it outside. In the case when you're unable to change that HTML output you can use a dirty hack of "moving" input copy outside of label element... like this
$(document).ready(function() {
var labelEl = document.querySelector("#sorttable_filter label:first-child");
var inputEl = labelEl.querySelector("input");
labelEl.parentNode.appendChild(inputEl);
labelEl.innerText = 'Suchen:';
});
What I don't like is the fact that document.ready() might happen a while before actual element appears, so you'd like to look for result HTML appearance at least...

Categories