I am doing a server-side pagination
this is my script,
$(document).ready(function() {
$('#dataTable').DataTable( {
'pagingType': 'full_numbers',
'paging' : true,
'responsive': true,
'processing': true,
'serverSide': true,
'serverMethod': 'post',
ajax: {
url: "<?php echo $this->Url->build(['action' => 'tableview']); ?>"
},
columns: [
{ data: "id" },
{ data: "product_name" },
{ data: "unit" },
{ data: "price" },
{ data: "expiry_date" },
{ data: "stock"}
]
} );
});
and here is the query for the retrieval of data from the MySQL db and converting them into JSON
## Read value
$requestData = $this->request->getData();
$row = $requestData['start'];
$rowperpage = $requestData['length'];
$columnIndex = $requestData['order'][0]['column']; // Column index
$columnName = $requestData['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $requestData['order'][0]['dir']; // asc or desc
$searchValue = mysqli_real_escape_string($con,$_POST['search']['value']); // Search value
## Search
$searchQuery = "";
if($searchValue != ''){
$searchQuery = " and (product_name like '%".$searchValue."%' or
id like '%".$searchValue."%' or
expiry_date like'%".$searchValue."%' ) ";
}
## Total number of records without filtering
$sel = mysqli_query($con,"select count(*) as allcount from products");
$records = mysqli_fetch_assoc($sel);
$totalRecords = $records['allcount'];
## Total number of record with filtering
$sel = mysqli_query($con,"select count(*) as allcount from products WHERE 1 ".$searchQuery);
$records = mysqli_fetch_assoc($sel);
$totalRecordwithFilter = $records['allcount'];
## Fetch records
$empQuery = "select * from products WHERE 1 ".$searchQuery." order by ".$columnName." ".$columnSortOrder." limit ".$row.",".$rowperpage;
$empRecords = mysqli_query($con, $empQuery);
$data = array();
while ($row = mysqli_fetch_assoc($empRecords)) {
$nested[] = array(
"id"=>$row['id'],
"product_name"=>$row['product_name'],
"unit"=>$row['unit'],
"price"=>$row['price'],
"expiry_date"=>$row['expiry_date'],
"stock"=>$row['stock']
);
}
$data = $nested;
## Response
$response = array(
"draw" => ($requestData['draw']),
"TotalRecords" => intval($totalRecords),
"TotalDisplayRecords" => intval($totalRecordwithFilter),
"Data" => $data
);
echo json_encode($response);
I am having a result of a JSON but it has a null string/value at the end making my JSON not valid.
ive tried removing the null and it makes the JSON valid. I want to know what causes the null or how can I remove it
Related
I am trying to insert data from database into an array, using while loop, here is my database:
id resulst
152556 0
152555 1
152553 1
152552 0
152551 1
152550 0
152549 1
Here is the code that I did:
$output = [
"online" => 0,
"success" => 0,
"servers" => []
];
$mini_result = $db->query("SELECT * FROM `sessions` WHERE status = '1' LIMIT 5");
while( $result = $mini_result->fetch()){
$output['servers']['mini_result'] = [
$result['id'] => $result['result']
];
}
$output["online"] = 1;
$output["success"] = 1;
echo json_encode($output, JSON_PRETTY_PRINT );
Output:
{
online: 1,
success: 1,
servers: {
mini_result: {
152556: "0"
}
}
}
It only prints 1 element, not 5 as I would like. This is the output I want:
{
online: 1,
success: 1,
servers: {
mini_result: {
152556: "0",
152555: "1",
152553: "1",
152552: "0",
152551: "1"
}
}
}
Can you help me?
You overwrite the result on every loop of the loop. What you need to do is:
while($result = $mini_result->fetch()) {
$output['servers']['mini_result'][$result['id']] = $result['result'];
}
This does get quickly quite confusing. You can simplify it, like this:
$miniResult = [];
while($result = $mini_result->fetch()) {
$miniResult[$result['id']] = $result['result'];
}
$output['servers']['mini_result'] = $miniResult;
This what u need:
$mini_result = $db->query("SELECT * FROM `sessions` WHERE status = '1' LIMIT 5");
$output['servers']['mini_result'] = [];
while( $result = $mini_result->fetch()){
$output['servers']['mini_result'][$result['id']] = $result['result'];
}
i am working in codeigniter and i need to show a list of destinations as row in datatables, like UK as Parent and London as Child destination.
i need to show them in datatable, i have created array of both parent and child data, but i am not able to understand, how to show them in datatable properly as each child destination row below their parent row.
something like wordpress parent and child category.
here is what i did as of now.
here is my controller
public function fetch_destinations(){
// POST data
$postData = $this->input->post();
// Get data
$data = $this->tourismo->fetch_dest_nested($postData);
echo json_encode($data);
}
this is my model
function fetch_dest_nested($postData=null)
{
$response = array();
## Read value
$draw = $postData['draw'];
$start = $postData['start'];
$rowperpage = $postData['length']; // Rows display per page
$columnIndex = $postData['order'][0]['column']; // Column index
$columnName = $postData['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $postData['order'][0]['dir']; // asc or desc
$searchValue = $postData['search']['value']; // Search value
## Search
$search_arr = array();
$searchQuery = "";
if($searchValue != ''){
$search_arr[] = " (name like '%".$searchValue."%' ) ";
}
if(count($search_arr) > 0){
$searchQuery = implode(" and ",$search_arr);
}
## Total number of records without filtering
$this->db->set_dbprefix('');
$this->db->select('count(*) as allcount');
$records = $this->db->get('destinations')->result();
$totalRecords = $records[0]->allcount;
## Total number of record with filtering
$this->db->select('count(*) as allcount');
if($searchQuery != '')
$this->db->where($searchQuery);
$records = $this->db->get('destinations')->result();
$totalRecordwithFilter = $records[0]->allcount;
//fetch records
$this->db->select("*");
if($searchQuery != '')
$this->db->where($searchQuery);
$this->db->where('level', 1);
$this->db->order_by($columnName, $columnSortOrder);
$this->db->limit($rowperpage, $start);
$this->db->from("destinations");
$q = $this->db->get();
$final = array();
if ($q->num_rows() > 0) {
foreach ($q->result() as $row) {
$this->db->select("*");
$this->db->from("destinations");
$this->db->where("parentid", $row->id);
$q = $this->db->get();
if ($q->num_rows() > 0) {
$row->children = $q->result();
}
array_push($final, $row);
}
}
$data = array();
foreach($final as $parentdest){
$data[] = array(
"id"=>$parentdest->id,
"name"=>$parentdest->name,
"slug"=>$parentdest->slug
);
}
## Response
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordwithFilter,
"aaData" => $data
);
return $response;
}
this is my view
<table class="apitable table dt-table" id="destlist_table">
<thead>
<th>
Destination Id</th>
<th>Destination Name</th>
<th>Destination Slug</th>
</thead>
</table>
here is my jquery code for ajax request
<script src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<!-- Script -->
<script type="text/javascript">
$(document).ready(function(){
var destlistDataTable = $('#destlist_table').DataTable({
'bDestroy': true,
'processing': true,
'serverSide': true,
'serverMethod': 'post',
"searching": true,
"pageLength": 10,
"order":[[0,'desc']],
'ajax': {
'url':'<?php echo admin_url('tourismo/tourismo/fetch_destinations'); ?>',
'data': function(data){
}
},
'columns': [
{ data: 'id' },
{ data: 'name' },
{ data: 'slug' },
]
});
});
what i want is every child destination row should be just below its Parent destination row, i am just not able to understand how to work with this loop here.
this is the reference for what i want
I have an user table using DataTables, that will contain more than 200 rows. It's look so fine when I'm using DataTables for default the "pageLength": 10, and this is the table example.
Username | Type | Request |
user01 1 request01
user02 1 request02
user03 2 request03
user04 1 request04
user05 1 request05
user06 1 request06
user07 1 request07
user08 1 request08
user09 1 request09
user10 1 request10
Showing 1 to 10 of 200 entries FirstPrevious123...20NextLast
So, for reducing the loading time, I decide to use "processing": true and "serverSide": true. Then I got some issue with this "serverSide" : true, It's print 200 rows of data in table.
Showing 0 to 0 of 0 entries (filtered from NaN total entries). Then the pagination is still print and after I click the page 2, it's doing nothing.
I wan't the DataTables is getting the 10 data for the first, after pagination 2 is clicked, it will get 10 more and so on.
I'm using CodeIgniter, here is my code :
On my Views + Js :
<select name="task" id="task">
<option value="1">Task 1</option>
<option value="2">Task 2</option>
</select>
<table id="user-request" class="table">
<thead>
<tr>
<th>Username</th>
<th>Type</th>
<th>Request</th>
</tr>
</thead>
</table>
<script>
... on task change ...
... var task = $("#task").val(); ...
$('#user-request').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
'type': 'POST',
'url': base_url+'user/get_user_request',
'data': {"task":task,"csrf_token":$("input[name=csrf_token]").val()}
}
})
</script>
Note : Task is a different group, example like Class 1 or Class 2, Orchard University or Harvard University
On my Controller :
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request(task);
foreach ($user_request as $ur)
{
$arr = array();
$arr[] = $ur->username;
$arr[] = $ur->type;
$arr[] = $ur->request;
$data[] = $arr;
}
$output = array(
"data" => $data
);
if (COUNT($output) > 0)
{
echo json_encode($output);
}
On my Model :
public function all_user_request($task_id) {
$query = "SELECT * FROM user_request WHERE task_id = ?";
return $this->db->query($query, $task_id)->result();
}
Note : In model is actually using 2 INNER JOIN, I'm just simplifying the select only for asking here. (turning into denormalization table only in here).
I was trying to add draw, recordsTotal, recordsFiltered to $output in my controller just using numeric data. Example
$output = array(
"draw" => 5,
"recordsTotal" => 5,
"recordsFiltered" => 5,
"data" => $data
);
if (COUNT($output) > 0)
{
echo json_encode($output);
}
I was searching for the answer but, and I think the problem is here but I still have no idea where I must get the draw - recordsTotal - recordsFiltered data. I see on another answer from others, they use "draw" => $_POST['draw'], then I tried it, and it's do nothing.
So I'm trying that using numeric data, but the result is still same. I need some help with this. It's still print 200 rows of data in table.
Showing 0 to 0 of 0 entries (filtered from NaN total entries). Then the pagination is still print and after I click the page 2, it's doing nothing.
Datatables send everything you need - if you take a look in your console under network you'll see, that they use the ajax-get method to send those requests to the server
The GET Parameter are as follows
draw
columns
start
length
search
You can find the entire list here
which means - you've to adapt your model properly...
something like that should work
public function all_user_request($task_id)
{
$intStart = intval($this->input->get("start"));
$intLength = intval($this->input->get("length"));
$strSearch = (strlen($this->input->get("search")["value"]) >= 2) ? $this->input->get("search",true)["value"] : false;
$order = $this->input->get("order",true);
$this->setQuery($task_id,$strSearch);
$query = $this->db->get();
$this->recordsTotal = $query->num_rows();
$this->setQuery($task_id, $strSearch);
if ($intStart >= 0 && $intLength > 0)
{
$this->db->limit($intLength,$intStart);
}
$strOrderField = 'username';
$strDirection = "ASC";
if (is_array($order))
{
switch($order[0]['column'])
{
case 1:
$strOrderField = 'type';
break;
case 2:
$strOrderField = 'request';
break;
}
if (!empty($order[0]['dir'])) $strDirection = $order[0]['dir'];
}
$this->db->order_by($strOrderField,$strDirection);
$query = $this->db->get();
$arrData = $query->result();
return $arrData;
}
public function getRecordsTotal()
{
return $this->recordsTotal;
}
private function setQuery($task_id, $strSearch="")
{
$this->db
->select('*')
->from('user_request')
->where('task_id', $task_id);
if (!empty($strSearch))
{
$this->db->like('task_id', $strSearch);
}
}
and your controller
//controller
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request($task);
$data = [];
foreach ($user_request as $ur)
{
$data[] = [
$ur->username,
$ur->type,
$ur->request
];
}
$arrCompiledData = [
'data' => $data,
'draw' => $this->input->get('draw'),
'recordsTotal' => $this->model->getRecordsTotal(),
'recordsFiltered' => $this->model->getRecordsTotal(),
];
$this->output
->set_content_type('application/json')
->set_output(json_encode($arrCompiledData));
Please keep in mind i just wrote this down - maybe there are some typos, but you should be able to understand how the serverside processing of a datatables request should work.
As long as you chose the server mode, you have to manage everything via the requests.
So, you have to dynamically create the values of the output array :
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->my_model->get_total_records(),
"recordsFiltered" => $this->my_model->get_total_filtered(),
"data" => $this->my_model->all_user_request($id)
);
and the model functions
public function all_user_request($task_id) {
$query = "SELECT * FROM user_request WHERE task_id = ?"; // add limit $_POST['length'], $_POST['start'] to your request
return $this->db->query($query, $task_id)->result();
}
If you're using serverSide = true, you should provide your own filter count and total count. Also provide your own search function, ordering and etc. Use controller & model below for your reference.
Controller
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request($task);
$output = array(
'draw' => $this->input->post('draw', TRUE),
'recordsTotal' => $user_request['recordsTotal'],
'recordsFiltered => $user_request['recordsFiltered'],
'data' => empty($user_request['data'])? array() : $user_request['data']
);
echo json_encode($output);
Model
public function all_user_request($task_id) {
$params = $this->input->post(null, TRUE);
$search_fields = array('username','type','request'); //change this into your table fields
$data = array();
$this->db->start_cache();
$this->db->select("username, type, request");
$this->db->from("user_request");
$this->db->where("task_id", $task_id);
if(!empty($params['search']['value'])){
$str = $params['search']['value'];
$this->db->group_start();
foreach($search_fields as $row){
$this->db->or_like($row, $str, 'BOTH');
}
$this->db->group_end();
}
$data['recordsTotal'] = $this->db->count_all_results();
$this->db->stop_cache();
$this->db->limit($params['length'], $params['start']);
$data['recordsFiltered'] = $this->db->count_all_results();
$query = $this->db->get();
$this->db->flush_cache();
foreach($query->result_array() as $row){
$data['data'][] = array_values($row);
}
return $data;
}
$query = "SELECT `contact_id`, `user_id`, `date_backup`, `first_name`, `last_name` FROM tbl_contacts WHERE date(`date_backup`) = (SELECT MAX(date(`date_backup`)) FROM tbl_contacts WHERE `user_id`= '$userId' ) ORDER BY `date_backup` DESC, `contact_id` ASC";
$result = mysql_query($query);
while($row = mysql_fetch_assoc($result)) {
$contacts = array(array());
$contactId = $row['contact_id'];
$names["first_name"] = $row['first_name'];
$names["last_name"] = $row['last_name'];
$contacts["names"][] = $names;
// Phone
$phoneQuery = "SELECT * FROM tbl_phone_details WHERE contact_id = '$contactId' AND date(`date_backup`) = (SELECT MAX(date(`date_backup`)) FROM tbl_phone_details WHERE `contact_id`= '$contactId')";
$phoneResult = mysql_query($phoneQuery);
$total = mysql_affected_rows();
if($total >= '1') {
while($phoneRow = mysql_fetch_assoc($phoneResult)) {
$phones["phone_number"] = $phoneRow['phone_number'];
$phones["phone_type"] = $phoneRow['phone_type'];
$contacts["phones"][] = $phones;
}
} else {
$contacts["phones"][] = array();
}
// Email
$emailQuery = "SELECT * FROM `tbl_email_details` WHERE `contact_id` = '$contactId' AND date(`date_backup`) = (SELECT MAX(date(`date_backup`)) FROM tbl_email_details WHERE `contact_id`= '$contactId')";
$emailResult = mysql_query($emailQuery);
$total = mysql_affected_rows();
if($total >= '1') {
while($emailRow = mysql_fetch_assoc($emailResult)) {
$emails["email_address"] = $emailRow['email_address'];
$emails["email_type"] = $emailRow['email_type'];
$contacts["emails"][] = $emails;
}
} else {
$contacts["emails"][] = array();
}
// Address
$addressQuery = "SELECT * FROM `tbl_address_detail` WHERE `contact_id` = '$contactId' AND date(`date_backup`) = (SELECT MAX(date(`date_backup`)) FROM tbl_address_detail WHERE `contact_id`= '$contactId')";
$addressResult = mysql_query($addressQuery);
$total = mysql_affected_rows();
if($total >= '1') {
while($addressRow = mysql_fetch_assoc($addressResult)) {
$address["street"] = $addressRow['street'];
$address["city"] = $addressRow['city'];
$address["state"] = $addressRow['state'];
$address["zip"] = $addressRow['zip'];
$address["country"] = $addressRow['country'];
$address["addressType"] = $addressRow['addressType'];
$contacts["address"][] = $address;
}
} else {
$contacts["address"][] = array();
}
$contectInfoJson["contacts"][] = $contacts;
}
$allContactJson["AllContacts"] = $contectInfoJson;
header('Content-Type: application/json');
echo json_encode($allContactJson);
OUTPUT OF CODE :-
AllContacts: {
userId: "15",
contacts: [
{
0: [ ], // Not needed
names: [ // Instead of array i need simple object of names
{
first_name: "ABC",
last_name: "XYZ"
}
],
phones: [
{
phone_number: "+911234567890",
phone_type: "Work"
},
{
phone_number: "+919876543210",
phone_type: "Home"
}
],
emails: [
[ ] //This is also extra and not needed.
],
address: [
{
street: "India",
city: "",
state: "",
zip: "",
country: "",
addressType: ""
}
]
},
REQUIRED OUTPUT:-
AllContacts: {
userId: "15",
contacts: [
{
names:
{
first_name: "ABC",
last_name: "XYZ"
},
phones: [
{
phone_number: "+911234567890",
phone_type: "Work"
},
{
phone_number: "+919876543210",
phone_type: "Home"
}
],
emails: [],
address: [
{
street: "India",
city: "",
state: "",
zip: "",
country: "",
addressType: ""
}
]
},
I am facing 2-3 small problem in the code.
First is that i am getting 0 : [] on every start of the object.
2nd one is names is array and i want it to be object not array.
3rd is emails :[ [] ], i want blank array if data is not available, but i am getting array inside array. I just want emails :[].
Replace $contacts = array(array()); with $contacts = array();. Should remove 0 : [].
$contacts["emails"][] = array(); is triggered probably, so try to replace it with $contacts["emails"] = array();
Replace $contacts["names"][] = $names; with $contacts["names"] = $names;
How this code works is every time a user visits the page, i scrape all of the data from the table and pass it through the below posts. If the user hasn't accessed that page before and the database is empty with their cookie_id, then it inserts the content, if it is found then it deletes the content from the database and inserts it again. The problem I am having though is that when the deletion occurs it deletes everything and seems to insert one value from $data1 instead of all the data from $data. Any ideas as to why this is happening?
Backend:
$cookie_id = $this->input->cookie("session_id");
$selected_size = $this->input->post('selected_size');
$product_id = $this->input->post('product_id');
$product_name = $this->input->post('product_name');
$product_color = $this->input->post('product_color');
$q1 = $this->db->query("SELECT * FROM default_cart_temp
WHERE cookie_id = '$cookie_id'
AND is_paid = 'No'");
if ($q1->num_rows() > 0) {
$this->db->where('cookie_id', $cookie_id);
$this->db->delete('default_cart_temp');
foreach($product_id as $key => $value) {
$data1 = array('selected_size' => $selected_size[$key],
'product_id' => $value,
'product_name' => $product_name[$key],
'product_color' => $product_color[$key],
'cookie_id' => $cookie_id,
'is_paid' => 'No');
} $this->db->insert('default_cart_temp', $data1);
echo json_encode(array('success' => true));
} else {
foreach($product_id as $key => $value) {
$data = array('selected_size' => $selected_size[$key],
'product_id' => $value,
'product_name' => $product_name[$key],
'product_color' => $product_color[$key],
'cookie_id' => $cookie_id,
'is_paid' => 'No');
} $this->db->insert('default_cart_temp', $data);
}
Frontend:
selected_size = $('.selected_size1').text();
arr1 = selected_size.split(".");
ss1 = arr1.slice(0, -1);
product_id = $('.product_id1').text();
arr2 = product_id.split(".");
ss2 = arr2.slice(0, -1);
product_name = $('.product_name1').text();
arr3 = product_name.split(".");
ss3 = arr3.slice(0, -1);
product_color = $('.product_color1').text();
arr4 = product_color.split(".");
ss4 = arr4.slice(0, -1);
$.ajax({
type: "POST",
dataType: "JSON",
url: "<?=base_url()?>index.php/products/products/new_instance",
data: { selected_size: ss1, product_id: ss2, product_name: ss3, product_color: ss4 },
json: {success: true},
success: function(data) {
if(data.success == true) {
alert("True");
}
}
});
In every foreach loop execution you are overriding $data and $data1 variables. You have to change them to arrays and add data like this $data[] = $subArray.