Datatables add multiple child-rows - javascript

I have a table hooked up to the jQuery datatable. Based on this example I want to add "hidden" child rows to show extra information.
I have the following jsfiddle where I have a name/value pair.
<tr data-child-name="Name1" data-child-value="Value 1">
<td class="details-control"></td>
function format ( name, value ) {
return '<div>' + name + ': '+ value + '</div>';
}
$(document).ready(function () {
var table = $('#example').DataTable({});
// Add event listener for opening and closing details
$('#example').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( format(tr.data('child-name'), tr.data('child-value') )).show();
tr.addClass('shown');
}
});
});
My question is how do I add more than one name/value pair? So that I can define various rows like in the datatables.net example.
My source is a php-script that generates html like in the jsfiddle example.
It's probably an easy task but my jQuery skills are very limited :-)
Thank you.
UPDATE:
The data comes from an ldap query:
$ldapResults[$i]
echo "<td>" . utf8_encode($ldapResults[$i]['sn'][0]) . "</td>"

If you want to keep data attributes for your data source, you can do something like this
function format ( dataSource ) {
var html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
for (var key in dataSource){
html += '<tr>'+
'<td>' + key +'</td>'+
'<td>' + dataSource[key] +'</td>'+
'</tr>';
}
return html += '</table>';
}
$(function () {
var table = $('#example').DataTable({});
// Add event listener for opening and closing details
$('#example').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(format({
'Key 1' : tr.data('key-1'),
'Key 2' : tr.data('key-2')
})).show();
tr.addClass('shown');
}
});
});
td.details-control {
background: url('http://www.datatables.net/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('http://www.datatables.net/examples/resources/details_close.png') no-repeat center center;
}
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://cdn.datatables.net/responsive/1.0.1/js/dataTables.responsive.min.js"></script>
<script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css" />
<table id="example" class="display nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th>Item 1</th>
<th>Item 2</th>
<th>Item 3</th>
<th>Item 4</th>
</tr>
</thead>
<tbody>
<tr data-key-1="Value 1" data-key-2="Value 2">
<td class="details-control"></td>
<td>data 1a</td>
<td>data 1b</td>
<td>data 1c</td>
<td>data 1d</td>
</tr>
<tr data-key-1="Value 1" data-key-2="Value 2">
<td class="details-control"></td>
<td>data 2a</td>
<td>data 2b</td>
<td>data 2c</td>
<td>data 2d</td>
</tr>
</tbody>
</table>

You can create an array of the data you need to show for each row
EG :
var data = [
{ key1 :'value1', key2 :'value2', key3 :'value3'}, //Row1
{ key1 :'value1', key2 :'value2'} //Row2
];
And updated the format()
function format (index ) {
var json_data = data[parseInt(index)];
var op = '';
$.each(json_data, function(key, value){
op +='<div>' + key + ': '+ value + '</div>';
});
return op;
}
Now just add the index of the array in a custom attribute <tr data-child-index="1">
And finally row.child(format(tr.data('child-index'))).show();
EDIT : No html changes needed.
Calculate the index dynamically using jQuery index()
row.child(format($('#example td.details-control').index($(this)))).show();
DEMO

If are are getting json data to show as child then try it like,
else {
// Open this row
// pass your json data to show in details
row.child( format(myJsonData)).show();
tr.addClass('shown');
}
And in the format function change it like,
function format ( json ) {
var $json=$.parseJSON(json);// if not parsed
var str='';
$json.each(function(key,value){
str += '<div>'+key+':'+value+'</div>';
});
return str;
}

Related

How do I make a button that, when clicked, displays data in node.js?

So I've created a button, along with a table that shows data from my database. However, I want that data to appear only when the button is clicked. So when the button is clicked, I want a random row from a specific table I have in my database appear.
`<button id="breakfast2">Breakfast</button>
<table id="mealTableContainer2">
<thead>
<tr>
<th id="mealname">Meal Name</th>
<th id="mealcalories">Calories</th>
<th id="mealtype">Type of Meal</th>
</tr>
</thead>
<tbody id="mealContainer2"></tbody>
</table>`
The only Javascript I currently have is for getting my database into that table, but I really only want it to appear when I click the breakfast button. I just can't figure out how; if someone could explain it to me very simply, I'd be appreciate it a ton!
console.log('Data2 received')
$.ajax({
url: 'http://localhost:5000' + "/read-recordsrandom",
type: 'get',
success: function(response) {
var data2 = JSON.parse(response);
if(data2.msg === "SUCCESS"){
console.log(data2.meal)
createMealTable2(data2.meal);
} else {
console.log(data2.msg);
}
},
error: function(err){
alert(err);
}
});
}
function createMealTable2(data2) {
var tableHTML2 = " ";
console.log("Test");
for(var i=0; i < data2.length; i++){
tableHTML2 += "<tr>";
tableHTML2 += "<td>" + data2[i].mealname + "</td>";
tableHTML2 += "<td>" + data2[i].mealcalories + "</td>"
tableHTML2 += "<td>" + data2[i].mealtype + "</td>";
tableHTML2 += "</tr>";
}
$('#mealContainer2').html(tableHTML2);
}
Hide it initially then display it
document.getElementById("breakfast2")
.addEventListener('click', function(event) {
document.getElementById("mealTableContainer2").classList.remove('hidden');
});
.hidden {
display: none;
}
<button id="breakfast2">Breakfast</button>
<table id="mealTableContainer2" class="hidden">
<thead>
<tr>
<th id="mealname">Meal Name</th>
<th id="mealcalories">Calories</th>
<th id="mealtype">Type of Meal</th>
</tr>
</thead>
<tbody id="mealContainer2"></tbody>
</table>
If I'm right, by default, the table is supposed to be hide. So you can first of all, hide the table with css
Change this line to hide the table
<table id="mealTableContainer2" style="display: none;">
After that, you will need to add event listener on the button "breakfast" in javascript to display the table on click
document.getElementById("breakfast2").addEventListener("click", function() {
document.getElementById("mealTableContainer2").style.display = "block";
});
Here is how you can ajax on click
NOTE: the `` are backticks used in template literal delimites and MUST be backticks
$(function() {
const createMealTable2 = data => {
$('#mealContainer2')
.html(data.map(meal => `<tr>
<td>${meal.mealname}</td>
<td>${meal.mealcalories}</td>
<td>${meal.mealtype}</td>
</tr>`)
.join("")
)
};
$("#breakfast2").on("click", function() {
$.ajax({
url: 'http://localhost:5000' + "/read-recordsrandom",
type: 'get',
success: function(response) {
var data2 = JSON.parse(response);
if (data2.msg === "SUCCESS") {
createMealTable2(data2.meal);
} else {
console.log(data2.msg);
}
},
error: function(err) {
alert(err);
}
});
})
})
<button type="button" id="breakfast2">Breakfast</button>
<table id="mealTableContainer2">
<thead>
<tr>
<th id="mealname">Meal Name</th>
<th id="mealcalories">Calories</th>
<th id="mealtype">Type of Meal</th>
</tr>
</thead>
<tbody id="mealContainer2"></tbody>
</table>
You need an event listener that listen for a click and than do the call to your database with asynchronous function. After the answer is returned just put it on the page using createElement or inner text of already existing html element.

Datatable row : manually update field

I have a datatable. I get a set of selected rows.
When i loop through, and update the value of a field remark,
I can't do it.
how do i manually update the value of a specific field in a row?
var table = $('#bankReconDataListing').DataTable();
$.map(table.rows('.selectedrow').data(), function (item) {
item.remarks = 'updated values';
console.log('-----------------1>',item);
});
<table id="bankReconDataListing">
<thead>
<tr>
<td>head</td>
<td>gender</td>
</tr>
</thead>
<tbody>
<tr><td>one</td><td>boy</td></tr>
<tr class="selectedrow"><td>two</td><td>boys</td></tr>
<tr><td>three</td>
<td>boys</td></tr>
</tbody>
</table>
var table = $('#bankReconDataListing').DataTable();
var temp = table.row(2).data();
alert("value before update = " + temp[0]);
temp[0] = "six";
table.row(2).data(temp).draw();
alert("value after update = " + temp[0]);

Child row datatables - row data value undefined

I have a datatable with child rows populated by the following function:
$('#myDataTable tbody').on('click', 'td.details-control', function () {
console.log(table.row(this).data());
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(format(row.data())).show();
tr.addClass('shown');
}
});
The format function:
function format(d) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>'+
'<td><strong>BLABLA1</td>' +
'<td align="center">'+
d.BLABLA1 +
'</td>'+
'<td><strong>BLABLA2</td>' +
'<td align="center">'+
d.BLABLA2+
'</td>'+
'</tr>' +
'</table>';
}
However, when I display the page, and I expand the child rows, the values of the columns are "undefined"...
The rows in the datatable are populated from a model (Using MVC 4) as follows:
<tbody>
#foreach (var item in Model)
{
<tr>
<td align="center">
#Html.DisplayFor(modelItem => item.BLABLA3)
</td>
.....</tr>}
</tbody>
I think I am missing the method to get the row.data() loaded into the formatting function.... What is the correct way of doing so? I already checked all the documentations and they all use what I tried....
Yes, it's strange the page https://datatables.net/examples/api/row_details.html explain that we have to write :
'<td>'+d.myrow+'</td>'+
But if i do this, row's value is "undefined", so i have to write :
'<td>'+d["myrow"]+'</td>'+
And it's works !
Apparently I had to select the index of the object/array returned by .data() for every row, the following code worked for me.....(replace KNOWN_INDEX by integer index of the child row...)
<tr>'+
'<td><strong>BLABLA1</td>' +
'<td align="center">'+
d[KNOWN_INDEX]+
'</td>'+
.
.
.
'</tr>'+

Get selected drop-down value of a row in html table using JavaScript/jQuery

I have a html table with 4 columns and multiple rows
column1 : simple text
column2 : simple text
column3 : select list with 2 values
column4 : Button that performs some operation
At run time, I want to get the selected / entered values for all the columns of that row against which column4 button is clicked. I know a little of JavaScript/jQuery.
Here is the static table code
<table id="invoiceTbl" border="1">
<thead>
<tr>
<th>Broker info</th>
<th>Receivable Amount</th>
<<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
And I am populating table i.e. inserting data on AJAX call like this:
$.ajax({
type: "POST",
data: $('#searchDetails').serialize(),
async: false,
cache: false,
url: "/opsadmin/search.json",
dataType: 'json',
success: function (result) {
var i = 1;
$.each(result, function (index, value) {
alert(index + ": " + value.brokerInfo);
$('table#invoiceTbl TBODY').append('<tr> <td>' + i + '</td><td>' + value.brokerInfo + '</td><td>' + value.receivableAmount + '</td><td><select name="act" id="s"><option>PENDING</option><option>CLEARED</option></select></td><td><input type="button" value="Process" onclick="updateStatus(\'' + index + '\')"</input></td></tr>');
i++;
});
}
});
return false;
First set the unique ID to each of your "select" with help of index like:
'<select name="act" id="s'+ index +'">'
and pass the index with "updateStatus(index)" function call.
function updateStatus(index) {
$('#s'+index).val(); // value of selected box.
}
$("#invoiceTbl input[type=button]").click(function(e){
$(e.target).closest("tr").find("td").slice(0,2).each(function(){
console.log($(this).text());
});
});
On #button click you will get an array (arr) that holds the values of the clicked row cells:
$('#button').on('click', function() {
var arr = [];
$(this).closest('tr').find('td').each(function() {
var that = $(this);
if (that.find('input[type="text"]').length > 0) {
arr.push(that.find('input[type="text"]').val());
} else if (that.find('select').length > 0) {
arr.push(that.find('select').val());
} else {
arr.push(that.text());
}
});
alert(arr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>text</td>
<td>text2</td>
<td>
<select>
<option value="opt1">opt1</option>
<option value="opt2">opt2</option>
<option value="opt3">opt3</option>
</select>
</td>
<td><button id="button">Click</button></td>
</tr>
</tbody>
</table>
There's already a few good answers, but my solution is a bit different:
$("#invoiceTbl tr").each(function(){
var select = $(this).find("select");
var button = $(this).find("button");
button.click(function(){
alert(select.val());
});
});
If you also want the content of the other columns, that's a bit more difficult:
$("#invoiceTbl tr").each(function(){
var tr = $(this);
var button = $(this).find("button");
button.click(function(){
tr.find("td").each(function(){
var select = $(this).find("select");
var td_button = $(this).find("button");
if(!td_button.length)
{
if(select.length)
console.log(select.val());
else
console.log($(this).text());
}
});
});
});
Check out https://jsfiddle.net/cgfjewoe/ to see it run.

How to add tr (row) with dynamic td (column) to table?

I have a question about dynamic tr with keep the content of td.
I have a table like flowing code:
<table id="map2">
<tr>
<td class="15c">15</td>
<td class="16c">16</td>
<td class="17c">17</td>
</tr>
<tr>
<td class="15c">15</td>
<td class="16c">16</td>
<td class="17c">17</td>
</tr>
</table>
I added some jQuery code that create a column dynamically. Like flowing code:
$('#map2').on('mouseenter', 'td:last-child', function(){
var tdClass = $(this).attr('class');
var newClass = parseInt(tdClass);
if(newClass <= 30) {
$(this).after('<td class="'+ (newClass+1) +'c">'+ (newClass+1) +'</td><td class="'+ (newClass+2) +'c">'+ (newClass+2) +'</td><td class="'+ (newClass+3) +'c">'+ (newClass+3) +'</td>');
} else {
alert('end!')
}
});
$('#map2').on('mouseenter', 'td:first-child', function(){
var tdClass = $(this).attr('class');
var newClass = parseInt(tdClass);
if(newClass >= 3) {
$(this).before('<td class="'+ (newClass-3) +'c">'+ (newClass-3) +'</td><td class="'+ (newClass-2) +'c">'+ (newClass-2) +'</td><td class="'+ (newClass-1) +'c">'+ (newClass-1) +'</td>');
} else {
alert('end!')
}
});
That code create a td for me, now I want to create a tr (row) with keep the content. For example when the new row was created, that had content like before td in before tr.
I tried some code like this:
$('#map2').on('mouseenter', 'tr:first-child', function(){
var trCont = $(this).html;
// $(this).before('<tr>'+ trCont +'</tr>');
$(this).before('<tr><td>new row</td></tr>');
});
but didn't work.
How can I solve this problem?
http://jsfiddle.net/H6MSS/2/

Categories

Resources