2

I'm using this CRUD tutorial https://www.webslesson.info/2017/01/php-pdo-ajax-crud-with-data-tables-and-bootstrap-modals.html to make some tests and i would like to improve it including 2 columns related to another tables on MySql.

I'm working with those tutorial files below:

  1. One php file that fetch data to display on DataTables (fetch.php);
  2. One index.php file;
  3. One table that call "Users" and it has 4 columns:
Users table
-------------------------------------
id | first_name | last_name | image

I created 2 tables to relate with "Users" table. Are they:

  1. "type_service" table with columns ("typeID" and "type") and
  2. "categories" table with columns ("categoryID" and "category").

On "users" table i included 2 columns that call "type_fk" and "category_fk" where "fk" is foreign key:

Users table
----------------------------------
id | first_name | last_name | image | type_fk | category_fk 

When columns were created they were related to "users" table where relationships works perfectly.

After this i included an INNER JOIN query in fetch.php file like below:

$query .= "SELECT users.*, type_service.type, categories.category
FROM users
INNER JOIN type_service ON users.type_fk = type_service.typeID
INNER JOIN categories ON users.category_fk = categories.categoryID ";

Fetch.php file:

<?php
include('db.php');
include('function.php');
$query = '';
$output = array();

    $query .= "SELECT users.*, type_service.type, categories.category 
    FROM users 
    INNER JOIN type_service ON users.type_fk = type_service.typeID
    INNER JOIN categories ON users.category_fk = catgories.categoryID

 ";

if(isset($_POST["search"]["value"]))
{
 $query .= 'WHERE first_name LIKE "%'.$_POST["search"]["value"].'%" ';
 $query .= 'OR last_name LIKE "%'.$_POST["search"]["value"].'%" ';
}
if(isset($_POST["order"]))
{
 $query .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';
}
else
{
 $query .= 'ORDER BY id DESC ';
}
if($_POST["length"] != -1)
{
 $query .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$statement = $connection->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
$data = array();
$filtered_rows = $statement->rowCount();
foreach($result as $row)
{
 $image = '';
 if($row["image"] != '')
 {
  $image = '<img src="upload/'.$row["image"].'" class="img-thumbnail" width="50" height="35" />';
 }
 else
 {
  $image = '';
 }
 $sub_array = array();
 $sub_array[] = $image;
 $sub_array[] = $row["first_name"];
 $sub_array[] = $row["last_name"];
 $sub_array[] = $row["type"];
 $sub_array[] = $row["category"];
 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
 $data[] = $sub_array;
}
$output = array(
 "draw"    => intval($_POST["draw"]),
 "recordsTotal"  =>  $filtered_rows,
 "recordsFiltered" => get_total_all_records(),
 "data"    => $data
);
echo json_encode($output);
?>

After included INNER JOIN query on code above, i included 2 sub_array in the same file (fetch.php) like below:

$sub_array[] = $row["type"];
$sub_array[] = $row["category"];

Where code stay like this:

 $sub_array = array();
 $sub_array[] = $image;
 $sub_array[] = $row["type"];
 $sub_array[] = $row["category"];
 $sub_array[] = $row["first_name"];
 $sub_array[] = $row["last_name"];
 $sub_array[] = '<button type="button" name="update" id="'.$row["id"].'" class="btn btn-warning btn-xs update">Update</button>';
 $sub_array[] = '<button type="button" name="delete" id="'.$row["id"].'" class="btn btn-danger btn-xs delete">Delete</button>';
 $data[] = $sub_array;

When the code above is executed, the index.php page show data through html code below:

<body>
        <div class="container box">
            <h1 align="center">PHP PDO Ajax CRUD with Data Tables and Bootstrap Modals</h1>
            <br />
            <div class="table-responsive">
                <br />
                <div align="right">
                    <button type="button" id="add_button" data-toggle="modal" data-target="#userModal" class="btn btn-info btn-lg">Add</button>
                </div>
                <br /><br />
                <table id="user_data" class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th width="10%">Image</th>
                            <th width="10%">Type</th>
                            <th width="15%">Category</th>
                            <th width="15%">First Name</th>
                            <th width="15%">Last Name</th>
                            <th width="10%">Edit</th>
                            <th width="10%">Delete</th>
                        </tr>
                    </thead>
                </table>

            </div>
        </div>
    </body>

And when i refresh index.php page, DataTable return an invalid JSON response like image below:

https://i.stack.imgur.com/pieF9.jpg

In this case if i remove the query line:

INNER JOIN categories ON users.category_fk = categories.category

The DataTable return all data but show Category column ID instead of the category name. The image below can show this:

https://i.stack.imgur.com/E2TnB.jpg

But if i reinclude:

INNER JOIN categories ON users.category_fk = categories.categoryID

DataTables display the error below again:

DataTables warning: table id=user_data - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1

What i see is when i include just one INNER JOIN query the DataTable display all data but if i include one more INNER JOIN, DataTable return an invalid JSON response even including the respective sub_arrays.

$sub_array[] = $row["type"];
$sub_array[] = $row["category"];

In this case what can i do to improve this code to show name instead of ID?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Michel Xavier
  • 133
  • 3
  • 14

1 Answers1

3

If you wanna have only 1 table you can combine type_service and categories like that

type_service_categories

id | type | name

where type is service or category and name is service_type or category name

...but this will not resolve your problem because you have to to write 2 inner join statements in the query anyway.

your error is possible to come from $result = $statement->fetchAll();

Can you post db.php? or you can try:

foreach($row as $rkey => $rvalue){
    $sub_array[] = $row[$rkey];}

to see what fields your query is returning when you call fetchAll() function or how they are fetch and return.

Or try developer option in chrome to see exactly json error.

JustAClue
  • 66
  • 3
  • Hello. My db.php is: ... ... On chrome i can see this error: ... Notice: Undefined index: draw in C:\xampp\htdocs\site\fetch.php on line 54 {"draw":0,"recordsTotal":0,"recordsFiltered":1,"data":[]} .... on line 54 there is a variable that call an output array. – Michel Xavier Feb 11 '19 at 00:39
  • try this: first: $sub_array = array(); $sub_array[] = $row["first_name"]; $sub_array[] = $row["last_name"]; $sub_array[] = $row["type"]; $sub_array[] = $row["category"]; – JustAClue Feb 11 '19 at 20:24
  • and $data=$sub_array. or you can try $data=$result; maybe you have an error on $row index keys. – JustAClue Feb 11 '19 at 20:32
  • Hello @JustAClue. Thanks for your support. I found the problem. I remove the relationships tables (type_fk and category_fk) from users table. In index.php file, it has an Ajax code that insert data into Users table. I inserted an HTML select to display options through prepared statement, so, the users table receive type and category ID'S and query INNER JOIN on fetch.php file display type and category name's instead of respectives ID's. – Michel Xavier Feb 11 '19 at 21:17