admin管理员组

文章数量:1327524

I have two DataTables objects on a page, lets call them searchResultsTable and currentPortfolioTable. I'm using the fnReloadAjax plugin to reload the DataTables on demand when I click a button. However only one of the tables loads the new data (currentPortfolioTable), searchResultsTable does perform the ajax requests for the data but fails to load the new (and valid) data into the table.

I've attempted destroying the DataTable and creating a new one and even rewrote parts of the fnReloadAjax plugin to see if I could produce a different result.

Even when only fnReloadAjax is called for the currentPortfolioTable it refuses to display the new data loaded.

The problem of the searchResultsTable failing to load new data also occurs on showing/hiding columns using the bVisible state of the aoColumns property of the DataTable.

Sample Code:

var dataTableObjects = dataTableObjects || {
    "searchResultsTable": {},
    "currentPortfolioTable": {}
};

var _rankingsRootUrl = window.ROOT + 'rankings/';

var _defaultDataTableSettings = {
    "aoColumns": [
        {   "bSortable": false,
            "sTitle": "Add to Portfolio",
            "bVisible": true
        },
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'search_results/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "program_type", "value": $(':input#RankingProgramType').val()},
            {"name": "program_name", "value": $(':input#RankingProgramName').val()},
            {"name": "min_investment", "value": $(':input#RankingMinimumInvestment').val()},
            {"name": "rate_of_return", "value": $(':input#RankingRateOfReturn').val()},
            {"name": "max_dd", "value": $(':input#RankingMaxDd').val()},
            {"name": "time_span", "value": $(':input#RankingTimeSpan').val()},
            {"name": "flags", "value": $(':input#RankingFlags').val()},
            {"name": "strategies", "value": $(':input#RankingStrategies').val()},
            {"name": "remended", "value": $(':input#RankingRemended').val()},
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

var _defaultCurrentPortfolioTableSettings = {
    "aoColumns": [
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'current_portfolio/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

dataTableObjects.searchResultsTable = $('#search-results table').dataTable(_defaultDataTableSettings);
dataTableObjects.currentPortfolioTable = $('#currently-in-portfolio table').dataTable(_defaultCurrentPortfolioTableSettings);

$("#rankings").on("click", "a.add", function (e){
   dataTableObjects.searchResultsTable.fnReloadAjax('/datable1-url');
   dataTableObjects.currentPortfolioTable.fnReloadAjax('/datable2-url');
   e.preventDefault();
});

Attempted Fixes:

  • Using callback method from fnReloadAjax to fire the reloading of data for dataTable2
  • Verifying that the ids for each table is unique
  • Verifying that the dataTableJSObjects are the correct and unique tables for the page
  • Console records no errors or issues
  • JShinted js to ensure no js errors or mistakes
  • Turned off fnReloadAjax dataTableObjects.searchResultsTable and dataTableObjects.currentPortfolioTable still does not reload correctly
  • Replaced using fnReloadAjax with fnDraw

I have two DataTables objects on a page, lets call them searchResultsTable and currentPortfolioTable. I'm using the fnReloadAjax plugin to reload the DataTables on demand when I click a button. However only one of the tables loads the new data (currentPortfolioTable), searchResultsTable does perform the ajax requests for the data but fails to load the new (and valid) data into the table.

I've attempted destroying the DataTable and creating a new one and even rewrote parts of the fnReloadAjax plugin to see if I could produce a different result.

Even when only fnReloadAjax is called for the currentPortfolioTable it refuses to display the new data loaded.

The problem of the searchResultsTable failing to load new data also occurs on showing/hiding columns using the bVisible state of the aoColumns property of the DataTable.

Sample Code:

var dataTableObjects = dataTableObjects || {
    "searchResultsTable": {},
    "currentPortfolioTable": {}
};

var _rankingsRootUrl = window.ROOT + 'rankings/';

var _defaultDataTableSettings = {
    "aoColumns": [
        {   "bSortable": false,
            "sTitle": "Add to Portfolio",
            "bVisible": true
        },
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'search_results/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "program_type", "value": $(':input#RankingProgramType').val()},
            {"name": "program_name", "value": $(':input#RankingProgramName').val()},
            {"name": "min_investment", "value": $(':input#RankingMinimumInvestment').val()},
            {"name": "rate_of_return", "value": $(':input#RankingRateOfReturn').val()},
            {"name": "max_dd", "value": $(':input#RankingMaxDd').val()},
            {"name": "time_span", "value": $(':input#RankingTimeSpan').val()},
            {"name": "flags", "value": $(':input#RankingFlags').val()},
            {"name": "strategies", "value": $(':input#RankingStrategies').val()},
            {"name": "remended", "value": $(':input#RankingRemended').val()},
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

var _defaultCurrentPortfolioTableSettings = {
    "aoColumns": [
        {
            "bSortable": true,
            "sTitle": "Name of Investment",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Chart",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Rating",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "Minimum",
            "bVisible": true
        },
        {   "bSortable": true,
            "sTitle": "ROR",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Max DD",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sharpe",
            "bVisible": false
        },
        {   "bSortable": true,
            "sTitle": "Sterling",
            "bVisible": false
        }
    ],
    "aaSorting": [
    ],
    "sAjaxSource": _rankingsRootUrl + 'current_portfolio/',
    "bServerSide": true,
    "bProcessing": true,
    "bPaginate": false,
    "bLengthChange": false,
    "sScrollY": 200,
    "sScrollX": "100%",
    "sScrollXInner": "100%",
    "bScrollCollapse": true,
    "fnServerData": function ( sSource, aoData, fnCallback ) {
        $.ajax( {
            "dataType": 'json',
            "type": "POST",
            "url": sSource,
            "data": aoData,
            "success": fnCallback
        } );
    },
    "fnServerParams": function ( aoData ) {
        aoData.push(
            {"name": "portfolio_id", "value": (window.PORTFOLIO && window.PORTFOLIO.id) || ""}
        );
    }
};

dataTableObjects.searchResultsTable = $('#search-results table').dataTable(_defaultDataTableSettings);
dataTableObjects.currentPortfolioTable = $('#currently-in-portfolio table').dataTable(_defaultCurrentPortfolioTableSettings);

$("#rankings").on("click", "a.add", function (e){
   dataTableObjects.searchResultsTable.fnReloadAjax('/datable1-url');
   dataTableObjects.currentPortfolioTable.fnReloadAjax('/datable2-url');
   e.preventDefault();
});

Attempted Fixes:

  • Using callback method from fnReloadAjax to fire the reloading of data for dataTable2
  • Verifying that the ids for each table is unique
  • Verifying that the dataTableJSObjects are the correct and unique tables for the page
  • Console records no errors or issues
  • JShinted js to ensure no js errors or mistakes
  • Turned off fnReloadAjax dataTableObjects.searchResultsTable and dataTableObjects.currentPortfolioTable still does not reload correctly
  • Replaced using fnReloadAjax with fnDraw
Share Improve this question edited Apr 30, 2012 at 14:14 Justin Yost asked Apr 25, 2012 at 14:19 Justin YostJustin Yost 2,34019 silver badges31 bronze badges 9
  • What is the AJAX response you get back for the second table? Is it the expected data or a server error? – Jeff Commented Apr 25, 2012 at 14:24
  • Expected and valid data. – Justin Yost Commented Apr 25, 2012 at 14:48
  • The only thing that es to mind is that maybe your selector is wrong, or maybe there are duplicate ids on the page. – Jeff Commented Apr 25, 2012 at 14:54
  • 1 if you reverse the order of the fnReloadAjax calls, is it the second call that breaks, or is it still dataTable2 that breaks? – jimmym715 Commented Apr 25, 2012 at 19:47
  • 1 and what if the reload of dataTable1 is mented out so only dataTable2 is reloaded? is there still an issue? If so, then it's likely that there's simply an issue with the configuration of dataTable2, rather than there being an issue with conflicts between the two dataTables, and Firebug (or some similar tool) is probably your best bet for tracking down the problem. However, if reloading only dataTable2 works fine on its own, then... well... I guess I'd have to see more code details to be of any help – jimmym715 Commented Apr 27, 2012 at 17:58
 |  Show 4 more ments

4 Answers 4

Reset to default 4

Thanks for posting the extra source code details. I think I may have found the issue...

In the description of the fnReloadAjax plugin, Allan Jardine added the following note:

Note: To reload data when using server-side processing, just use the built-in API function fnDraw rather than this plug-in.

Now, while I realize that you've confirmed that data being requested from /datable1-url and /datable2-url is correct and that the first data table is even reloading properly when using fnReloadAjax; however, in light of Allan's note, and for lack of a better answer because of the mysterious nature of the problem, I'd say that it's likely that the problem with your current implementation is indeed due to fnReloadAjax not being the appropriate solution for the way you have your tables configured.

I also realize, though, that simply changing fnReloadAjax to fnDraw, as the tables are set up right now, is not going to solve your problem...time to get tricky...

Here's my solution:

Start by adding these two lines to the top of your script:

var isInitialLoadTable1 = true;
var isInitialLoadTable2 = true;

Next, in each of the dataTable settings variables, add the following additional callback after the fnServerParams callback:

"fnInitComplete": function( oSettings, json ) {
    isInitialLoadTable1 = false;
}

Make sure to change isInitialLoadTable1 to initialLoadTable2 in the second table [and don't forget the ma after the end brace for fnServerParams :-) ]

Now for the trickiness... in the fnServerData callback change the url setting of the $.ajax call like so:

"url": (isInitialLoadTable1 ? sSource : '/datable1-url'),

Again, be sure to change both of the 1's to 2's in this statement for the second dataTable

Finally, change your click event to the following:

$("#rankings").on("click", "a.add", function (e) {
    dataTableObjects.searchResultsTable.fnDraw();
    dataTableObjects.currentPortfolioTable.fnDraw();
    e.preventDefault();
});

Now, I haven't tested this, but the real test lies with your code and your data.

Hopefully, this solves the problem.

One thought is that calling fnReloadAjax consecutively on two different tables may be causing conflicts for dataTable2 that it wouldn't experience if it waited for dataTable 1 to finish loading.

The fnReloadAjax function accepts a callback parameter that may help...

For example:

dataTableObjects.dataTable1 = $('#search-results table').dataTable();
dataTableObjects.dataTable2 = $('#currently-in-portfolio table').dataTable();

$("#rankings").on("click", "a.add", function (e){
    dataTableObjects.dataTable1.fnReloadAjax('/datable1-url', null, reloadDataTable2, false);
    e.preventDefault();
});

// outside of the "ready" block
var reloadDataTable2 = function () {
    dataTableObjects.dataTable2.fnReloadAjax('/datable2-url');
};

I haven't tested this, so I don't know for sure that it will work.

However, I saw this question while searching for a solution to one of my own problems, and I thought I'd offer this idea. Hope this helps.

I've just put an example together which shows that it should work just fine: http://live.datatables/aqazek/edit#javascript,html . I've made a tiny adjustment to fnReloadAjax so you can see the effect of the reload on my static data source (just rewrite one of the cells with a counter), but other than that - no changes from the DataTables site.

So I think to offer any further assistance we'd need to see an example of it not working.

The solution to this specific problem was that the data returned for the dataTableObjects.currentPortfolioTable included the value sEcho which is used by DataTable for pagination of data, ie, which page of data this is. The sEcho can be seen in the example usage of DataTables with Server Side Data.

The sEcho value for dataTableObjects.currentPortfolioTable was always set to 1, which apparently caused DataTables to always think that the data was still the original set of data and not new data. Incrementing sEcho to the value passed back in the AJAX request for the new data fixed the issue.

本文标签: