User selectable rows (multiple rows) with Server side processing

User selectable rows (multiple rows) with Server side processing

iuliandumiuliandum Posts: 70Questions: 0Answers: 0
edited September 2009 in General
I want a table with server side processing but with User selectable rows (multiple rows) features.
With server side table when change current page and when come back, the first selection disappear.
Thanks!


[code]
oTable = $("#example").dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "../examples_support/server_processing_post.php",
"fnServerData": function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": fnCallback
} );
},
"fnDrawCallback": function ( oSettings ) {
$('#example tbody tr').each( function () {
$(this).click( function () {
if ( $(this).hasClass('row_selected') ) {
$(this).removeClass('row_selected');
}
else {
$(this).addClass('row_selected');
var iPos = oTable.fnGetPosition( this );
var aData = oTable.fnGetData( iPos );
var iId = aData[0];
}
} );
} );
}
} );
[/code/

Replies

  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    The example of user selectable rows makes use of the fact that DataTables will retain applied classes names etc for data found from the DOM, a JS array of a JSON file. However, this doesn't hold true in server-side processing, since DataTables has no idea what are on any of the other pages - that's all handled by the server-side script. As such, the TR elements for the table are dynamically created on each row - and thus classes etc are not retained.

    Therefore, in order to do user selectable rows with server-side processing, you'll need to use a different method. The obvious one that springs to mind is having a column with a unique ID, and you can maintain an array of the row IDs which have been selected.

    Hope this helps,
    Allan
  • iuliandumiuliandum Posts: 70Questions: 0Answers: 0
    edited September 2009
    Thanks for answer! and Thanks very much for this application!

    Yes, at this solution i am thinking. Respectively,to put in the table an ID hidden column and save in an array each row selected. But I don't know how to make to select a row (and how select all rows from current page).
    I am a novice into Object-oriented programming and JQuery. Maybe you show me an example cod.

    Thanks,
    iuliandum
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    Hi iuliandum,

    Selecting a row would be very similar to me demo code, where an event handler is applied to the TR elements and will act as the 'select', adding (or removing) an entry from the array containing the selected IDs.

    I don't really do example code for this kind of thing, as I believe it's much more instructive for one to learn by working through it :-). Between the ideas in this thread and my demo code, there is quite a bit to be getting on with!

    Regards,
    Allan
  • iuliandumiuliandum Posts: 70Questions: 0Answers: 0
    edited September 2009
    OK!
    Working!
    This is code:
    Allan, please input this table in the "Server-side processing" example with the name "User selectable rows (multiple rows) ". Maybe another user like to use.
    Thank you and Congratulations! You are a genius!


    [code]
    var oTable;
    var selected = new Array();


    $(document).ready(function() {
    $('#form').submit( function() {
    alert (selected);
    return false;
    } );

    /* Init the table */
    oTable = $("#example").dataTable({
    "bProcessing": true,
    "bServerSide": true,
    "sAjaxSource": "../examples_support/server_processing_post.php",
    "fnServerData": function ( sSource, aoData, fnCallback ) {
    $.ajax( {
    "dataType": 'json',
    "type": "POST",
    "url": sSource,
    "data": aoData,
    "success": fnCallback
    } );
    },
    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
    $('#example tbody tr').each( function () {
    if (jQuery.inArray(aData[0], selected)!=-1) {
    $(this).addClass('row_selected');
    }
    });
    return nRow;
    },
    "fnDrawCallback": function ( oSettings ) {
    $('#example tbody tr').each( function () {
    var iPos = oTable.fnGetPosition( this );
    if (iPos!=null) {
    var aData = oTable.fnGetData( iPos );
    if (jQuery.inArray(aData[0], selected)!=-1)
    $(this).addClass('row_selected');
    }
    $(this).click( function () {
    var iPos = oTable.fnGetPosition( this );
    var aData = oTable.fnGetData( iPos );
    var iId = aData[0];
    is_in_array = jQuery.inArray(iId, selected);
    if (is_in_array==-1) {
    selected[selected.length]=iId;
    }
    else {
    selected = jQuery.grep(selected, function(value) {
    return value != iId;
    });
    }
    if ( $(this).hasClass('row_selected') ) {
    $(this).removeClass('row_selected');
    }
    else {
    $(this).addClass('row_selected');
    }
    });
    });
    }
    });
    } );
    [/code]
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    Hi iuliandum,

    Nice one! That is outstanding, and thanks for sharing it with us :-)

    I have indeed posted this as an example on the site: http://datatables.net/examples/server_side/select_rows.html as I'm sure this will provide most useful for people - not only for this specific case, but how state can be retained over DataTables operations with server-side processing. I have made one or two slight changes to your code to simplify here and there, and to keep it in the same style as the other demo code (simply for consistency).

    Excellent stuff.

    Regards,
    Allan
  • iuliandumiuliandum Posts: 70Questions: 0Answers: 0
    Hi Allan!
    I ask you if it fast working to use this code.
    [code]
    "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
    var iPos = oTable.fnGetPosition( nRow );

    if ( jQuery.inArray(aData[0], gaiSelected) != -1 )
    {
    $(nRow).addClass('row_selected');
    }

    if ( iPos != null )
    {
    var aData = oTable.fnGetData( iPos );
    if ( jQuery.inArray(aData[0], gaiSelected) != -1 )
    {
    $(this).addClass('row_selected');
    }
    }

    $(nRow).click( function () {
    var iPos = oTable.fnGetPosition( nRow );
    var aData = oTable.fnGetData( iPos );
    var iId = aData[0];

    if ( jQuery.inArray(iId, gaiSelected) == -1 )
    {
    gaiSelected[gaiSelected.length++] = iId;
    }
    else
    {
    gaiSelected = jQuery.grep(gaiSelected, function(value) {
    return value != iId;
    } );
    }

    $(nRow).toggleClass('row_selected');
    });
    return nRow;
    }
    [/code]
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    Hi iuliandum,

    Sorry, I'm not quite sure I understand. Are you asking if this code is more optimised? It looks fine to me on a quick scan, but the best way to tell is to load it up using Firebug and enable profiling. Do it a number of times and take an average.

    Regards,
    Allan
  • jemisonjemison Posts: 21Questions: 0Answers: 0
    Hi, Allan,
    I'm trying to follow on this example, I'm trying to send the Ids of the selected rows to the server and then remove those rows on the client side.
    [code]
    $('#process').click( function() {
    if(gaiSelected == ''){
    alert ("Please select at least one row ");
    return false;
    }
    else{
    $.getJSON('/products/iprocess?id='+gaiSelected+'&ajax=true');
    return false;
    }
    } );[/code]
    this part seems to work, I'm not sure it's the best way, but I can get the data on the server, but I tried to remove the selected rows like this, but it didn't work:
    [code]
    var anSelected = fnGetSelected( oTable );
    for (var i=0 ; i
  • jemisonjemison Posts: 21Questions: 0Answers: 0
    can someone sees why fnDeleteRow is not deleting the selected rows like in this example mention above?
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    Hi jemison,

    Yes indeed - I suspect it's because you are using server-side processing. The interaction API functions (add row / delete row etc) that are built into DataTables aren't designed to work with server-side processing since the work ont he client-side only. What you need to do is send a request to the server to delete the row and then re-draw the table once it has been removed from the database (so it doesn't show up again).

    What I am guessing is happening at the moment is that DataTables deletes the row as required on the client-side, but issues a draw update request to the server, which doesn't know that the row has been deleted, so the re-draw shows the row again!

    Regards,
    Allan
  • Jens GutzeitJens Gutzeit Posts: 22Questions: 0Answers: 0
    Not sure if this is the right topic, but there's also a little bug in the documentation regarding row-selection and serverside. The rows arent available when Jquery tries to bind the click-event on them, there should be a note in the documentation for the .live() method of JQuery: http://docs.jquery.com/Events/live#typefn which is obviously better suited for dealing with all kind of "on the fly node-creation".
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    Hi Jens,

    Thanks for your note. You are quite correct - live event handling in jQuery is perfect for this kind of scenario. The example was written for jQuery 1.2 which was before the live events were introduced in 1.3. I'll update the example at some point soon to use live events, which should result in a much cleaner execution of the example.

    Regards,
    Allan
  • semseosemseo Posts: 9Questions: 0Answers: 0
    Hi,

    Is there a way to make the Table Tools "Select All" button work with this feature? I have tried to make a button to do it but without success. I think it must involve the code below but I don't know how to finish it off?
    [code]
    "sRowSelect": "multi",
    "aButtons": [
    {
    "sExtends": "select_all",

    "fnClick": function ( nButton, oConfig, oFlash ) {
    //alert( 'Mouse click' );

    // select all
    var oTT = TableTools.fnGetInstance( 'propertyList' );
    oTT.fnSelectAll();

    /* add or remove values from: */ gaiSelected

    toggleClass('row_selected'); // for all visible rows.

    [/code]
  • schnibitzschnibitz Posts: 15Questions: 0Answers: 0
    edited January 2012
    All, is this code still working? I tried pasting it into one of my pages and it made a previous working table stop working. Any ideas?

    -S
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    @schnibitz: You mean this code: http://datatables.net/release-datatables/examples/server_side/select_rows.html ? Looks like it is working in the demo to me :-)

    Allan
  • schnibitzschnibitz Posts: 15Questions: 0Answers: 0
    Yes, that's the one, sorry I forgot to put that in my question. Must be something I'm doing wrong then since it's not working for me yet.

    I wonder if selectable rows will work with rows that are set to reload as described here:

    http://datatables.net/forums/discussion/5886/trying-to-reload-data-at-setinterval-but-failing-miserably/p1

    I implemented the final bit of code he has at the end, and it works PERFECTLY, but I noticed when I select some of the text on the rows (as if I'm going to copy it ), the selection disappears during the refresh. Makes me wonder if selecting and deleting rows is even possible with the refresh code, because I wonder if a selection will even hold after a refresh.
  • allanallan Posts: 61,839Questions: 1Answers: 10,134 Site admin
    > but I noticed when I select some of the text on the rows (as if I'm going to copy it ), the selection disappears during the refresh

    That is because when a refresh occurs, the DOM elements in the table (when using server-side processing) are destroyed, and new ones created. Hence the text you had selected before no longer exists! Row select gets around this by caching information about which rows are selected and then reselecting them on the redraw.

    In theory it might be possible to get the current text selection and then try to select it and after a redraw, but I don't know if browsers allow that capability. The other option might be to not do the data refresh if some text is selected.

    Allan
  • schnibitzschnibitz Posts: 15Questions: 0Answers: 0
    Cool, I didn't see your comment until just now, thank you for the input, although that might be a little beyond my capabilities at the moment.

    Thank you,
    -S
  • xfloydxfloyd Posts: 35Questions: 12Answers: 1
    First of course let me congratulate you on this slick project.
    I implemented example http://datatables.net/release-datatables/examples/server_side/select_rows.html and it works great. But I’m in need of Select/Deselect All and I’m lost. I also implemented TableTool example that already has Select/Deselect All nicely build in and it is even greater, but it does not support server-side, so I can only deal with one page at the time. The big question is how to combine the two examples if possible, and if not then how to implement select all for the first example.
    I created a mockup of what I’m talking about http://portal.iasclaims.com/testing/admin/test3.php
    It has both examples there already with server side working, if someone could point me in the right direction that would be great.
  • congaconga Posts: 1Questions: 0Answers: 0
    Dear,
    Your posts help me very much, however I want to control the parameters to submit to server. When I change to GET method, it shows only a meaningless parameter named: delete?example_length=10
    Thanks a lot for your help.
  • drc83drc83 Posts: 11Questions: 0Answers: 0
    Hi,

    I have had a look at the example on:

    http://datatables.net/release-datatables/examples/server_side/select_rows.html

    as the rows are selected the id's are strung together and the separator is a comma but is there an easy way to change the separator I would like to use | as I am going to use text as the id instead of a number?

    Thanks
This discussion has been closed.