Kaiden Rogers Kaiden Rogers - 6 months ago 20
jQuery Question

Adding table data to editable DataTables removes filters

I'm using an editable DataTable and when I add more than 4 table headers or table data it removes the filters of the table (Search, Sort, Pagination, Edit, etc).

This code works:

<table class="table table-bordered table-striped mb-none" id="datatable-editable">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="gradeU">
<td></td>
<td></td>
<td></td>

<td class="actions">
<a href="#" class="hidden on-editing save-row"><i class="fa fa-save"></i></a>
<a href="#" class="hidden on-editing cancel-row"><i class="fa fa-times"></i></a>
<a href="#" class="on-default edit-row"><i class="fa fa-pencil"></i></a>
<a href="#" class="on-default remove-row"><i class="fa fa-trash-o"></i></a>
</td>
</tr>
</tbody>
</table>


result:
output 1

This one doesn't:

<table class="table table-bordered table-striped mb-none" id="datatable-editable">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="gradeU">
<td></td>
<td></td>
<td></td>
<td></td>
<td class="actions">
<a href="#" class="hidden on-editing save-row"><i class="fa fa-save"></i></a>
<a href="#" class="hidden on-editing cancel-row"><i class="fa fa-times"></i></a>
<a href="#" class="on-default edit-row"><i class="fa fa-pencil"></i></a>
<a href="#" class="on-default remove-row"><i class="fa fa-trash-o"></i></a>
</td>
</tr>
</tbody>
</table>


result:

output 2

And the only difference is the added header and table data
Does anyone know how to fix this?

Update:

I checked another DataTable that isn't editable but still has filters and i was able to successfully add table headers and table data.

The only difference between the tables are the dependent files:
example.datatables.default.js for the non-editable table and example.datatables.editable.js for the editable table

example.datatables.default.js

(function( $ ) {

'use strict';

var datatableInit = function() {

$('#datatable-default').dataTable();

};

$(function() {
datatableInit();
});
}).apply( this, [ jQuery ]);


example.datatables.editable.js

(function( $ ) {

'use strict';

var EditableTable = {

options: {
addButton: '#addToTable',
table: '#datatable-editable',
dialog: {
wrapper: '#dialog',
cancelButton: '#dialogCancel',
confirmButton: '#dialogConfirm',
}
},

initialize: function() {
this
.setVars()
.build()
.events();
},

setVars: function() {
this.$table = $( this.options.table );
this.$addButton = $( this.options.addButton );

// dialog
this.dialog = {};
this.dialog.$wrapper = $( this.options.dialog.wrapper );
this.dialog.$cancel = $( this.options.dialog.cancelButton );
this.dialog.$confirm = $( this.options.dialog.confirmButton );

return this;
},

build: function() {
this.datatable = this.$table.DataTable({
aoColumns: [
null,
null,
null,
{ "bSortable": false }
]
});

window.dt = this.datatable;

return this;
},

events: function() {
var _self = this;

this.$table
.on('click', 'a.save-row', function( e ) {
e.preventDefault();

_self.rowSave( $(this).closest( 'tr' ) );
})
.on('click', 'a.cancel-row', function( e ) {
e.preventDefault();

_self.rowCancel( $(this).closest( 'tr' ) );
})
.on('click', 'a.edit-row', function( e ) {
e.preventDefault();

_self.rowEdit( $(this).closest( 'tr' ) );
})
.on( 'click', 'a.remove-row', function( e ) {
e.preventDefault();

var $row = $(this).closest( 'tr' );

$.magnificPopup.open({
items: {
src: _self.options.dialog.wrapper,
type: 'inline'
},
preloader: false,
modal: true,
callbacks: {
change: function() {
_self.dialog.$confirm.on( 'click', function( e ) {
e.preventDefault();

_self.rowRemove( $row );
$.magnificPopup.close();
});
},
close: function() {
_self.dialog.$confirm.off( 'click' );
}
}
});
});

this.$addButton.on( 'click', function(e) {
e.preventDefault();

_self.rowAdd();
});

this.dialog.$cancel.on( 'click', function( e ) {
e.preventDefault();
$.magnificPopup.close();
});

return this;
},

// ==========================================================================================
// ROW FUNCTIONS
// ==========================================================================================
rowAdd: function() {
this.$addButton.attr({ 'disabled': 'disabled' });

var actions,
data,
$row;

actions = [
'<a href="#" class="hidden on-editing save-row"><i class="fa fa-save"></i></a>',
'<a href="#" class="hidden on-editing cancel-row"><i class="fa fa-times"></i></a>',
'<a href="#" class="on-default edit-row"><i class="fa fa-pencil"></i></a>',
'<a href="#" class="on-default remove-row"><i class="fa fa-trash-o"></i></a>'
].join(' ');

data = this.datatable.row.add(['', '', '', actions ]);
$row = this.datatable.row( data[0] ).nodes().to$();

$row
.addClass( 'adding' )
.find( 'td:last' )
.addClass( 'actions' );

this.rowEdit( $row );

this.datatable.order([0,'asc']).draw(); // always show fields
},

rowCancel: function( $row ) {
var _self = this,
$actions,
i,
data;

if ( $row.hasClass('adding') ) {
this.rowRemove( $row );
} else {

data = this.datatable.row( $row.get(0) ).data();
this.datatable.row( $row.get(0) ).data( data );

$actions = $row.find('td.actions');
if ( $actions.get(0) ) {
this.rowSetActionsDefault( $row );
}

this.datatable.draw();
}
},

rowEdit: function( $row ) {
var _self = this,
data;

data = this.datatable.row( $row.get(0) ).data();

$row.children( 'td' ).each(function( i ) {
var $this = $( this );

if ( $this.hasClass('actions') ) {
_self.rowSetActionsEditing( $row );
} else {
$this.html( '<input type="text" class="form-control input-block" value="' + data[i] + '"/>' );
}
});
},

rowSave: function( $row ) {
var _self = this,
$actions,
values = [];

if ( $row.hasClass( 'adding' ) ) {
this.$addButton.removeAttr( 'disabled' );
$row.removeClass( 'adding' );
}

values = $row.find('td').map(function() {
var $this = $(this);

if ( $this.hasClass('actions') ) {
_self.rowSetActionsDefault( $row );
return _self.datatable.cell( this ).data();
} else {
return $.trim( $this.find('input').val() );
}
});

this.datatable.row( $row.get(0) ).data( values );

$actions = $row.find('td.actions');
if ( $actions.get(0) ) {
this.rowSetActionsDefault( $row );
}

this.datatable.draw();
},

rowRemove: function( $row ) {
if ( $row.hasClass('adding') ) {
this.$addButton.removeAttr( 'disabled' );
}

this.datatable.row( $row.get(0) ).remove().draw();
},

rowSetActionsEditing: function( $row ) {
$row.find( '.on-editing' ).removeClass( 'hidden' );
$row.find( '.on-default' ).addClass( 'hidden' );
},

rowSetActionsDefault: function( $row ) {
$row.find( '.on-editing' ).addClass( 'hidden' );
$row.find( '.on-default' ).removeClass( 'hidden' );
}

};

$(function() {
EditableTable.initialize();
});

}).apply( this, [ jQuery ]);


And JavaScript is definetly not my strong point.

Can someone please help me make sense of this?

Answer

Your code is hard-coded for 4 columns. You need to change it so that any number of columns are accepted.

Change this line in example.datatables.editable.js:

this.datatable = this.$table.DataTable({
    aoColumns: [
        null,
        null,
        null,
        { "bSortable": false }
    ]
});

to:

this.datatable = this.$table.DataTable({
    columnDefs: [
        { targets: -1, orderable: false }
    ]
});

Also replace

data = this.datatable.row.add(['', '', '', actions ]);

with

var numCols = this.datatable.columns().nodes().length;
var rowData = [];
for(var i = 0; i < numCols - 1; i++){ rowData.push(''); }
rowData.push(actions);
data = this.datatable.row.add(rowData);
Comments