I'm using jQuery DataTables, and I am able to look at the row data and colorize the row.
Here is the code that creates the datatable:
var $dataTable = $('#example1').DataTable({
"data": data,
"dataType": "json",
"iDisplayLength": 25,
"order": [[6, "desc"]],
"scrollY": 550,
"scrollX": true,
"bDestroy": true,
"stateSave": true,
// here is the part that styles the row
"fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull)
{
if (aData[12] == "Y"){$('td', nRow).css('background-color', '#EE6363');}
if (aData[9] == "Y"){$('td', nRow).css('font-weight', 'bold');}
}
});
So if you'll notice in the code above, the 1st if statement checks if the row data of the 12th column, which is called REJECTED, is "Y". If so, make the entire row red.
The 2nd if statement checks if the row data of the 9th column, which is called URGENT, is "Y". If so, make the text for that entire row bold.
What I would like to do is make the cell for that column red instead of the whole row, primarily for the 1st row.
How can I alter my code above to achieve this?
I can't test it....
But I would try something like this :
if (aData[12] == "Y"){$('td', nRow)[12].css('background-color', '#EE6363');}
Or this tricky thing:
if (aData[12] == "Y"){$('td', nRow).parent().children()[12].css('background-color', '#EE6363');}
If zero-based:
if (aData[12] == "Y"){$('td', nRow)[11].css('background-color', '#EE6363');}
Or:
if (aData[12] == "Y"){$('td', nRow).parent().children()[11].css('background-color', '#EE6363');}
Here is the code that will color the target cell:
if (aData[12] == "Y"){$('td', nRow).eq(1).css('background-color', '#BF5FFF');}
By adding eq(1), I can target and color the 2nd cell in the datatable. This is how I got it to work.
Related
I have a table in which I can edit and modify each cell.
I would like to highlight the cell that I modified.
At the moment I can only highlight the entire row but I don't have what I want to do.
I use createdRow to make the cells editable and get the modified row.
How can I do to highlight that modified cell?
var table = $("#deploymentMap_table").DataTable({
data: constructRaws(dataSet),//tbody
paging: false,
searching: false,
info: false,
fixedHeader: true,
scrollY: false,
scrollX: false,
responsive: false,
dom: 't', //display only the table
order: [[ 0, 'asc' ]],//order by 'service' col
columnDefs:[
{
targets:'_all',
render:function(data){
if(data == null) {return ""
} else {return data;}
}
},
{ targets: [0,1], "width" : "200px"},
],
columns: constructColumns(dataSet),//thead
dom: 'Bfrtip',
// attribute classname (background color) for services
rowCallback: function(row, data, index){
if ( data.code == 1 ) {
$('td', row).each( function ( value, index ) {
if($(this).contents().first().text()){
$(this).addClass('td_colorCD');
}
} );
}
$(row).find('td:eq(0)').css('background-color', '#7f7f7f').css('color', '#fff').css('text-align', 'left');
$(row).find('td:eq(1)').css('background-color', '#7f7f7f').css('color', '#fff').css('text-align', 'left');
$.each(row.childNodes, function(i,value){
if(value.innerText == "NoUP"){
$(value).addClass('td_colorBSF');
}
else if(value.innerText){
$(value).addClass('td_color');
}
})
},
// Make all cell editable
createdRow: function(row, data, dataIndex, cells) {
console.log(cells);
let original
row.setAttribute('contenteditable', true)
row.setAttribute('spellcheck', false)
row.addEventListener('focus', function(e) {
original = e.target.textContent
})
row.addEventListener('blur', function(e) {
if (original !== e.target.textContent) {
$('td', row).removeClass();
$('td', row).addClass('td_color_change');
const r = table.row(e.target.parentElement)
r.invalidate();
var lign = e.target.innerText;
lign = lign.split('\t');
var nRow = $('#deploymentMap_table thead tr')[0].innerText;
head = nRow.split('\n\t\n');
var newAR = mergeArrayObjects(head, lign);
console.log("newAR", newAR);
$(dataSet).each(function( index, values ) {
if(newAR.service[0].Services == values.service_name){
delete values.regions;
values.regions = newAR.region;
console.log(values);
}
})
console.log("dataset", dataSet);
}
})
}
});
I think the easiest way to handle this is to replace your rowCallback with a DataTables delegated event.
Below is a simple example which would change the color of a specific cell when you leave that cell:
Step 1) The onblur event requires the cell to have a tabindex attribute. You can add this however you wish - but here is one way, in your existing code:
$.each(row.childNodes, function(i,value){
$(value).attr('tabindex', i); // this line is new
// your existing code goes here
})
Note - this could be improved as it repeats tab indexes across rows. But it illustrates the approach.
Step 2: Add a new onblur event listener, after the end of your DataTable definition:
$('#deploymentMap_table td').on('blur', function () {
this.classList.remove("td_color");
this.classList.add("td_color_change");
} );
Step 3: The above code would need to be enhanced to include your edit-checking logic, which checks for an actual cell value change.
You can get the "before" cell values using this:
table.cell( this ).data();
And the "after" cell values using this - which gets the value from the HTML table (the DOM node), not from DataTables:
table.cell( this ).node().textContent;
The updated listener would be something like this:
$('#deploymentMap_table td').on('blur', function () {
var cellValueStart = table.cell( this ).data();
var cellValueEnd = table.cell( this ).node().textContent;
//console.log( cellValueStart );
//console.log( cellValueEnd );
if (cellValueEnd !== cellValueStart) {
table.cell( this ).data(cellValueEnd);
this.classList.remove("td_color");
this.classList.add("td_color_change");
}
} );
The table.cell( this ).data(cellValueEnd) command updates the cell in DataTables so that it matches the value you typed into the HTML cell. If you do not do this, then the data in the DataTables object (behind the scenes) will be out-of-sync with the data in the HTML table (what you see on your screen).
Warning: This approach is basic. It does not cover the case where a user may do the following:
Edit a cell from "A" to "B".
Leave the cell, so it is highlighted.
Return to the cell and edit it back from "B" to "A".
Leave the cell again.
In this case, the cell will remain highlighted.
One way around this is to capture the original state of every cell when you first load the table - and then check each edit against the value in the original data. This can be done, if needed - but is outside the scope of this question. But it also depends on what you need to do with the data, after you have finished editing it. If this is important to you, then it may be worth asking a new question for that specific problem.
Friends,I have tried this a lot but i don't know where I am wrong.I am trying to color the cell of my datatable depending on its cell content,but nothing is happening. I have tried using fnrowcallback function ,Createdrow function ,but nothing is working out. When I change the comparison operator to "not equal to(!=)" it colors all the cells of my table.But when it is "equal to(==)" it does not work as required.I want to color the row if its 3rd column cell contains "A" or "Sat".Please check my code and let me know ,where did i go wrong.
Here is my code-
"fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[2] == "A")
{
$('td', nRow).css('background-color', 'pink');
}
else if (aData[2] == "Sat")
{
$('td', nRow).css('color', 'Orange');
}
}
Maybe this works for you if you're willing to use jQuery:
$('td:contains("three")').css('background', 'red');
$('td:contains("two")').css('background', 'yellow');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td>one</td><td>two</td></tr>
<tr><td>three</td><td>four</td></tr>
</table>
Try to check the dataype of aData. It its an object then accessing it via object notation should not give you undefined. My guess is it might be a json string???
I am using the jquery plugin datatable
https://datatables.net/
And I would like to hide some row during the process,
$(".menu_time_table tbody tr").hide();
$.each(obj, function (i, v) {
if (v.user_type === "2") {
$(".student_time_" + v.share_to).parent().show();
} else {
$(".teacher_time_" + v.share_to).parent().show();
}
});
finally, at setup the datatable, are there any way to not count the hidden row in the result? e.g. Now the problem is , if total rows are 200, hidden rows are 100, then the datatable shows there are 200 rows.
$('.menu_time_table').DataTable({
"order": [[0, "asc"]],
"language": table_lang,
"bDestroy": true,
"deferRender": true
});
Thanks a lot for helping.
I have a datatable, I want to color code the column based value in the last row.
If the TYPE value is "O" then apply yellow color, otherwise nothing. My columns are dynamic.
expected result:
var dt= $(element).dataTable({
deferRender: true,
destroy: true,
"aaData": data, // data is coming from service
"aoColumns": columns // column is dynamic
});
SOLUTION
You can use drawCallback to handle table draw event and enumerate columns data with columns().every() to find columns containing required values and highlight them.
var table = $('#example').DataTable({
drawCallback: function(){
var api = this.api();
api.columns().every( function () {
var data = this.data();
if($.inArray('O', data) !== -1){
$(this.nodes()).addClass('highlight');
} else {
$(this.nodes()).removeClass('highlight');
}
});
}
});
Please note that the code above detects O in all rows. To handle only the last row you need to add more code.
DEMO
See this jsFiddle for code and demonstration.
Use the rowCallback
$(element).dataTable({
"rowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
switch(aData[0]){
case 'O':
$(nRow).css('backgroundColor', 'yellow');
//also style other rows here
break;
}
}
});
Simple demo: Fiddle
Summary
I am using the great dataTables jQuery plugin from http://www.datatables.net. In my script, I am dynamically adding rows based on an event firing using fnAddData. Using fnRowCallback, I add in a unique row ID. This sometimes fails and does not add a row ID. In a test of 46 row additions, usually 6 to 8 rows do not get a row ID.
Add Row function
function ps_ins(row)
{
var rowArray = row.split('|');
row = rowArray;
var alarmID = parseInt(row[1],10);
$('#mimicTable').dataTable().fnAddData([
alarmID, 'col2', 'col3', 'col4',
'col5', 'col6', 'col7'
]);
}
Rows are added to the table correctly. The test I am running adds 46 rows, and all appear as expected.
Add the row ID
I am trying to add a unique ID to each row so I can later modify a specific row and refer to it in dataTable's cache using a combination of fnGetRows and .filter.
I am doing this using fnRowCallback during the initialisation stage. I've kept all the other settings just incase there's anything there that might have an impact on the problem.
$('#mimicTable').dataTable({
"sDom": 'lip<"mimicSpacer">f<"numUnAck">rt',
"sScrollY": "365px",
"aaSorting": [[4,'desc'],[5,'desc']],
"iDisplayLength": 15,
"aLengthMenu": [[15, 50, 100, -1], [15, 50, 100, 'All']],
"bAutoWidth": false,
"aoColumns": [
null,
{ "sWidth": "20%" },
{ "sWidth": "22%" },
{ "sWidth": "9%" },
{ "sWidth": "9%" },
{ "sWidth": "20%" },
{ "sWidth": "20%" }
],
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull) {
$(nRow).attr("id",'alarmNum' + aData[0]);
return nRow;
}
});
A console.log of the dataTable object shows:
As you can see, #14 has the row id and also the correct rowStripe class. #15 (and onwards) doesn't.
So, why is fnRowCallback not firing each time a row is added, only sometimes? Maybe there is a better way to add a row ID when a row is added?
Found the solution:
http://www.datatables.net/forums/discussion/2119/adding-row-attributes-after-fnadddata/p1
For anyone else wanting a quick solution, I did:
var addId = $('#mimicTable').dataTable().fnAddData([
alarmID,
'col2',
'col3',
'col4',
'col5'
]);
var theNode = $('#mimicTable').dataTable().fnSettings().aoData[addId[0]].nTr;
theNode.setAttribute('id','alarmNum' + alarmID);
I know this is quite an old thread, but this might help others.
The easiest way I do it to add id attribute to the last added row as soon as I called the data table function fnAddData is:
$('#table').dataTable().fnAddData( ['col1','col2','col3'] );
$('#table tr:last').attr('id','col'+row_id);
Try this it worked for me nicely:
var newRow = oTable.fnAddData( [ etc..]);
var oSettings = oTable.fnSettings();
var nTr = oSettings.aoData[ newRow[0] ].nTr;
nTr.id = 'new id';
There is something unexpected with your code in the jsbin, even if it appears to be working. It initializes with the "browsers" data set. Then it clears. Then it makes a new table with one row. Then it clears. Then it makes a new table with two rows. Then it clears. Then it makes a new table with three rows.
I'd have to get a better sense of the code sample and its end goal (and alas my attention is diverted elsewhere right now) but you should be aware that fnRowCallback SHOULD be the way to do this, and that there are many redundant table constructions and row additions that are going to impact performance as well as flexibility with modifying rendering in the future.
You can use DT_RowId when you add new row, and use object instead an array, see below:
$('#mimicTable').dataTable().fnAddData({
'DT_RowId': alarmID, 0:'col2', 1:'col3', 2:'col4',
3:'col5', 4:'col6', 5:'col7'
});
This worked for me
var MyUniqueID = "tr123"; // this is the uniqueId.
var rowIndex = $('#MyDataTable').dataTable().fnAddData([ "column1Data", "column2Data"]);
var row = $('#MyDataTable').dataTable().fnGetNodes(rowIndex);
$(row).attr('id', MyUniqueID);