How to make a row read-only based on value from another column in the table?
How to make a row read-only based on value from another column in the table?
I'm using DT for the first time and have it working pretty well, but one thing my Google-fu is failing at is finding a way to dynamically make a row read-only (i.e. my checkbox selector (multi) in Column 0 cannot be checked) based on the value of another column in the table.
$(document).ready(function() {
$('#show-entries').DataTable( {
"language": {
"search": "Filter records:"
},
columns: [
{ data: null, title: "Select"},
{ data: "ID", title: "ID" },
{ data: "Year", title: "Year" },
{ data: "First_Name", title: "First_Name" },
{ data: "Last_Name", title: "Last_Name" },
{ data: "Entry_Form_Number", title: "Entry #" },
{ data: "Barcode_Text", title: "Barcode" },
{ data: "Entrant_Name", title: "Entrant Name" },
{ data: "Model_Name", title: "Title of Entry" },
{ data: "Category_Name", title: "Category" },
{ data: "Paid", title: "Paid" ,
render: function (data, type, row, meta) {
if (type === 'display') {
return data === "1" ? 'Y' : 'N';
}
return data;
}
},
{ data: "DatePaid", title: "Date Paid" },
{ data: "DateCreated", title: "Date Created" },
{ data: null, title: "Print",
render: function (data, type, row, meta) {
return '<input type="button" class="btn-print printrec" id="' + meta.row + '" value="Print"/>';
}
}
],
"columnDefs": [
{
defaultContent: '',
orderable: false,
className: 'select-checkbox',
targets: 0
},
{ className: "dt-center", "targets": [ 10 ] },
{
// Hide 'ID' & 'Year' columns
"targets": [ 1, 2 ],
"visible": false,
"searchable": false
},
{
// Hide 'First_Name' & 'Last_Name' columns
"targets": [ 3, 4 ],
"visible": false
},
{
// Limit 'Entrant Name' text length
"targets": [ 7 ],
render: function ( data, type, row ) {
return type === 'display' && data.length > 43 ?
data.substr( 0, 43 ) +'…' :
data;
}
},
{
// Limit 'Title of Entry' text length
"targets": [ 8 ],
render: function ( data, type, row ) {
return type === 'display' && data.length > 100 ?
data.substr( 0, 97 ) +'…' :
data;
}
}
],
select: {
style: 'multi',
selector: 'td:first-child',
info: true
},
order: [[ 1, 'asc' ]]
} );
$('#formsearch').click(function() {
// Get values of search inputs
var contestYear= $('#contest-year').val();
var entryNumber= $('#entry-number').val();
var barCode= $('#barcode').val();
var firstName= $('#first-name').val();
var lastName= $('#last-name').val();
var title= $('#title-name').val();
var isPaid = $('input[name=paidStatus]:checked').val();
// Send Ajax request to get results of search entry
$.ajax({
type: "POST",
url: "php/searchreceive.php",
data:{"c_year": contestYear, "e_number": entryNumber, "bCode":barCode, "fName":firstName, "lName": lastName, "title":title, "isPaid":isPaid}
}).done(function(status) {
status=status.trim();
if(status==="InvalidSession"){
// Redirect to logout page
window.location.href='../common/php/logout.php';
}
if(status==="NoResults") {
alert("No records found - please try again.");
}else {
// Process result data into DT
dataSet = JSON.parse(status);
//console.log(dataSet);
// clear table and add new rows
$('#show-entries').DataTable().clear().draw();
$('#show-entries').DataTable().rows.add(dataSet).draw();
}
});
});
// Select All button
$('#selectAll').click(function() {
if(this.checked) {
//checked here
$('#show-entries').DataTable().rows().select();
//console.log('selectall checked');
}
else {
//unchecked here
$('#show-entries').DataTable().rows().deselect();
//console.log('selectall unchecked');
}
});
});
The column titled 'Select' is a DT checkbox and what I'd like to do is make a row read-only if the 'Paid' column is 'Y', so that the $selectAll click event (tied to a checkbox outside of DT) will not update that row (Ultimately, what will happen is the user will use my main HTML form to do a search and then use the 'selectAll' button to select all non-Paid rows in the table; that list of selected rows will then be passed to a PHP script for processing). I think I need a render function inside 'Select', but how to I make it dynamic based on what's in 'Paid' for that row?
This question has accepted answers - jump to:
Answers
Perhaps ‘read-only’ is the wrong term - disabled, maybe? A callback function in the column render?
The easiest thing to do would be to remove the
select-checkbox
class from the column. The checkbox wouldn't show. That you would probably do inrowCallback
.Haven't tried this but you might be able to use the
select
handler to check the data in the row and deselect if needed. The first example shows how to get the data usingpluck()
which is what you would do then userow().deselect()
if appropriate.Kevin
Thanks Kevin, but is there a way to do this before a user tries to select the row? In other words, make the checkbox read-only/disabled on the first draw after processing the results from the Ajax call if the value of 'Paid' = 'Y'?
I was going to mention that I missed a step with option one. In your
select
option config you would change the selector to theselect-checkbox
class:selector: '.select-checkbox',
A better option would be to do as you mention, to disable the checkbox. I think the easiest way to do this is to add a second class to column 0,
select-enabled
for example then set the selector to that. For example:Then in
rowCallback
you can add or remove the class as desired. Updated example:http://live.datatables.net/vinipiye/4/edit
Note that I'm checking to see if
Paid == "1"
because that is the original data as the render function is only updating the displayed data.Kevin
While you were typing your answer, I added this:
... which didn't work. Then I saw your most recent post and changed the check on Paid to "1" and bingo - the checkbox for those rows disappears! Thanks again!
Spoke too soon. So, the checkbox disappears for those rows where Paid=1, but I can still select the row via:
So, I still need to disable the row to prevent it from being selected.
If you use the second class then you can also use that as the row selector:
https://datatables.net/reference/type/row-selector
I think this should work using the additional
.select-enabled
class:$('#show-entries').DataTable().rows('.select-enabled').select();
Kevin
I tried your code from your site but all checkboxes are disabled (regardless if Paid = 1 or not). But, if I click my 'Select all' button it still selects all the rows.
Not sure why all your checkboxes would be disabled, don't see anything that stands out in your code. It looks the same as mine and mine seems to work.
Yep, I can see that my guess at the selector for select all isn't correct. According to the docs you should be able to select rows based on
td
node info but I haven't figured out what to use. I tried a couple things in my example. Maybe someone else can help or if I find something I will respond.Kevin
I was able to use a function to select the rows with the class
select-enabled
:Its working here:
http://live.datatables.net/vinipiye/4/edit
Kevin
Thanks Kevin. It's working great, except for records not on the current page - clicking the 'Select all' button will select Paid rows not on the current page, but if you go to that page and toggle the 'Select all' button then it won't select them.
Sorry, I thought rowCallback affected all rows but it only runs on the displayed rows. You will need to use
columns.createdCell
for column 0 to do this. You can remove the rowCallback and do something like this:You can see the working example here:
http://live.datatables.net/vinipiye/4/edit
There are now two pages of display.
Kevin
That's it! Thank you very much.