Using a POST instead of a GET, but a GET is still sent initially...

Using a POST instead of a GET, but a GET is still sent initially...

dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
edited June 2009 in General
I've setup my datatables to use a POST instead of a GET for the ajax call, but when my web page is first loaded, it uses a GET (according to FireBug) to try and retrieve the info via ajax. I'm using version 1.5 beta 8 of datatables.

I have a select box on my web page that when it is changed, reloads the data in the table using my criteriaChanged function and a fnReloadAjax function I found on here (modified to do a POST instead of a GET). These work correctly and send a POST.

Any idea why when my page initially loads it is sending the ajax request as a GET? Thanks in advance for the help.

Here is another topic that is essentially what I'm doing (Retrieve new dataset via select element):
http://datatables.net/forums/comments.php?DiscussionID=175

[code]
var oTable;
var oSettings;


$j(document).ready(function(){
//Check to see if an admin Type was passed in, if not go to the first value
if ("${adminList.adminType}" != "") {
//Select the passed in value in the selection box
$j("#adminListType").val("${adminList.adminType}");
}
else { //Select the first option
$j("#adminListType option:eq(0)").val();
}

oTable = $j('#adminTable').dataTable( {
"bPaginate": true,
"bLengthChange": true,
"iDisplayLength": 25,
"bProcessing": true,
"bStateSave": true,
"bFilter": true,
"bSort": true,
"bInfo": true,
"sPaginationType": 'full_numbers',
"bAutoWidth": true,
"sAjaxSource": '${adminList.jsonURL}',
"aoColumns": [
null,
{ "sType": "html" },
null
],
"fnServerData": function ( sSource, aoData, fnCallback ) {
aoData.push( { "name": "adminType", "value": $j('#adminListType').val() } );
$j.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": fnCallback
});
}
});
});

$j.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, sAdminType )
{
if ( typeof sNewSource != 'undefined' )
{
oSettings.sAjaxSource = sNewSource;
}
this.fnClearTable( this );
this.oApi._fnProcessingDisplay( oSettings, true );
var that = this;
oSettings.aoData.push( { "name": "adminType", "value": sAdminType } );

$j.ajax( {
"dataType": 'json',
"type": "POST",
"url": oSettings.sAjaxSource,
"data": oSettings.aoData,
"success": function(json) {
/* Got the data - add it to the table */
for ( var i=0 ; i

Replies

  • dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
    ok, here's some more info. I found that if I include "bServerSide": true, when initially setting up the datatable, that it will initially send a POST instead of a GET. The problem with doing this is that now for everything (search, sort, etc.) it's going back to the server with a new POST. I only want it to send a post when initialized (or when my select box changes).

    I think it boils down to me trying to do a POST without serverside processing. I'm not sure if this a feature or a bug. Any ideas?
  • dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
    edited June 2009
    I think I found the problem. It appears the "fnServerData" function included in the initialization of the DataTable is only called if "bServerSide": true is included. I need/want it to be called if "bServerSide":false is included (or not defined). Is there a reason that this is this way?

    I created a work around by modifying the datatables.js file. It probably isn't the best (duplicate code to add the data returned in JSON format to the table), but it works. In the "_fnInitalise" function I added some code to check if the "fnServerData" function was defined. Here's the new version with the new stuff commented.

    [code]
    /*
    * Function: _fnInitalise
    * Purpose: Draw the table for the first time, adding all required features
    * Returns: -
    * Inputs: object:oSettings - dataTables settings object
    */
    function _fnInitalise ( oSettings )
    {
    /* Ensure that the table data is fully initialised */
    if ( oSettings.bInitialised === false )
    {
    setTimeout( function(){ _fnInitalise( oSettings ); }, 200 );
    return;
    }

    /* Show the display HTML options */
    _fnAddOptionsHtml( oSettings );

    /* Draw the headers for the table */
    _fnDrawHead( oSettings );

    /* If there is default sorting required - let's do it. The sort function
    * will do the drawing for us. Otherwise we draw the table
    */
    if ( oSettings.oFeatures.bSort )
    {
    _fnSort( oSettings, false );
    /*
    * Add the sorting classes to the header and the body (if needed).
    * Reason for doing it here after the first draw is to stop classes being applied to the
    * 'static' table.
    */
    _fnSortingClasses( oSettings );
    }
    else
    {
    oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
    _fnCalculateEnd( oSettings );
    _fnDraw( oSettings );
    }

    /* if there is an ajax source */
    if ( oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
    {
    _fnProcessingDisplay( oSettings, true );

    //*** Start of NEW
    if ( typeof oSettings.fnServerData == 'function' )
    {
    oSettings.fnServerData( oSettings.sAjaxSource, oSettings.aoData, function(json) {
    /* Got the data - add it to the table */
    for ( var i=0 ; i
  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Hi dgtaylor22,

    Sorry for the delay in getting back to you about this. It looks like you have a fix in place for what you want, but basically if you want to use server-side processing then you should set bServerSide: true. Server-side processing is a feature in DataTables and it needs to be enabled (it is off by default since DataTables tends to focus on progressive enhancement).

    A typical way of having server-side processing with DataTables is shown in this example: http://datatables.net/1.5-beta/examples/data_sources/server_side.html (there is also a post example http://datatables.net/1.5-beta/examples/server_side/post.html where you will be able to see that all Ajax requests are POST methods).

    I would very much recommend using the single "bServerSide: true" in your initialisation code rather than the change to DataTables core, in order that your code will remain compatible with future versions.

    Hope this helps to explain the situation.

    Regards,
    Allan
  • dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
    Thanks for getting back to me. Actually I do NOT want to do server side processing. I want all the data coming down initially and then letting the table do its thing (sorting, filtering, etc). The problem is that I want to do a POST to retrieve the data via JSON format, but if bServerSide is set to false, then the fnServerData function that I've declared to do the POST is ignored/never called when the table is initiallized.

    My "fix" gets around this, but it could cause other problems (my fix is kind of brute force), and I'd prefer not to modify the core code. Any further insight to doing a POST with bServerSide set to false is welcome. Thanks for your help.

    Dave
  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Ah ha - I see! Sorry for the misunderstanding.

    I was confused because I was not expecting fnServerData() to be used for anything other than server-side processing, and you mentioned that it was doing multiple Ajax requests.

    What I would suggest you do, if you need POST rather than GET (I presume you are sending some variables to the server?) is that you make use of $.ajax() and make the Ajax request yourself with the POST, and then give DataTables the returned data in aaData (or fnAddData() if you want to initialise the table immediately). I wasn't really expecting anyone to want to override the standard DataTables Ajax source method, but this is probably the best way of doing it without modifying the source.

    Allan
  • dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
    Thanks for pointing me in the correct direction. I solved this without having to modify the core code. What ultimately was causing me problems was setting sAjaxSource during the initialization. Because sAjaxSource is set and bServerSide is false, datatables sends a GET request to the specified URL and ignored my fnServerData function which I wanted to send a POST during initialization. I will post my cleaned up code and explanation of what I'm doing later today or Monday in case anybody else is trying to do something similar.

    Thanks for a great tool and the best support I've ever received!!!
  • dgtaylor22dgtaylor22 Posts: 16Questions: 0Answers: 0
    edited June 2009
    Ok here is my problem and solution.

    Problem:
    I have a web page with a drop down list box (select) and based on the value in the listbox, I'll get different data and display it in a datatable. I want to send a POST (instead of a GET) to retrieve the data in JSON format. I don't want to do server side processing so I'm going to retrieve all the data at one time and let the datatable take care of sorting, filtering, and pagination.

    Solution:
    To do this when initializing the datatable, I leave off the sAjaxSource and bServerSide values to use their default values of null and false respectively. If sAjaxSource is set, then a GET is done during initialization. After the code to initialize the datatable, I call my function that is triggered when the listbox selection changes. This function gets the settings and calls the custom API function fnReloadAjax which I've modified from Allan's original version to do a POST (using jquery's $.ajax).

    It is working for me and hopefully this can help somebody else. Thanks to Allan for his great table and quick response to my questions.

    Here's the guts of my HTML page
    [code]











    var oTable;
    var oSettings;

    $(document).ready(function(){
    //Check to see if an admin Type was passed in, if not go to the first value
    if ("${adminList.adminType}" != "") {
    //Select the passed in value in the selection box
    $("#adminListType").val("${adminList.adminType}");
    }
    else { //Select the first option
    $("#adminListType option:eq(0)").val();
    }

    oTable = $('#adminTable').dataTable( {
    "bPaginate": true,
    "bLengthChange": true,
    "iDisplayLength": 25,
    "bProcessing": true,
    "bStateSave": true,
    "bFilter": true,
    "bSort": true,
    "bInfo": true,
    "sPaginationType": 'full_numbers',
    "bAutoWidth": true,
    "aoColumns": [
    { "sType": "html" },
    { "sType": "html" },
    null
    ]
    });

    //This functions gets the data via a POST
    criteriaChanged($('#adminListType').val());
    });

    $.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, sAdminType )
    {
    if ( typeof sNewSource != 'undefined' )
    {
    oSettings.sAjaxSource = sNewSource;
    }
    this.fnClearTable( this );
    this.oApi._fnProcessingDisplay( oSettings, true );
    var that = this;
    oSettings.aoData.push( { "name": "adminType", "value": sAdminType } );

    $.ajax( {
    "dataType": 'json',
    "type": "POST",
    "url": oSettings.sAjaxSource,
    "data": oSettings.aoData,
    "success": function(json) {
    // Got the data - add it to the table
    for ( var i=0 ; i








    IDSummaryDetails



    IDSummaryDetails





    [/code]
  • allanallan Posts: 61,446Questions: 1Answers: 10,054 Site admin
    Hi dgtaylor22,

    That looks absolutely superb - thanks very much for sharing your source with us! I'm sure others will find it useful as well.

    Regards,
    Allan
This discussion has been closed.