I'm working on a system of medical transportation. Every day I have around 700 trips, so the table is pretty large.
I want the app, after the user adds a trip, the screen is positioned in the newly added trip. (scroll) ,for the user to corroborate the trip successfully added (not my idea, my client wants it that way) . For this, I am sending to the page by parameter the ID of the new trip added.
I'm using a function "fnFindCellRowIndexes" that i found on datatables page, but i can't make it work. The column i wait to search in is index 1.
Here's my code:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#tabla').DataTable({
"deferRender": true,
"language": {
"url": "include/DataTables/Spanish.json"
},
"paging": false,
"ordering": false,
"info": false,
"searching": true,
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
"searchable": true
},
{
"targets": [ 1 ],
"visible": false,
"searchable": false
}
],
"stateSave": true
});
var index = table.fnFindCellRowIndexes( '<?=$idNuevo?>', 1 );
alert(index);
jQuery.fn.dataTableExt.oApi.fnFindCellRowIndexes = function ( oSettings, sSearch, iColumn )
{
var
i,iLen, j, jLen, val,
aOut = [], aData,
columns = oSettings.aoColumns;
for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
{
aData = oSettings.aoData[i]._aData;
if ( iColumn === undefined )
{
for ( j=0, jLen=columns.length ; j<jLen ; j++ )
{
val = this.fnGetData(i, j);
if ( val == sSearch )
{
aOut.push( i );
}
}
}
else if (this.fnGetData(i, iColumn) == sSearch )
{
aOut.push( i );
}
}
return aOut;
};
</script>
I'm getting error "fnFindCellRowIndexes is not a function"
Can anyone help me? if anyone has any idea to do it in a better way, suggestions are accepted.
Declare fnFindCellRowIndexes before you instantiate your dataTable!
You must instantiate with dataTable(). fnFindCellRowIndexes is an oldschool none-API plugin. As far as I can see in your code, you should not have problems with that. If you still want to use the new API, you can always use table.api().<api-functions>
The PHP variable does not magically echo itself out (no offense :-) - you forget to actually print it :
var index = table.fnFindCellRowIndexes( '<? echo $idNuevo ?>', 1 );
Remember that fnFindCellRowIndexes is an equal / == search. If you search for 1 in column #1 it only return columns that hold the value 1 and nothing more, not rows holding 10, 101, 1.1 etc.
Related
I have a datatable that shows mock json data retrieved from a text file. I have removed the first column as it contains the id and it isn't ideal to display the id on the table. I appended a buy button on each row on the first column only. However, when I sort the table the button disappears and the original first column data also appears.
JavScript:
$(document).ready(function() {
$.getJSON('/apps/mchp/clientlibs/clientlib-site/components/parametrictable/data.txt', function(json) {
var data = json.data;
var $thead = $('#parametrictable').find('thead');
var tr = $("<tr>");
$thead.append(tr);
var columns = [];
var obj = Object.keys(data[0]);
console.log(data[0])
var button = '<div class="left-btn"><i class="download fas fa-file-download"></i></div><div class="right-btn"><div class="input-group"><div class="input-group-area"><input type="text" value="100"></div><div class="input-group-icon">BUY</div></div></div>';
$.each(data[0], function(name, value) {
var column = {
"data": name,
"title":name
};
$('tr').find('th:first-child',).remove();
columns.push(column);
});
for (i=1; i<obj.length; i++) {
$(".dropdown-content").append('<li><input type="checkbox" class="dropcheck" data-column="'+i+'"/>'+obj[i]+'</li>');
}
var table= $('#tableId').DataTable({
data: data,
columns: columns,
columnDefs: [ {
orderable: true,
className: 'select-checkbox',
targets: 1
} ],
select: {
style: 'multi',
selector: 'td:first-child'
},
order: [[ 1, 'asc' ]]
});
$('tr').find('th:first-child').remove();
$('tr').find('td:first-child').remove();
$('tr').find('td:first-child').append(button);
$('tr').on('change', function(e){
e.preventDefault();
console.log('change!');
});
$('input[type=checkbox]').on( 'change', function (e) {
e.preventDefault();
var column = table.column( $(this).attr('data-column') );
column.visible( ! column.visible() );
} );
$('.show-all').on( 'click', function (e) {
e.preventDefault();
var obj = Object.keys(data[0])
for (i=1; i<obj.length; i++) {
var col = table.columns([i]);
if (col.visible().join(', ') == 'false') {
col.visible(true);
$(".dropcheck").prop("checked", false);
}
}
} );
});
})
First, it is not a good practice to hide datatable columns by .remove(), datatables have a built-in code for that by columnDefs refer:
https://datatables.net/examples/basic_init/hidden_columns.html
Second, that is not the right way to append data/html in datatable columns, use rowCallback function for datatable, see:
columnDefs: [
{
"targets": [ 0 ],
"visible": false,
"searchable": false
},
],
rowCallback: function(row, data, index) {
if($('td:eq(1)', row).find('.download').length == 0)
{
$('td:eq(1)', row).append(button);
}
},
When using datatable sort or search or any datatable actions it always refreshes the table therefore, any initialization before the action will be disregarded unless executed again.
This might be a straight forward question, but I'm struggling to implement the solution I found. Lack of experience with JavaScript.
I'm trying to implement a custom search in a DataTables table, but the function I have only fires on startup and not on typing in the search box.
here is my original question.
and here is the solution for the search I'm trying.
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
var term = $('.dataTables_filter input').val().toLowerCase()
for (var i=0, l=data.length; i<l; i++) {
if ($(data[i], 'label').text().toLowerCase().indexOf(term) == 0 ) return true
}
return false
})
Ive tried it outside the $(document).ready(function(){, but it does not work.
here is the initialization of the DataTables table.
$(document).ready(function(){
.
.
.
var oTable = $('#desktop_table').dataTable({
"bInfo": false,
"iDisplayLength": 15,
"aLengthMenu": [15, 30, 50, 100],
"sPaginationType": "full_numbers",
"sDom": '<"top"i>frt<"bottom"lp><"clear">',
"oLanguage": {
"sLengthMenu": "Show _MENU_"
},
"sStripeOdd": "odd",
"sStripeEven": "even",
"rowReorder": true,
});
}
Preview of a cell in my DataTables table
<td>
<div class="plCell_desktop">
<input type="radio" class="" data-lnk_id="414107671" data-group="RUTH">
<label for="414107671">RUTH</label>
</div>
</td>
$('input[type="radio"]').change(function () {
$.fn.dataTable.ext.search.push(function( settings, data, dataIndex ) {
var term = $('.dataTables_filter input').val().toLowerCase()
for (var i=0, l=data.length; i<l; i++) {
if ($(data[i], 'label').text().toLowerCase().indexOf(term) == 0 )
return true;
}
return false;
});
var table = $('#desktop_table').DataTable();
table.draw();
});
I have my dataTable done successfully
All I have to do is assign the attributes to the columns of this table.
I have the attributes in the array as shown:
$attributes = array('7' => array(
'17' => array(
'class' => 'editable'
)
'18' => array(
'class' => 'custom_7_18 editable'
)
)
where 17 and 18 are the ids of fieldone and fieldtwo.
code for dataTable
$('table.crm-multifield-selector').dataTable({
"bProcessing": true,
"asStripClasses" : [ "odd-row", "even-row" ],
"sPaginationType": "full_numbers",
"sDom" : '<"crm-datatable-pager-top"lfp>rt<"crm-datatable-pager-bottom"ip>',
"bServerSide": true,
"bSort" : false,
"sAjaxSource": sourceUrl,
});
I can't use the sClass in datatable as it will assign same attribute to all the <td> element. Is there any param to assign different attribute?
Can I assign the attributes from the $attribute array to the dataTable?
Or is there any way to assign attribute from the callback function? so that I can use this $attribute array in the php file and the dataTable assigns this attribute every time it draws a row?
I've tried this -
"fnCreatedRow": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
$.each(attributes, function(index, item) {
//as the number of column can be changed, I can't give
//hardcoded values as I found during searching like
$('td:eq(2)', nRow).addClass('editable');
});
}
Has anyone come across a situation like this ?
I've just fixed this, would like to share here :)-
Assign the attribute for each cell in the call back function itself, i.e, change the cell value to be the array which contains the data as well as the attributes (for eg: class)
//$value is the array sent to dataTable
foreach ($value as $fieldId => &$fieldName) {
if (!empty($attributes[$fieldId][$id]['class'])) {
//change the fieldName to array containing the attributes and the data part
$fieldName = array(
'data' => $fieldName,
// as I said in the question, I had $attributes array for the fields ids
'fieldClass' => $attributes[$fieldId][$id]['class']
);
}
}
Adjust this to replicate on the dataTable using standard fnRowCallback:
//Add class attributes to cells
"fnRowCallback": function(nRow, aData) {
// iterate through each row
$('td', nRow).each(function(index, element) {
if (typeof aData[index]=='object') {
if (typeof aData[index].fieldClass != 'undefined') {
$(element).addClass(aData[index].fieldClass);
}
if (typeof aData[index].data != 'undefined') {
$(element).html(aData[index].data);
}
}
});
return nRow;
},
I have following code for jQuery DataTables:
Contact.DataTable = $('#otable').DataTable( {
"ajax": {
"url" : '/Contact/' + Contact.id,
"dataSrc": function(check) {
return check.data;
},
},
"responsive": true,
"columns": [
{ "data": "id"},
{ "data": "category", "sClass": "category" },
{ "data": "name", "sClass": "name" },
{ "data": "lname" },
{
"render": function ( data, type, method, meta ) {
return Contact.saveContact(method);
}
},
]
} );
Datatable - dropdown - inline edit:
$('#otable tbody').on('click', '.category', function () { //second column
var row = this.parentElement;
if(!$('#otable').hasClass("editing")){
$('#otable').addClass("editing");
var data = Contact.DataTable.row(row).data();
var $row = $(row);
var thiscategory = $row.find("td:nth-child(2)");
var thiscategoryText = thiscategory.text();
thiscategory.empty().append($("<select></select>",{
"id":"category" + data[0],
"class":"in_edit"
}).append(function(){
var options = [];
$.each(Categories, function(key, value){
options.push($("<option></option>",{
"text":value,
"value":value
}))
})
return options;
}));
$("#category" + data[0]).val(thiscategoryText)
}
})
;
For changing values in dropdown
$('#otable tbody').on("change", ".in_edit", function(){ //Inline editing
var val = $(this).val();
$(this).parent("td").empty().text(val);
$('#otable').removeClass("editing");
});
Below code for saving new values(after inline edit) while clicking save:
$('#divsave').on("click", ".saveContact", function() {
var data = Contact.DataTable.row($(this).closest('tr')).data();
// Here I have to get new values after inline editing - but getting old values
});
My problem is : while clicking edit, in 'data', I am getting old values in the row of datatable, not the modified value after inline edit
datatable view - 1:
datatable - dropdown in column:
datatable after inline editing:
What I need: Save modified row while clicking 'save' image - currently it saves older value before inline editing(datatable view - 1)
When using dataTables it is generally a very bad idea to manipulate the DOM <table> or any content by "hand" - you should always go through the dataTables API.
Thats why you are getting "old values" - you have manipulated the content of the <table>, or so it seems - dataTables are not aware of those changes.
In a perfect world you should refactor the setup completely (i.e to use the API) but I guess you can solve the issue by using invalidate() on the row being changed in order to refresh the dataTables internals :
$('#otable tbody').on("change", ".in_edit", function(){ //Inline editing
var val = $(this).val();
$(this).parent("td").empty().text(val);
//add this line to refresh the dataTables internals
Contact.DataTable.row($(this).parent("tr")).invalidate();
//
$('#otable').removeClass("editing");
});
I am using datatables in my application. Whenever user click on any row I want to highlight it and pick some values from selected row.
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
var s=$(node).children();
alert("Selected Row : " + $s[0]);
}
I tried sRowSelect and fnRowSelected but no luck. The row is not highlighted and neither fnRowSelected is called. Even no error on console.
Here is my complete code
var userTable = $('#users').dataTable({
"bPaginate": true,
"bScrollCollapse": true,
"iDisplayLength": 10,
"bFilter": false,
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"oLanguage": {
"sLengthMenu": "Display _MENU_ records per page",
"sZeroRecords": "Enter a string and click on search",
"sInfo": "Showing _START_ to _END_ of _TOTAL_ results",
"sInfoEmpty": "Showing 0 to 0 of 0 results",
"sInfoFiltered": "(filtered from _MAX_ total results)"
},
"aaSorting": [[ 0, "asc" ]],
"aoColumns": [/* Name */ null,
/*Institution*/null,
/*Email*/null],
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
alert("Clicked");
}
}
});
Am I missing anything ?
EDIT:
Now able to highlight selected row.Added class="display" to HTML table. Still wondering why I didn't find this in datatable docs. Now looking how to collect selected values.
Here is how I do it
just add this function to your page (if users is your table id)
$("#users tbody").delegate("tr", "click", function() {
var iPos = userTable.fnGetPosition( this );
if(iPos!=null){
//couple of example on what can be done with the clicked row...
var aData = userTable.fnGetData( iPos );//get data of the clicked row
var iId = aData[1];//get column data of the row
userTable.fnDeleteRow(iPos);//delete row
}
When you are using fnRowSelected (i.e. when creating new tabletool) you have to use
"sRowSelect": "multi",
That will resolve the issue. Please increment my comment count if it helps. I need to have more points.
I used it in my code as follows
pqrtbl = new TableTools(NameOfTbl, { "sRowSelect": "multi",
"fnRowSelected": function ( node ) {
var s= $(node).children();
fnAddToSelLst(s[1].innerText);
},.......................
//column index depend upon your req.
The selected class should be, Within your function you used $s and you define var s which is not the same var.
"oTableTools": {
"sSelectedClass": "yourclassname",
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
var s=$(node).children();
alert("Selected Row : " + s[0]);
}
}
If you wanna select multiple row, wanna get the data of selected row for ajax purpose check this
http://jsfiddle.net/ezospama/1/
DataTable code will be as follows
$(document).ready(function() {
var table = $('#datatable').DataTable();
$('#datatable tbody').on( 'click', 'tr', function (){
$(this).toggleClass('selected');
} );
$('#btn').click( function () {
console.log(table.rows('.selected').data());
alert("Check the console for selected data");
} );
})