the default behaviour of dataTable is good, as long as the number of rows are not 907234. I would like to use Ajax oriented working, so get 10 records per pages, etc. I know I can set AJAX source, but only once, and then paging would be futule. (how would it work, if datatable doesnt know the number of records?) not to mention the searching. So how to start?
The server side approach of Datatable is like so:
$('#dataTable').dataTable({
"sServerMethod": "GET",
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "data.php",
"aoColumns": [null, null, null, { "bSortable": false }],
"order": [[ 1, "asc" ]],
"oLanguage": {"sZeroRecords": "No Members found", "sEmptyTable": "No members to display"},
});
The backend i.e data.php should be like so:
<?php
$start = $_GET['iDisplayStart'];
$length = $_GET['iDisplayLength'];
$sSearch = $_GET['sSearch'];
$col = $_GET['iSortCol_0'];
$arr = array(1 => 'oe.org_given_id', 2 => 'usr.name');
$sort_by = $arr[$col];
$sort_type = $_REQUEST['sSortDir_0'];
$query = "SELECT usr.id,usr.name,oe.org_given_id FROM users usr JOIN organization_employees oe on usr.id=oe.employee_id WHERE oe.organization_id=".$organization_id." AND (usr.name LIKE '%".$sSearch."%' OR oe.org_given_id LIKE '%".$sSearch."%') ORDER BY ".$sort_by." ".$sort_type." LIMIT ".$start.", ".$length;
$db=new DB();
$resultSet=$db->SelectRead($query);
while($row = mysqli_fetch_assoc($resultSet))
{
$data[] = $row;
}
$counterQuery = "SELECT COUNT(usr.id) as total FROM users usr JOIN organization_employees oe on usr.id=oe.employee_id WHERE oe.organization_id=".$organization_id.";";
$countSet = $db->SelectRead($counterQuery);
$iTotal=0;
while($counterRow = mysqli_fetch_assoc($countSet))
{
$iTotal = $counterRow['total'];
}
$rec = array(
'iTotalRecords' => $iTotal,
'iTotalDisplayRecords' => $iTotal,
'aaData' => array()
);
$k=0;
if (isset($data) && is_array($data))
{
foreach ($data as $item)
{
$rec['aaData'][$k] = array(
0 => $k,
1 => $item['org_given_id'],
2 => $item['name'],
3 => "Delete"
);
$k++;
}
}
header("Content-type:application/json");
echo json_encode($rec);
?>
The parameters like:
iDisplayStart and iDisplayLength etc are default given by Datatables.
Some online working examples are:
https://coderexample.com/datatable-demo-server-side-in-phpmysql-and-ajax/
http://phpflow.com/php/datatables-example-server-side-processing-with-php/
http://phpflow.com/demo/datatable/
A github repository of my code is below with some additional features offcourse:
https://github.com/shaktiphartiyal/DataTable-Editor-Free
Related
I am building a news blog that upload posts every hour. I have created a shortcode that displays the last 15 posts on the home page. My problem was that the server cache needed to be deleted every hour. so I've decided to serve the post via AJAX so this area will get the latest posts every page load.
I found this answer and combine it whit my code.
My problem is that it displays all of the posts and not just 15.
PHP:
function get_ajax_posts() {
// Query Arguments
$args = array(
'post_type' => array('post'),
'post_status' => array('publish'),
'posts_per_page' => 15,
'nopaging' => true,
'order' => 'DESC',
'orderby' => 'date',
);
$ajaxposts = new WP_Query( $args );
$response = '';
if ( $ajaxposts->have_posts() ) {
while ( $ajaxposts->have_posts() ) {
$ajaxposts->the_post();
$response .= get_template_part( 'template-parts/content-archive');
}
} else {
$response .= get_template_part('none');
}
echo $response;
exit; // leave ajax call
}
// Fire AJAX action for both logged in and non-logged in users
add_action('wp_ajax_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
JS:
$.ajax({
type: 'POST',
url: '<?php echo admin_url('admin-ajax.php');?>',
dataType: "html",
data: { action : 'get_ajax_posts' },
success: function( response ) {
$( '.home-hot-flights' ).html( response );
//hot-flights
var hot_flights_item = $(".home-hot-flights article").width() + 17;
$(".art-move-left").click(function () {
$('.move-right').addClass('show-move-right');
var leftPos = $('.home-hot-flights').scrollLeft();
$(".home-hot-flights").animate({scrollLeft: leftPos - hot_flights_item}, 200);
});
$(".art-move-right").click(function () {
var leftPos = $('.home-hot-flights').scrollLeft();
$(".home-hot-flights").animate({scrollLeft: leftPos + hot_flights_item}, 200);
});
}
});
This might help you:
Pagination parameters
(nopaging (boolean) – show all posts or use pagination. Default value
is ‘false’, use paging. )
Display all posts by disabling pagination:
$query = new WP_Query( array( 'nopaging' => true ) );
I think you should remove that parameter if you want to display a certain number of posts using posts_per_page.
Try this piece of code I have edit your code please see below
function get_ajax_posts() {
// Query Arguments
$args = array(
'post_type' => array('post'),
'post_status' => array('publish'),
'posts_per_page' => 15,
'order' => 'DESC',
'orderby' => 'date',
);
wp_reset_query();
$ajaxposts = new WP_Query( $args );
$response = '';
if ( $ajaxposts->have_posts() ) {
while ( $ajaxposts->have_posts() ) {
$ajaxposts->the_post();
$response .= get_template_part( 'template-parts/content-archive');
}
} else {
$response .= get_template_part('none');
}
echo $response;
exit; // leave ajax call
}
// Fire AJAX action for both logged in and non-logged in users
add_action('wp_ajax_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
If the two loops data is overwridden then, I your first code wp_reset_query() is incorrect. If you are using WP_Query then
wp_reset_postdata() //remove wp_reset_query() which is used for wp_query()
should be used after the end of the WHILE loop which means that in your two loops you have to have
wp_reset_postdata() // use this at both loops
I am using ajax to send data to a custom rest endpoint. I am doing this because i'm creating a filter function on my WP site.
Now I am stuck trying to get the tax_query to work with my array of terms collected with JS on the front end. No matter what I do I cant seem to get this to work, and I am strongly suspecting this is only a minor error that I keep overlooking...
Just to clarify, the ajax sends the request successfully but the query returns all posts no matter what.
Here is the checkboxes used on the front end:
<div class="form-group">
<?php
if( $terms = get_terms( array( 'taxonomy' => 'utst', 'hide_empty' => false, 'orderby' => 'name' ) ) ) :
foreach ( $terms as $term ) :
echo '<div class="form-check">';
echo '<label class="form-check-label" for="'.$term->slug.'"><input class="form-check-input" type="checkbox" id="'.$term->slug.'" name="utstyrAr[]" value="'.$term->term_id.'"> '.$term->name.'</label>'; // ID of the category as the value of an option
echo '</div>';
endforeach;
endif;
?>
</div>
The JS (ajax function):
filterOppdrag(fiOppdrag) {
var utst = [];
var utstyrArray = document.getElementsByName("utstyrAr[]");
for (var i = 0; i < utstyrArray.length; i++) {
if(utstyrArray[i].type =='checkbox' && utstyrArray[i].checked == true) utst.push(utstyrArray[i].value);
}
console.log(utst);
$.ajax({
url: the.root + '/wp-json/myfilter/v1/filter',
type: 'GET',
data: {
'checkUtst' : utst,
},
success: (response) => {
console.log(response);
},
error: (response) => {
console.log(response);
}
});
}
And the wp_query (php):
function myFilter ($data) {
$checkUtst = sanitize_text_field($data['checkUtst']);
//Main $args
$args = array(
'post_type' => 'ml_opp', // Query only "ml_opp" custom posts
'post_status' => 'publish', // Query only posts with publish status
'orderby' => 'date', // Sort posts by date
'order' => 'ASC' // ASC or DESC
);
// for taxonomies / utstyr
if( isset( $utstyr ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'ml_utst',
'field' => 'id',
'terms' => $checkUtst
)
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
This returns all the posts regardless of terms no matter what I pass through. I get no error messages and yes I have tested so that there is value in the array when I send it to the query. But what happens to it on the road there, I dont know. That's why i figure that Its probably just a rookie mistake I am making here.
Any help would be greatly appreciated!
Have you tried removing the wrapping array and not using a key?
$args = array(
'taxonomy' => 'ml_utst',
'field' => 'id',
'terms' => $checkUtst
);
Before all
I have model for image as simple as
return [
'id' => 'ID',
'parent_id' => 'Parent ID',
'photo' => 'Photo', <= just for filename
];
the case is
Create Parent model then save then redirect to form for uploading images related to its parent.
all uploading function work proprerly but no with delete function
This is my upload image form
echo FileInput::widget([
'model' => $photo,
'attribute' => 'photo',
'options'=>[
'accept'=>'image/*',
'multiple'=>true
],
'pluginOptions' => [
'uploadUrl' => Url::to(['/controller/upload', 'id'=> $parent->id]),
'initialPreview'=>$pre-initViews-data,
'initialPreviewAsData'=>true,
'initialCaption'=>"Foto Tersangka",
'initialPreviewConfig' => $pre-initConfigs-data,
'overwriteInitial'=>true,
//'deleteUrl'=> Url::to(['/controller/deletephoto']), <= case 2
'showPreview' => true,
'showRemove' => false,
'showUpload' => false,
'maxFileSize'=>2800
],
'pluginEvents' => [
'fileuploaded'=>"function(event, data, previewId, index){
console.log(data);
}",
]
]);
And here my controller side
$imageFile = UploadedFile::getInstance($model, 'photo');
$directory = Yii::$app->basePath. '/images/';
if ($imageFile) {
$fileName = Yii::$app->security->generateRandomString(). '.' . $imageFile->extension;
$filePath = $directory . $fileName;
if ($imageFile->saveAs($filePath) && $model->save(false)) {
$path = '/images/temp/' . $fileName;
Image::thumbnail($directory.$fileName, 120, 120)
->save(Yii::$app->basePath.$path, ['quality' => 80]);
$response = [];
$reponse['initialPreview'] = \Yii::$app->request->BaseUrl.'/images/'.$fileName;
$reponse['initialPreviewConfig']=[
'caption'=>'',
'width'=>'90px',
'key'=>$model->id,
'url'=>Url::to(['/controller/deletephoto']),
'extra'=>['id'=>$model->id]
];
echo json_encode($reponse);
}
}
And will produce JSON data like this :
{
"initialPreview": "\/web\/images\/Kl1IJOabLs5ENzzgkuW8ln_TILcDumy9.png",
"initialPreviewConfig": {
"caption": "",
"width": "90px",
"key": 38,
"url": "\/web\/index.php?r=controller%2Fdeletephoto",
"extra": {
"id": 38
}
}
}
The issue
I try different way like :
case 1 :
at form widget withoud pluginOptions => deleteUrl'=> Url::to(['/controller/deletephoto']),
upload process success, response from controller initialPreview overwriting initial as expected, but initialPreviewConfig seems doesnt fit, so delete button doesnt work/ doesnt give any process when clicked.
case 2 :
at form widget with pluginOptions => deleteUrl'=>
Url::to(['/controller/deletephoto']) , upload process as expected, but when i click delete button post action didnt parse key as below
Query string
r : controller/deletephoto
Form data
key : {empty key}
Finally
Ive spend huge amount of hours, Please review my code, is there something wrong?
a Big thanks for your help.
UPDATE ISSUE RESOLVED
after long hours finally i got the way..
replace
$response = [];
$reponse['initialPreview'] = \Yii::$app->request->BaseUrl.'/images/'.$fileName;
$reponse['initialPreviewConfig']=[
'caption'=>'',
'width'=>'90px',
'key'=>$model->id,
'url'=>Url::to(['/controller/deletephoto']),
'extra'=>['id'=>$model->id]
];
echo json_encode($reponse);
with
return Json::encode([
'initialPreview' => \Yii::$app->request->BaseUrl.'/images/'.$fileName,
'initialPreviewConfig' => [
[
'caption'=>'',
'width'=>'90px',
'key'=>$model->id,
'url'=>Url::to(['/controller/deletephoto']),
'extra'=>['id'=>$model->id]
],
],
]);
dont know why this happen,
I'm not a JS guy, I working on a small interface for my weather station. I have a serverside code which generates the JSON data for the graph. It looks like this:
[
{
"temperature": "32.1",
"humidity": "91",
"battery": "100",
"time": "2016-02-21 15:28:56"
},
{
"temperature": "32.1",
"humidity": "99.3",
"battery": "100",
"time": "2016-02-21 15:28:47"
},
{
"temperature": "22.2",
"humidity": "70.2",
"battery": "88.2",
"time": "2016-02-21 15:28:19"
},
{
"temperature": "21.2",
"humidity": "88.1",
"battery": "90.4",
"time": "2016-02-21 15:28:22"
}
]
How can I feed this data into a Line chart using Google's Chart API? I have tried using the example but it does not work. (https://developers.google.com/chart/interactive/docs/gallery/linechart)
First define your array in the format which google charts requires:
$resultsarray = array(
'cols' => array(
array('label' => 'temperature', 'type' => 'number'),
array('label' => 'humidity', 'type' => 'number'),
array('label' => 'battery', 'type' => 'number'),
array('label' => 'time', 'type' => 'date'),
),
'rows' => array()
);
Then add the data to your array:
$resultsarray['rows'][] = array('c' => array( array('v'=> 'tempvalue'), array('v'=>'humidityval'), array('v'=>'batteryval'),array('v'=>'timeval')));
Encode as JSON and write to a file:
$fp = fopen('data.json', 'w');
//JSON encode and write array to file
fwrite($fp, json_encode($resultsarray, JSON_NUMERIC_CHECK));
fclose($fp);
Then in your JavaScript you need: (as per Google Example)
function drawChart() {
var jsonData = $.ajax({
url: "getData.php",
dataType: "json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
Then the contents of getdata.php (as per google example)
<?php
// This is just an example of reading server side data and sending it to the client.
// It reads a json formatted text file and outputs it.
$string = file_get_contents("data.json");
echo $string;
// Instead you can query your database and parse into JSON etc etc
?>
The json isn't formatted properly. Google charts expect a specific json type for its chart. I'm assuming that your database is mysql. If not, I can always modify the following code. I have created a small library to perform these annoying tasks. So here it is :
<?php
function generate_GChart_cols($result) {
$fieldcount = mysqli_num_fields($result);
$stringVal = [253]; // MySQL field type codes -See http://php.net/manual/en/mysqli-result.fetch-field-direct.php
$numericVal = [246, 8]; // MySQL field type codes -See http://php.net/manual/en/mysqli-result.fetch-field-direct.php
$colsarray = array();
for ($i = 0; $i < $fieldcount; $i++) {
$finfo = mysqli_fetch_field_direct($result, $i);
switch ($finfo->type) {
case in_array($finfo->type, $stringVal):
$type = 'string';
break;
case in_array($finfo->type, $numericVal):
$type = 'number';
break;
default:
$type = 'string';
}
// Constructs the column array
$colsarray[] = array(
'label' => $finfo->name,
'type' => $type
);
}
return $colsarray;
}
function generate_GChart_rows($result) {
$fieldcount = mysqli_num_fields($result);
$rows = array();
while ($r = $result->fetch_row()) {
$temp = array();
for ($j = 0; $j < $fieldcount; $j++) {
$temp[] = array(
'v' => $r[$j]
);
}
$rows[] = array(
'c' => $temp
);
};
return $rows;
}
?>
A usage example would be :
<?php
header('content-type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin:*'); //Include this header to make the requests cross-origin
include 'dbconnect.php';
include 'generate_google_json.php';
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = // Your query here - e.g SELECT * FROM TABLE // ;
$result = $conn->query($sql);
$table['data']['rows'] = generate_GChart_rows($result); // Call to function to generate rows
$table['data']['cols'] = generate_GChart_cols($result); // Call to function to generate columns
$conn->close(); // Close db connection
// We echo the json and enforce a numeric check on the values
echo $_GET['callback'] . '(' . json_encode($table, JSON_NUMERIC_CHECK) . ')';
?>
An example output would be :
?(
{
data:{
rows:[
{
c:[
{
v:3123600
},
{
v:3116452
}
]
}
],
cols:[
{
label:2013,
type:"number"
},
{
label:2014,
type:"number"
}
]
}
}
)
In the event where you use other types than bigint, varchart and decimal, you might wanna add more values to the $stringVal and $numericVal arrays :)
Cheers
Google charts is expecting the JSON in this format:
{
"cols": [
{"id":"","label":"temperature","pattern":"","type":"number"},
{"id":"","label":"humidity","pattern":"","type":"number"},
{"id":"","label":"battery","pattern":"","type":"number"},
{"id":"","label":"time","pattern":"","type":"date"}
],
"rows": [
{"c":[{"v":"32.1","f":null},{"v":99.3,"f":null},{"v":100,"f":null},{"v":2016-02-21 15:28:47,"f":null}]}
]
}
I have a mysql database that is in UTF8, I've properly output the letters before but cannot make my php do so with datatables using the ajax process. I have tried various methods to get the UTF8 to show, including, changing headers, using mysql functions, and changing the json encode function, but I cannot make it work. Please help me show UTF8 properly instead of ?s.
I have: temps.php
My server side processing script:
<?php
header("Content-Type: text/json; charset=utf-8");
require( 'ssp.class.php' );
$table = 'articles';
$primaryKey = 'id';
$columns = array(
array( 'db' => 'title', 'dt' => 0 ),
array( 'db' => 'description', 'dt' => 1 ));
$sql_details = array(
'user' => 'root', 'pass' => 'pass', 'db' => 'test', 'host' => 'localhost'
);
$db = SSP::db($sql_details);
.....
if($clause !== ""){
$whereAll[] = $clause;
$_GET['columns'][$i]['search']['value'] = "";
}}
echo json_encode(
SSP::complex( $_GET, $db, $table, $primaryKey, $columns, null,
(!empty($whereAll) ? implode(" AND ", $whereAll) : "")
));
I have: temp.html: My Javascript function (based on datatables and yadcf)
$(document).ready(function(){
$("#example").dataTable({
"responsive": true,
"processing": true,
"serverSide": true,
"ajax": "scripts/temps.php",
"columns": [
// ID
null,
// Distributor
null
// Director
]
}).yadcf([
// ID
{
column_number: 0 ,
filter_type: "text",
filter_reset_button_text: false
},
// Abstract
{
column_number: 1,
filter_type: "text",
filter_delay: 500,
filter_reset_button_text: false
},
]);
});
And I have temp.html where the data is outputted: (redacted because a lot of the code is irrelevant to the question)
<!DOCTYPE html>
<div>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="Description" CONTENT=""/>
..........
<table id="example" class="table table-striped table-bordered table-condensed" cellspacing="0" width="100%">
<thead>
<tr>
<th><div>One</div></th>
<th><div>Two</div></th>
</tr>
</thead>
</table>
Sorry for such a long question; but what else can I change to make UTF8 properly show on the html page? I've tried all the combinations of variables and functions I can think of; but can't make it work. Perhaps there is a js function that could be applied somewhere? Thank you for the help.
Edit: SQL structure for reference:
CREATE TABLE IF NOT EXISTS `articles` (
`id` int(11) NOT NULL,
`title` varchar(300) CHARACTER SET utf8 DEFAULT NULL,
`description` text CHARACTER SET utf8
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-- Dumping data for table `articles`
INSERT INTO `articles` (`id`, `title`, `description`) VALUES
(1, 'శ్రీనివాస్scddadas తామాడా', '新概念英语第asv'),
(2, 'asda', 'asdవా'),
3, 'sdfsadfsdf英语', 'sadf英');
You need to force utf8 in the PDO connection :
$db = SSP::db($sql_details);
$db->exec("set names utf8");
alternatively, try pass it as a param :
$sql_details = array(
'user' => 'root',
'pass' => 'ryan',
'db' => 'edata',
'host' => 'localhost',
'charset' => 'utf8'
);
But this does not work with all PHP versions.
PS: Why do you set the table fields to be of type utf8, but the table character set to be latin1?
If you have added all the columns as "UTF-8" and still the problem persists then try this
Add these lines on the server side file
mysql_query("SET character_set_client=utf8",$gaSql['link']);
mysql_query("SET character_set_connection=utf8",$gaSql['link']);
mysql_query("SET character_set_results=utf8",$gaSql['link']);