kim de castro
kim de castro

Reputation: 309

How to search word by word using this approach (datatables)?

Here's the code I'm using it only search (starts with first letter to last) not word by word. How is it possible to make it word by word(keyword)?

<?php
/* Database connection start */
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "sample";

$conn = mysqli_connect($servername, $username, $password, $dbname) or die("Connection failed: " . mysqli_connect_error());
mysqli_set_charset($conn,"utf8");
/* Database connection end */


// storing  request (ie, get/post) global array to a variable  
$requestData= $_REQUEST;


$columns = array( 
// datatable column index  => database column name
    0=> 'app_id',
    1 =>'fullname',


);

// getting total number records without any search
$sql = "SELECT app_id";
$sql.=" FROM applicants";
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$totalData = mysqli_num_rows($query);
$totalFiltered = $totalData;  // when there is no search parameter then total number rows = total number filtered rows.


$sql = "SELECT app_id, fullname";
$sql.=" FROM applicants WHERE 1=1";
if( !empty($requestData['search']['value']) ) {   // if there is a search parameter, $requestData['search']['value'] contains search parameter
    $sql.=" AND ( app_id LIKE '".$requestData['search']['value']."%' ";    
    $sql.=" OR fullname LIKE '".$requestData['search']['value']."%' ";
    $sql.=" OR contact LIKE '".$requestData['search']['value']."%' ";
    $sql.=" OR address LIKE '".$requestData['search']['value']."%' ";
    $sql.=" OR photo LIKE '".$requestData['search']['value']."%' ";
    $sql.=" OR datereg LIKE '".$requestData['search']['value']."%' )";
}
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.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. 
$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  */    
$query=mysqli_query($conn, $sql) or die("employee-grid-data1.php: get employees");
$data = array();
while( $row=mysqli_fetch_array($query) ) {  // preparing an array
    $nestedData=array(); 
    $nestedData[] = $row["app_id"];
    $nestedData[] = $row["fullname"];

    $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

?>

The problem: it'ss start to first letter to last letter not WORD by WORD. Is it possible to make it word by word?

source

Upvotes: 1

Views: 313

Answers (3)

kim de castro
kim de castro

Reputation: 309

here's the solution provided by: Gyrocode.com

    // If there is a search parameter
if( !empty($requestData['search']['value']) ) {   
    $search = mysqli_real_escape_string(
       $conn,
       // Match beginning of word boundary
       "[[:<:]]".
       // Replace space characters with regular expression
       // to match one or more space characters in the target field
       implode("[[.space.]]+",             
          preg_split("/\s+/", 
             // Quote regular expression characters
             preg_quote(trim($requestData['search']['value']))
          )
       ).
       // Match end of word boundary
       "[[:>:]]"
    );


    $sql.=" AND ( app_id REGEXP '$search' ";    
    $sql.=" OR fullname REGEXP '$search' ";
    $sql.=" OR contact REGEXP '$search' ";
    $sql.=" OR address REGEXP '$search' ";
    $sql.=" OR photo REGEXP '$search' ";
    $sql.=" OR datereg REGEXP '$search' )";
}

Upvotes: 0

Gyrocode.com
Gyrocode.com

Reputation: 58900

You can use REGEXP and the [[:<:]] and [[:>:]] word-boundary markers to match words only.

For example:

SELECT *
FROM table 
WHERE keywords REGEXP '[[:<:]]word[[:>:]]'

Also you need to escape data with mysqli_real_escape_string().

See updated code below:

// If there is a search parameter
if( !empty($requestData['search']['value']) ) {   
    $search = mysqli_real_escape_string(
       $conn,
       // Match beginning of word boundary
       "[[:<:]]".
       // Replace space characters with regular expression
       // to match one or more space characters in the target field
       implode("[[.space.]]+",             
          preg_split("/\s+/", 
             // Quote regular expression characters
             preg_quote(trim($requestData['search']['value']))
          )
       ).
       // Match end of word boundary
       "[[:>:]]"
    );


    $sql.=" AND ( app_id REGEXP '$search' ";    
    $sql.=" OR fullname REGEXP '$search' ";
    $sql.=" OR contact REGEXP '$search' ";
    $sql.=" OR address REGEXP '$search' ";
    $sql.=" OR photo REGEXP '$search' ";
    $sql.=" OR datereg REGEXP '$search' )";
}

As an alternative you may look into using full-text search.

Upvotes: 2

markpsmith
markpsmith

Reputation: 4918

If I understand you correctly - you're referring to the fact that the search is triggered by the keyup event in the search box. This javascript will allow the user to enter a word and then hit enter to perform the search.

This need to be added to the same js file that contains the datatables initialisation code, and goes AFTER the init code:

var oTable = $('#example').dataTable({
   ... yourdatatable init code

// unbind the keyup event that triggers the search 
$("#example_filter input").unbind();

// use fnFilter() to perform the search when the `Return` key is pressed
$("#example_filter input").keyup(function (e) {
     if (e.keyCode === 13) {
         oTable.fnFilter(this.value);
     }
});

This assumes datatables v1.9. If you're using 1.10 there's a SO answer here which outlines the modifications

working version -> https://jsfiddle.net/markps/HEDvf/3225/

Upvotes: 0

Related Questions