fnDeleteRow isn't really deleting the row?

fnDeleteRow isn't really deleting the row?

rcritenrcriten Posts: 5Questions: 0Answers: 0
edited November 2009 in General
I'm attempting to update a table with new information. If a row isn't visited during the update, we need to remove that row from the table. I wrote the following method that removes the selected row from the rendered output. However, the call to fnGetNodes() keeps returning the original number of nodes. Using firebug, I can see that the deleted row has some special attribute (it is greyed out). Calls to fnGetData() still have the deleted row in the returned result. I'm using datatables, version 1.5.2 at the moment.

I realize that I can change the code from fnGetNodes() to $('#theTable).find('tr').... But this handles only the visible rows. If I have a large table with pagination, I will miss deleting some rows that could later be displayed.

Hopefully, I'm doing something crazy.


// take a list of processed ids and remove any un-processed rows from the table.
function cleanUpOldIds(procid) {
var nodes = theTable.fnGetNodes();
var oid = [];
oid.length = 0;
var ii=0;
$(nodes).filter('tr').each( function() { oid[ii++] = $(this).attr('id'); });

alert(' number of ids before deletion: ' + oid.length + ', values=' + oid.join(',') + '\n number of processed ids: ' + procid.length + ', values=' + procid.join(','));
// slow!
for(ii=0; ii < oid.length; ++ii) {
if($.inArray(oid[ii], procid) == -1)
alert('must delete row for id=' + oid[ii]);
var pos = vmTable.fnGetPosition($('tr#' + oid[ii]).get(0));
vmTable.fnDeleteRow(pos);
}
}

var nodes = theTable.fnGetNodes();
var noid = []
noid.length = 0;
ii=0;
$(nodes).filter('tr').each( function() { noid[ii++] = $(this).attr('id'); }); /// this still has the data.
$('#vmTable tbody').find('tr').each( function() { noid[ii++] = $(this).attr('id'); }); // this works...
alert(' number of ids in table after deletion: ' + noid.length);

}

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Hi rcriten,

    What you need to do is pass "true" as the third parameter to fnDeleteRow (and null as the second) in order to delete the row completely from DataTables, rather than just the display arrays: http://datatables.net/api#fnDeleteRow . The reason for this is exactly what you are seeing, so it is possible to add rows back in if you want later (but you don't want this - so fnDeleteRow allows for this too :-) ).

    Regards,
    Allan
  • bakaynbakayn Posts: 14Questions: 0Answers: 0
    edited April 2010
    i have a error with the allan solution, but i want delete the selected row for ever from all place.
    my code:
    [code]
    $('#delete').click( function() {
    var anSelected = fnGetSelected( oTable );
    oTable.fnDeleteRow( anSelected[0], null, true );
    } );
    ...

    function fnGetSelected( oTableLocal ){
    var aReturn = new Array();
    var aTrs = oTableLocal.fnGetNodes();
    for ( var i=0 ; i
  • jokkejokke Posts: 4Questions: 0Answers: 0
    I get an error too on calling fnDeleteRow(index, null, true). I tried adding a bool argument more for fnDeleteRow; "bRemoveFromaoData" like this:
    [code]
    this.fnDeleteRow = function (mTarget, fnCallBack, bNullRow, bRemoveFromaoData) {
    ...
    if (typeof bRemoveFromaoData != "undefined" && bRemoveFromaoData === true) {
    oSettings.aoData.splice(iAODataIndex, 1);
    }
    ...
    [/code]
    but this results in an error in _fnBuildSearchArray...
    I could follow it through and edit even more in the js file, but I would not like getting too far away from the base line.
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    You could try using the 1.7 betas which have reworked this part of DataTables. fnDeleteRow will actually permanently delete the row now :-)

    The function "prototype" in 1.7 beta is:

    [code]
    this.fnDeleteRow = function( mTarget, fnCallBack, bRedraw )
    [/code]
    Allan
  • jokkejokke Posts: 4Questions: 0Answers: 0
    thanks a bunch.
    That fixed it.

    You are welcome to remove what i am posting from here - don't know where i should post it, so i'll just do it here:

    I'm using a datatable with about 1500 entries and every tablerow is drawn with several inputs and selectors. Often I would like to display 100 or more entries consequently drawing the table is quite heavy. This becomes a problem when searching, so I have added a search button, so that you only search when clicking it or pressing enter - just going to leave the code here:

    [code]
    /*
    * Function: _fnFeatureHtmlFilter
    * Purpose: Generate the node required for filtering text
    * Returns: node
    * Inputs: object:oSettings - dataTables settings object
    */
    function _fnFeatureHtmlFilter ( oSettings )
    {
    var nFilter = document.createElement('div');
    var filterId = "undefined";
    if (oSettings.sTableId !== '' && typeof oSettings.aanFeatures.f == "undefined")
    {
    filterId = oSettings.sTableId + '_filter';
    nFilter.setAttribute( 'id', filterId );
    }
    nFilter.className = oSettings.oClasses.sFilter;
    var sSpace = oSettings.oLanguage.sSearch==="" ? "" : " ";
    nFilter.innerHTML = oSettings.oLanguage.sSearch + sSpace + '';

    var jqFilter = $('#' + filterId + '_TextField', nFilter);
    var jqFilterButton = $('#' + filterId + '_SearchButton', nFilter);

    jqFilter.val(oSettings.oPreviousSearch.sSearch.replace('"', '"'));
    jqFilter.keydown(function () {
    if (event.keyCode == 13) { $('#' + filterId + '_SearchButton').click(); return false; }
    });
    jqFilterButton.click(function () {
    /* Update all other filter input elements for the new display */
    var n = oSettings.aanFeatures.f;
    for ( var i=0, iLen=n.length ; i
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    A very useful addition! Not something I'll include in the core at the moment, but I'm sure others will be using this now that you've made it available. Thanks very much for sharing this with us :-)

    Regards,
    Allan
  • jokkejokke Posts: 4Questions: 0Answers: 0
    I'm not quite sure about this, but it seems that when deleting a single row, one or more of the "backend" arrays are reordered. Which means, if you have a collection of positions, some of your positions might be invalidated by the backend rebuilds after one row has been deleted.
    Is there something to this?

    Joakim
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Yes that is possible - depending on what you mean by 'positions'. When you delete a row, the aoData index (and therefore everything built off it) is altered - i.e. the row is actually removed. In 1.6 it was just nulled out so the indexes didn't change, but that prove to be a mistake in my design as it caused a bit of peoples for people trying to delete rows on occasion. It's best to get the new position (assuming you mean the aoData index) just before you do the delete, and not cache it for multiple deletes. Treat it like a DOM array, which would show exactly this as well.

    Allan
  • jokkejokke Posts: 4Questions: 0Answers: 0
    Thank you. I think that clarified it for me.
    Would it be an idea to make "fnRemoveData(aaData)" in a similar way as fnAddData(aaData)?
    At the moment I'm working with a datatable with over 2000 entries - each with about 30 fields. I have experienced that fnDeleteRow in a loop is detected as a slow script by both firefox and IE (those I've tested) and will bring up the are-you-sure-you-want-to-continue-to-run-this-script-dialog obnoxiously many times, whereas calling fnClearTable followed by fnAddData is not detected this way i.e. I'm adding over 2000 entries each time - and still this seems to perform better.

    Joakim
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Yes, creating a plug-in which tried to do this a little bit faster sounds like quite a good idea. I've added it to my to-do list. For the moment, ensuring the DataTables doesn't to a redraw on each delete is about as fast as it will go without some work on the plug-in.

    Allan
This discussion has been closed.