I have a datatable that is displaying 6 total columns of data from my database. The 7th column is a "+" button that expands down and displays a further 7 pieces of data about that specific entry. I am also using Codeigniter for my framework. Originally I was using colspan to make the row hidden and squeeze down, and found out that was a no-no, so I looked into Datatables child rows here: https://datatables.net/examples/api/row_details.html but it appears that the data needs to be there after the generation of the table.
I have the HTML/PHP to generate the table and populate it with data now. The data is sent from my model to controller and to this view:
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover" id="dataTables-listlg">
<thead>
<th>ItemID</th>
<th>Name</th>
<th>Quantity</th>
<th>Identified?</th>
<th>Item Type</th>
<th>Unique ID</th>
<th>Details</th>
</thead>
<tbody>
<?php foreach ($storage_items as $storageItem) { ?>
<tr>
<td><?php echo $storageItem['nameid']; ?></td>
<td><?php echo $storageItem['name']; ?></td>
<td><?php echo $storageItem['amount']; ?></td>
<td><?php echo $storageItem['identify']; ?></td>
<td><?php echo $item_types[$storageItem['type']]; ?></td>
<td><?php echo $storageItem['unique_id']; ?></td>
<td><center><a data-toggle="collapse" data-parent="#accordion" href="#storagedetails<?php echo $storageItem['id']; ?>"><button type="button" class="btn btn-primary btn-circle btn-sm"><i class="fa fa-plus"></i></button></a></center></td>
<td>
<?php echo form_open('/account/edititem', array('class' => 'form-inline'), array('id' => $storageItem['id'], 'item_loc' => "inventory", 'acctid' => $acct_data->account_id)); ?>
</td>
</tr>
<tr>
<td colspan="8" class="hiddenRow">
<div id="storagedetails<?php echo $storageItem['id']; ?>" class="panel-collapse collapse">
<div class="panel-body">
<div class="row">
<div class="col-xs-2">
<strong>Refine level:</strong> <input type="number" name="refine" class="form-control" value="<?php echo $storageItem['refine']; ?>" <?php if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "readonly"; } ?> />
</div>
<div class="col-xs-2">
<strong>Broken?:</strong> <input type="checkbox" name="attribute" class="form-control" value="1" <?php if ($storageItem['attribute'] == 1) { echo "checked"; } if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "disabled"; } ?> />
</div>
<div class="col-xs-2">
<strong>Bound?:</strong> <input type="checkbox" name="bound" class="form-control" value="1" <?php if ($storageItem['bound'] == 1) { echo "checked"; } ?> />
</div>
</div>
<br />
<div class="row">
<div class="col-xs-2">
<strong>Card 1:</strong> <input type="number" name="card0" class="form-control" value="<?php echo $storageItem['card0']; ?>" <?php if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "readonly"; } ?> /></br>
</div>
<div class="col-xs-2">
<strong>Card 2:</strong> <input type="number" name="card1" class="form-control" value="<?php echo $storageItem['card1']; ?>" <?php if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "readonly"; } ?> /></br>
</div>
<div class="col-xs-2">
<strong>Card 3:</strong> <input type="number" name="card2" class="form-control" value="<?php echo $storageItem['card2']; ?>" <?php if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "readonly"; } ?> /></br>
</div>
<div class="col-xs-2">
<strong>Card 4:</strong> <input type="number" name="card3" class="form-control" value="<?php echo $storageItem['card3']; ?>" <?php if ($storageItem['type'] != 4 && $storageItem['type'] != 5) { echo "readonly"; } ?> /></br>
</div>
</div>
<?php echo form_close(); ?>
</div>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
The javascript I'm using now to make the table is:
<script>
$(document).ready(function() {
$('#dataTables-listlg').DataTable({
"responsive": true,
"lengthMenu": [ [25, 50, 100, -1], [25, 50, 100, "All"] ],
"searching": false,
"defaultContent": "",
});
});
</script>
Where the <td colspan="8" class="hiddenRow"> is, is where I want to make the child row drop down (UNDER the entry showing the additional information). I've seen the example but I have no idea how to get my data into the proper format to put it into the datatable and where it should go. Here is the controller with the relevant part:
$data['storage_items'] = $this->accountmodel->get_storage_items($aid);
$this->load->view('account/details',$data);
$this->load->view('footer'); // Where the javascript is above
And the model:
function get_storage_items($aid) {
$this->db->select('*');
$this->db->from('storage')->order_by('storage.id', 'asc');
$this->db->where('storage.account_id', $aid); // This is just sorting out the results from that specific account
$q = $this->db->get();
return $q->result_array();
}
It looks like I need to get my array of results from my model into json/ajax but have no idea how I'd get this all the way to my footer AFTER the table is generated. Any help you can provide would be appreciated.
---Edit--- After looking over the answer below and mulling over thoughts, I have changed things to the following. Here is the complete view from foreach loop to the end, including the Javascript to put stuff in the 'content' array:
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover display" id="dataTables-listlg">
<thead>
<th>ItemID</th>
<th>Name</th>
<th>Quantity</th>
<th>Identified?</th>
<th>Item Type</th>
<th>Unique ID</th>
<th>Details</th>
<th>Options</th>
</thead>
<tbody>
<?php foreach ($storage_items as $storageItem) { ?>
<tr>
<td><?php echo $storageItem['nameid']; ?></td>
<td><?php echo $storageItem['name']; ?></td>
<td><?php echo $storageItem['amount']; ?></td>
<td><?php echo $storageItem['identify']; ?></td>
<td><?php echo $item_types[$storageItem['type']]; ?></td>
<td><?php echo $storageItem['unique_id']; ?></td>
<td class="details-control"></td>
<td>
<button type="submit" class="btn btn-success btn-sm <?php if ($check_perm['editstorageitem'] == 0) { echo "disabled"; } ?>" >Edit</button>
<button type="button" class="btn btn-danger btn-sm <?php if ($check_perm['editstorageitem'] == 0) { echo "disabled"; } ?>">Delete</button>
</td>
</tr>
<script>
var content = [];
content[<?php echo $storageItem["id"]; ?>] = '"'<?php echo form_open("/account/edititem", array("class" => "form-inline"), array("id" => $storageItem["id"], "item_loc" => "inventory", "acctid" => $acct_data->account_id)); ?> \
<div class="panel-body"> \
<div class="row"> \
<div class="col-xs-2"> \
<strong>Refine level:</strong> <input type="number" name="refine" class="form-control" value="<?php echo $storageItem["refine"]; ?>" <?php if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "readonly"; } ?> /> \
</div> \
<div class="col-xs-2"> \
<strong>Broken?:</strong> <input type="checkbox" name="attribute" class="form-control" value="1" <?php if ($storageItem["attribute"] == 1) { echo "checked"; } if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "disabled"; } ?> /> \
</div> \
<div class="col-xs-2"> \
<strong>Bound?:</strong> <input type="checkbox" name="bound" class="form-control" value="1" <?php if ($storageItem["bound"] == 1) { echo "checked"; } ?> /> \
</div> \
</div> \
<br /> \
<div class="row"> \
<div class="col-xs-2"> \
<strong>Card 1:</strong> <input type="number" name="card0" class="form-control" value="<?php echo $storageItem["card0"]; ?>" <?php if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "readonly"; } ?> /></br> \
</div> \
<div class="col-xs-2"> \
<strong>Card 2:</strong> <input type="number" name="card1" class="form-control" value="<?php echo $storageItem["card1"]; ?>" <?php if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "readonly"; } ?> /></br> \
</div> \
<div class="col-xs-2"> \
<strong>Card 3:</strong> <input type="number" name="card2" class="form-control" value="<?php echo $storageItem["card2"]; ?>" <?php if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "readonly"; } ?> /></br> \
</div> \
<div class="col-xs-2"> \
'<strong>Card 4:</strong> <input type="number" name="card3" class="form-control" value="<?php echo $storageItem["card3"]; ?>" <?php if ($storageItem["type"] != 4 && $storageItem["type"] != 5) { echo "readonly"; } ?> /></br> \
</div> \
</div> \
<?php echo form_close(); ?> \
</div>'"';
</script>
<tr item_id="<?php echo $storageItem['id']; ?>">
</tr>
<?php } ?>
</tbody>
</table>
</div>
and my javascript in the footer looks like this now:
<script>
$(document).ready(function() {
var table = $('#dataTables-listlg').DataTable({
"responsive": true,
"lengthMenu": [ [25, 50, 100, -1], [25, 50, 100, "All"] ],
"searching": false,
"defaultContent": "",
});
// Add event listener for opening and closing details
$('#dataTables-listlg tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child(content[tr.attr('item_id')]).show();
tr.addClass('shown');
}
});
});
</script>
In fact, the 'unique_id' in this table is not as "unique" as I thought (I didn't design it, just writing the backend for it). There is however a unique key on the table 'id', so that's what I'm using to make sure I get the right value.
This however is not working. I am getting an error in the console:
SyntaxError: missing ; before statement - appears on the line that starts content[<?php echo $storageItem["id"]; ?>] =... in each iteration of the foreach
I'm also getting the error from the webpage warning about DataTables: DataTables warning: table id=dataTables-listlg - Requested unknown parameter '0' for row 1. For more information about this error, please see http://datatables.net/tn/4
Additionally, the child row doesn't drop down. Did I misunderstand or make a silly mistake?