datatables + serverside processing + search filtering - javascript

I am following this tutorial:
http://coderexample.com/datatable-demo-server-side-in-phpmysql-and-ajax/
and here is the demo:
http://coderexample.com/demo/datatable-demo-server-side-in-phpmysql-and-ajax/
If i search for ou in the search input i get No matching records found but what I would like returned is this row Airi Satou at least.
this is the code that i have to change, I think, as I have to do the search server side.
<?php
/* Database connection start */
$servername = "localhost";
$username = "root";
$password = "Password1";
$dbname = "test";
$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
/* Database connection end */
// storing request (ie, get/post) global array to a variable
$requestData= $_REQUEST;
$columns = array(
// datatable column index => database column name
0 =>'employee_name',
1 => 'employee_salary',
2=> 'employee_age'
);
// getting total number records without any search
$sql = "SELECT employee_name, employee_salary, employee_age ";
$sql.=" FROM employee";
$query=mysqli_query($conn, $sql) or die("employee-grid-data.php: get employees");
$totalData = mysqli_num_rows($query);
$totalFiltered = $totalData; // when there is no search parameter then total number rows = total number filtered rows.
if( !empty($requestData['search']['value']) ) {
// if there is a search parameter
$sql = "SELECT employee_name, employee_salary, employee_age ";
$sql.=" FROM employee";
$sql.=" WHERE employee_name LIKE '".$requestData['search']['value']."%' "; // $requestData['search']['value'] contains search parameter
$sql.=" OR employee_salary LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR employee_age LIKE '".$requestData['search']['value']."%' ";
$query=mysqli_query($conn, $sql) or die("employee-grid-data.php: get employees");
$totalFiltered = mysqli_num_rows($query); // when there is a search parameter then we have to modify total number filtered rows as per search result without limit in the query
$sql.=" ORDER BY ". $columns[$requestData['order'][0]['column']]." ".$requestData['order'][0]['dir']." LIMIT ".$requestData['start']." ,".$requestData['length']." "; // $requestData['order'][0]['column'] contains colmun index, $requestData['order'][0]['dir'] contains order such as asc/desc , $requestData['start'] contains start row number ,$requestData['length'] contains limit length.
$query=mysqli_query($conn, $sql) or die("employee-grid-data.php: get employees"); // again run query with limit
} else {
$sql = "SELECT employee_name, employee_salary, employee_age ";
$sql.=" FROM employee";
$sql.=" ORDER BY ". $columns[$requestData['order'][0]['column']]." ".$requestData['order'][0]['dir']." LIMIT ".$requestData['start']." ,".$requestData['length']." ";
$query=mysqli_query($conn, $sql) or die("employee-grid-data.php: get employees");
}
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData[] = $row["employee_name"];
$nestedData[] = $row["employee_salary"];
$nestedData[] = $row["employee_age"];
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval( $requestData['draw'] ), // for every request/draw by clientside , they send a number as a parameter, when they recieve a response/data they first check the draw number, so we are sending same number in draw.
"recordsTotal" => intval( $totalData ), // total number of records
"recordsFiltered" => intval( $totalFiltered ), // total number of records after searching, if there is no searching then totalFiltered = totalData
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
?>
Am I right to say that this is the code I have to change?
If so, can anyone advise what I have to do?
I understand this is alot to ask but would appreciate the guidance!

$sql.=" WHERE employee_name LIKE '".$requestData['search']['value']."%' ";
will match search term then anything (due to wild card %)
as you want to match the search term in the middle of the name you need to add the wild card at the begging as well:
$sql.=" WHERE employee_name LIKE '%".$requestData['search']['value']."%' ";
Note this will disable the use of indexes on employee_name which may or may not be a problem for you.
This is not the best search approach over all, you should not check all three fields, but ask the searcher which to use. After all age and salary could have some matching numbers.
a search for 27, could match age 27 or 27000 salary etc. And no one will have an age of bob so its pointless to do that search

Your query need to be updated.
The following SQL statement selects all with a employee_name starting with "search field value":
$sql.=" WHERE employee_name LIKE '".$requestData['search']['value']."%' ";
so, your query should be something like below, to get desired output, as it check whether a particular pattern is present in the employee_name.
$sql.=" WHERE employee_name LIKE '%".$requestData['search']['value']."%' ";

The way you are constructing your Where clause, the fields you are searching must start with the search term. Change your where clauses to
$sql.=" WHERE employee_name LIKE '%".$requestData['search']['value']."%' ";
You are also open to SQL injection by doing what you are doing. You need to use parameterized queries to remove this vulnerability. See How can I prevent SQL injection in PHP? for information

Related

share the same php function if `all years` option is selected

<select id='selYear'>
<option value='all'>ALL YEARS</option>
<option>2018</option>
<option>2019</option>
</select>
$('#selYear').on('change' function(){
let a = $(this).val();
$.post('articles-pro.php', {fn: 'sel_year', args: [a]}, function(data){
console.log(data);
});
});
articles-pro.php
function sel_year($a)
{ global $db;
$sql = "select id, date from arts where date like :adate order by date desc";
$st = $db->prepare($sql);
$st->execute([
":adate" => $a . "%"
]);
...rest of code
}
This works if user selects a year from selYear dropdown.
If all is selected - problem is because there is no such a value in date column.
Of course, I can write a separate function on php side, but it would be better to share the same function (sel_year).
How to do this?
Simply create an IF statement for if $a == "all".
//default query
$sql = "SELECT id, date FROM arts WHERE date LIKE :adate ORDER BY date DESC";
//default params
$params = [":adate" => $a . "%"];
//check if input is "all"
if($a == "all") {
//overwrite default query if $a == "all"
$sql = "SELECT id, date FROM arts ORDER BY date DESC";
//overwrite default params
$params = [];
}
$st = $db->prepare($sql);
$st->execute($params);
//...rest of code
My shorter solution, inspired by https://stackoverflow.com/a/54204013/5827005 (Using Ternaries)
//set default values
$sql = 'SELECT id, date FROM arts WHERE date LIKE :adate ORDER BY date DESC';
$params = [':adate' => "$a%"];
//check if $a === 'all', if it is, change $sql and $params, if it's not, leave defaults
$sql = $a === 'all' ? 'SELECT id, date FROM arts ORDER BY date DESC' : $sql;
$params = $a === 'all' ? [] : $params;
$st = $db->prepare($sql);
$st->execute($params);
This solution is shorter, but honestly I don't think this matters as much as readability/maintainability, so I would probably still use the first solution. I also doubt you'll see much if any performance difference in these, but if I had to guess, the first solution may be slightly more efficient because you don't have to check if $a == "all" multiple times, and I'm not sure if ternaries are more efficient or not.
You can check the value of $a in your function:
$sql = 'SELECT `id`, `date` FROM `arts` '; # select is the same either case
$orderBy = 'ORDER BY `date` DESC;'; # as is order by
$where = ($a === 'all' ? 'WHERE `date` LIKE :adate' : ''); # ternary to see if we need a where
$params = ($a === 'all' ? [] : [':adate' => $a. '%']); # same applies to params
$stmt = $db->prepare($sql. $where .$orderBy); # and exec
$stmt->execute($params);
You could either write an if statement in the function sel_year which checks the value of $a. If that value is all you can give the $db->prepare a separate SQL string without checking for the date, effectively returning all dates.

Decimal Database to JSON

I have Decimal data type in my database with value 0.00 but in JSON result is .00, How I can convert so i can still get 0.00 in result ?
I working in Jquery.. Thanks
This my code
<?php
include "../../../config/config.php";
$kd_entitas=$_POST['kd_entitas'];
$tglAwal = $_POST['tglAwal'];
$tglAkhir = $_POST['tglAkhir'];
$con = sqlsrv_connect(serverNameAST,$connectionInfoAST) or die('Unable to Connect');
if( $con === false )
{
echo "Could not connect.\n";
die( print_r( sqlsrv_errors(), true));
}
else{
//$sql = "SELECT SELECT #rownum := #rownum + 1 AS urutan, t.* FROM SYS_DEPT t, (SELECT #rownum := 0) r";
$sql="[Daily_report_r] '$kd_entitas','$kd_entitas','$tglAwal','$tglAkhir'";
$result = sqlsrv_query($con, $sql, array(), array( "Scrollable" => 'static' ));
$data = array();
while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC))
{
$data[] = $row;
}
$datax = array('data' => $data);
echo json_encode($datax);
}
?>
Result JSON in field oustand
Result from my database sql server
You have two problems here:
When you're getting the data from database all values will be strings. If you want a specific number to be a double then you have to explicitly cast it to a double.
If you want to preserve zero fraction in json you have to use JSON_PRESERVE_ZERO_FRACTION flag in json_encode. See http://php.net/manual/en/function.json-encode.php for details.
But this solution will preserve only one zero and will only work on numbers of type double. If you want to have more zeros after coma you have to leave the number in the string and handle yourself.
If the number from the database is returned without the fraction part then check your field type or field precision.

Display table records order by time in descending

I am displaying table records with below code.The records are displaying but not in proper order(asc/desc).
// storing request (ie, get/post) global array to a variable
$requestData= $_REQUEST;
$columns = array(
// datatable column index => database column name
0 =>'***',
1 => '***',
2=> '***',
3=> 'time',
4=> '***'
);
// getting total number records without any search
$sql = "SELECT * ";
$sql.=" FROM details where account_id=".$_SESSION['admin_id'];
$query=mysqli_query($conn, $sql) or die("server_response.php: get details");
$totalData = mysqli_num_rows($query);
$totalFiltered = $totalData; // when there is no search parameter then total number rows = total number filtered rows.
$sql = "SELECT * ";
$sql.=" FROM details where account_id=".$_SESSION['admin_id'];
if( !empty($requestData['search']['value']) ) { // if there is a search parameter, $requestData['search']['value'] contains search parameter
$sql.=" AND ( *** LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR *** LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR *** LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR time LIKE '".$requestData['search']['value']."%' ";
$sql.=" OR *** LIKE '".$requestData['search']['value']."%' )";
}
$query=mysqli_query($conn, $sql) or die("server_response.php: get details");
$totalFiltered = mysqli_num_rows($query); // when there is a search parameter then we have to modify total number filtered rows as per search result.
$sql.=" ORDER BY ". $columns[$requestData['order'][0]['column']]." ".$requestData['order'][0]['dir']." LIMIT ".$requestData['start']." ,".$requestData['length']." ";
/* $requestData['order'][0]['column'] contains colmun index, $requestData['dir'][0]['order'] contains order such as asc/desc */
$query=mysqli_query($conn, $sql) or die("server_response.php: get details");
$data = array();
while( $row=mysqli_fetch_array($query) ) { // preparing an array
$nestedData=array();
$nestedData[] = $row[""];
$nestedData[] = $row[""];
$nestedData[] = $row[""];
$nestedData[] = $row["time"];
$nestedData[] = $row[""];
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval( $requestData['draw'] ), // for every request/draw by clientside , they send a number as a parameter, when they recieve a response/data they first check the draw number, so we are sending same number in draw.
"recordsTotal" => intval( $totalData ), // total number of records
"recordsFiltered" => intval( $totalFiltered ), // total number of records after searching, if there is no searching then totalFiltered = totalData
"data" => $data // total data array
);
echo json_encode($json_data); // send data as json format
?>
I need to display records in descending order by time. How can I Sort the record to descending order?
Try to write mysql query to order by time as descending
SELECT something , something FROM mytable ORDER BY time DESC;
Try with this in your PHP It will be helpfull to you
$json = '[{"date": "2011-08-07", "name": "bob"},{"date": "2011-07-07", "name": "jones"},{"date": "2011-09-03", "name": "blair"},{"date": "2009-01-01", "name": "test"}]';
$arr = json_decode($json, true);
echo 'Before Sorting <br>';
print_r($arr);
function cmp($a, $b)
{
return strcmp($a['date'], $b['date']);
}
usort($arr, "cmp");
echo "<br><br> After Sorting <br>";
print_r($arr);

How to add items from a foreach loop into a string with json_encode() in PHP?

I'm trying to insert into a string all emails retrieved from the database, so I can use javascript to check if the email typed by the user into a form field is already registered. I'm trying to use json_encode().
$conectar = mysqli_connect(HOST, USER, PASS, DATABASE);
$listarCorreos = " SELECT userEmail
FROM usuarios
";
$resultado = mysqli_query($conectar,$listarCorreos);
$arrayEmails = mysqli_fetch_array($resultado);
foreach($arrayEmails as $row){
$emails[]=array($row['userEmail']);
}
echo json_encode($emails);
Now, I'm getting this error:
Warning: Illegal string offset 'userEmail' in /home/verificarEmail.php
on line 21
Line 21 is $emails[]=array($row['userEmail']);
What Am I doing wrong?
UPDATE:
I'm also trying:
$resultado = mysqli_query($conectar,$listarCorreos);
$emails = array();
while($row = mysql_fetch_assoc($resultado)) {
$emails[] = $row;
}
echo json_encode($emails);
And I get this error:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource,
object given in /home/verificarEmail.php on line 18
Line 18: while($row = mysql_fetch_assoc($resultado)) {
Use MYSQLI_ASSOC like below
$conectar = mysqli_connect(HOST, USER, PASS, DATABASE);
$listarCorreos = " SELECT userEmail
FROM usuarios
";
$resultado = mysqli_query($conectar,$listarCorreos);
while ( $row = mysqli_fetch_array($resultado, MYSQLI_ASSOC) ) {
$emails[]=array($row['userEmail']);
}
echo json_encode($emails);
There are a few problems there. To get your emails in an array do:
$resultado = mysqli_query($conectar,$listarCorreos);
if(!resultado) die($mysqli_error($conectar));//check for errors
$emails = mysqli_fetch_all($resultado);//fetch all results
echo json_encode($emails);
That should get your code working or show you the error. However, please don't do this.
so I can use javascript to check if the email typed by the user into a
form field is already registered
This is a terrible idea security wise because it will expose all your users' emails to people who are not even registered to your site. You should instead look up the desired username in the DB directly. If it's not there, then it hasn't been registered before. The Javascript side should only get a available or not available response.
The process (pseudo-code):
SELECT userEmail from usarios WHERE userEmail = ? ? is email to look for
execute query and capture $resultado
If $resultado is false, die(mysqli_error($conectar)) to show error
if mysqli_num_rows($resultado) === 0 email is available; else not available
Echo available or not available to Javascript
use the code like below
$conectar = mysqli_connect(HOST, USER, PASS, DATABASE);
$listarCorreos = " SELECT userEmail
FROM usuarios
";
$resultado = mysqli_query($conectar,$listarCorreos);
while ( $row = mysqli_fetch_array($resultado) ) {
$emails[]=$row['userEmail'];
}
echo json_encode($emails);
use the code like below
$conectar = mysqli_connect(HOST, USER, PASS, DATABASE);
$listarCorreos = " SELECT userEmail
FROM usuarios
";
$resultado = mysqli_query($conectar,$listarCorreos);
while ( $row = mysqli_fetch_array($resultado) ) {
$emails[]=$row['userEmail '];
}
echo json_encode($emails);

Count query in php

I would like to seek some help with my query problem in php...I want to do is count all (atic) with the same number and if the specific (atic) is equal to 7 my Insert query will execute to that (atic).
The problem is my count query wont work as i wanted....and execute my insert query to all aic even the count is not = 7.
current code:
<?php
mysql_connect("localhost","root","") or die("cant connect!");
mysql_select_db("klayton") or die("cant find database!");
$total = NULL;
$count = "SELECT count(t.atic) as '$total', t2.name FROM app_interview as t, tb_applicants as t2 WHERE t.atic = t2.aic GROUP BY t.atic";
$query = mysql_query($count) or die (mysql_error());
while($rows =mysql_fetch_array($query)){
if($query = 7){
mysql_query("INSERT INTO afnup_worksheet (faic,fnl_name,interview,fregion,ftown,funiq_id,fposition,fsalary_grade,fsalary,dateinputed) SELECT DISTINCT atic, atname,(SELECT sum(inttotal) FROM app_interview t2 WHERE t2.atic = t.atic)/7, region, town, uniq_id, position, salary_grade, salary, CURRENT_TIMESTAMP FROM app_interview t GROUP BY atname HAVING COUNT(DISTINCT atic)");
}
}
?>
$query = 7 means you are assigning value 7 to variable $query
In order to compare you have to use double equal sign ==
or triple equal signs === for same data type.
if($query = 7)
means you assign $query is 7 and it will always true and always executed, you can try this
if( $query == 7 )
That means if $query value is equal to 7 or not

Categories

Resources