Permalink
Browse files

New: `ajax` parameter to control all aspects of Ajax that DataTables …

…uses

- DataTables 1.9 had 5 different parameters that controlled how Ajax
  data was obtained, which with its own naming properties, often mapping
  to the jQuery.ajax methods, or otherwise extending them. To hugely
  simply and extend the Ajax functionality DataTables has, these five
  parameters have now been deprecated and the funtionality provided by
  them merged into the new `ajax` parameter.

- Deprecated properties:
   - sAjaxSource
   - fnServerData
   - sAjaxDataProp
   - sServerMethod
   - fnServerParams

- Note that these parameters are still fully supported and can be used,
  but for new projects, `ajax` should be used as they will eventually be
  removed (likely DataTables v2 whenever that is, as they are too widely
  used to be removed in v1.x).

- Added additional / missing tests for the deprecated properties to
  ensure full backwards compatiblity

- The new `ajax` property is fully documented in the doc comments, but
  as a summary it can take three forms:
   - string - the url to get the data from (i.e. this is the new
     sAjaxSource)
   - object - maps directly to jQuery.ajax, allowing full control of the
     Ajax call (provides the abilities of fnServerParams, sServerMethod,
     sAjaxDataProp)
   - function - a function so you can get the data your own way
     (provides the abilities of fnServerData)

- Added unit tests for the new `ajax` property and doc comment examples
  updated to use this property exclusively.
  • Loading branch information...
DataTables committed Feb 10, 2013
1 parent fad7536 commit 2b6788011fbeeef3efa8df94bfd5b983852f25ce

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -21,7 +21,7 @@
*/
/*jslint evil: true, undef: true, browser: true */
-/*globals $,require,jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns,_fnHungarianMap,_fnCamelToHungarian*/
+/*globals $,require,jQuery,define,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns,_fnHungarianMap,_fnCamelToHungarian,_fnBuildAjax,_fnAjaxDataSrc*/
(/** @lends <global> */function( window, document, undefined ) {
@@ -45,7 +45,6 @@ this.oApi = {
"_fnAjaxUpdate": _fnAjaxUpdate,
"_fnAjaxParameters": _fnAjaxParameters,
"_fnAjaxUpdateDraw": _fnAjaxUpdateDraw,
- "_fnServerParams": _fnServerParams,
"_fnAddOptionsHtml": _fnAddOptionsHtml,
"_fnFeatureHtmlTable": _fnFeatureHtmlTable,
"_fnScrollDraw": _fnScrollDraw,
@@ -112,7 +111,9 @@ this.oApi = {
"_fnBrowserDetect": _fnBrowserDetect,
"_fnGetColumns": _fnGetColumns,
"_fnHungarianMap": _fnHungarianMap,
- "_fnCamelToHungarian": _fnCamelToHungarian
+ "_fnCamelToHungarian": _fnCamelToHungarian,
+ "_fnBuildAjax": _fnBuildAjax,
+ "_fnAjaxDataSrc": _fnAjaxDataSrc
};
$.extend( DataTable.ext.oApi, this.oApi );
View
@@ -1,4 +1,101 @@
+
+/**
+ * Create an Ajax call based on the table's settings, taking into account that
+ * parameters can have multiple forms, and backwards compatibility.
+ *
+ * @param {object} oSettings dataTables settings object
+ * @param {array} data Data to send to the server, required by
+ * DataTables - may be augmented by developer callbacks
+ * @param {function} fn Callback function to run when data is obtained
+ */
+function _fnBuildAjax( oSettings, data, fn )
+{
+ // Compatibility with 1.9-, allow fnServerData and event to manipulate
+ _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
+
+ var ajaxData;
+
+ if ( $.isPlainObject( oSettings.ajax ) && oSettings.ajax.data )
+ {
+ ajaxData = oSettings.ajax.data;
+ var newData = $.isFunction( ajaxData ) ?
+ ajaxData( data ) : // fn can manipulate data or return an object or array
+ ajaxData; // object or array to merge
+
+ if ( $.isArray( newData ) )
+ {
+ // name value pair objects in an array
+ data = data.concat( newData );
+ }
+ else if ( $.isPlainObject( newData ) )
+ {
+ // aData is an array of name value pairs at this point - convert to
+ // an object to easily merge data - jQuery will cope with the switch
+ var oData = {};
+ $.each( data, function (key, val) {
+ oData[val.name] = val.value;
+ } );
+
+ data = $.extend( true, oData, newData );
+ }
+
+ // Remove the data property as we've resolved it already
+ delete oSettings.ajax.data;
+ }
+
+ var baseAjax = {
+ "data": data,
+ "success": function (json) {
+ if ( json.sError ) {
+ oSettings.oApi._fnLog( oSettings, 0, json.sError );
+ }
+
+ $(oSettings.oInstance).trigger('xhr', [oSettings, json]);
+ fn( json );
+ },
+ "dataType": "json",
+ "cache": false,
+ "type": oSettings.sServerMethod,
+ "error": function (xhr, error, thrown) {
+ if ( error == "parsererror" ) {
+ oSettings.oApi._fnLog( oSettings, 0, "DataTables: invalid JSON response" );
+ }
+ }
+ };
+
+ if ( oSettings.fnServerData )
+ {
+ // DataTables 1.9- compatibility
+ oSettings.fnServerData.call( oSettings.oInstance,
+ oSettings.sAjaxSource, data, fn, oSettings
+ );
+ }
+ else if ( oSettings.sAjaxSource || typeof oSettings.ajax === 'string' )
+ {
+ // DataTables 1.9- compatibility
+ oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
+ url: oSettings.ajax || oSettings.sAjaxSource
+ } ) );
+ }
+ else if ( $.isFunction( oSettings.ajax ) )
+ {
+ // Is a function - let the caller define what needs to be done
+ oSettings.jqXHR = oSettings.ajax.call( oSettings.oInstance,
+ data, fn, oSettings
+ );
+ }
+ else
+ {
+ // Object to extend the base settings
+ oSettings.jqXHR = $.ajax( $.extend( baseAjax, oSettings.ajax ) );
+
+ // Restore for next time around
+ oSettings.ajax.data = ajaxData;
+ }
+}
+
+
/**
* Update the table using an Ajax call
* @param {object} oSettings dataTables settings object
@@ -13,12 +110,11 @@ function _fnAjaxUpdate( oSettings )
_fnProcessingDisplay( oSettings, true );
var iColumns = oSettings.aoColumns.length;
var aoData = _fnAjaxParameters( oSettings );
- _fnServerParams( oSettings, aoData );
-
- oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData,
- function(json) {
- _fnAjaxUpdateDraw( oSettings, json );
- }, oSettings );
+
+ _fnBuildAjax( oSettings, aoData, function(json) {
+ _fnAjaxUpdateDraw( oSettings, json );
+ }, oSettings );
+
return false;
}
return true;
@@ -95,18 +191,6 @@ function _fnAjaxParameters( oSettings )
}
-/**
- * Add Ajax parameters from plug-ins
- * @param {object} oSettings dataTables settings object
- * @param array {objects} aoData name/value pairs to send to the server
- * @memberof DataTable#oApi
- */
-function _fnServerParams( oSettings, aoData )
-{
- _fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [aoData] );
-}
-
-
/**
* Data the data from the server (nuking the old) and redraw the table
* @param {object} oSettings dataTables settings object
@@ -139,7 +223,7 @@ function _fnAjaxUpdateDraw ( oSettings, json )
oSettings._iRecordsTotal = parseInt(json.iTotalRecords, 10);
oSettings._iRecordsDisplay = parseInt(json.iTotalDisplayRecords, 10);
- var aData = _fnGetObjectDataFn( oSettings.sAjaxDataProp )( json );
+ var aData = _fnAjaxDataSrc( oSettings, json );
for ( var i=0, iLen=aData.length ; i<iLen ; i++ )
{
_fnAddData( oSettings, aData[i] );
@@ -152,3 +236,23 @@ function _fnAjaxUpdateDraw ( oSettings, json )
_fnProcessingDisplay( oSettings, false );
}
+
+/**
+ * Get the data from the JSON data source to use for drawing a table. Using
+ * `_fnGetObjectDataFn` allows the data to be sourced from a property of the
+ * source object, or from a processing function.
+ * @param {object} oSettings dataTables settings object
+ * @param {object} json Data source object / array from the server
+ * @return {array} Array of data to use
+ */
+function _fnAjaxDataSrc ( oSettings, json )
+{
+ var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
+ oSettings.ajax.dataSrc :
+ oSettings.sAjaxDataProp; // Compatibility with 1.9-.
+
+ return dataSrc !== "" ?
+ _fnGetObjectDataFn( dataSrc )(json) :
+ json;
+}
+
@@ -120,6 +120,7 @@ _fnMap( oSettings.oScroll, oInit, "bScrollInfinite", "bInfinite" );
_fnMap( oSettings.oScroll, oInit, "iScrollLoadGap", "iLoadGap" );
_fnMap( oSettings.oScroll, oInit, "bScrollAutoCss", "bAutoCss" );
_fnMap( oSettings, oInit, "asStripeClasses" );
+_fnMap( oSettings, oInit, "ajax" );
_fnMap( oSettings, oInit, "fnServerData" );
_fnMap( oSettings, oInit, "fnFormatNumber" );
_fnMap( oSettings, oInit, "sServerMethod" );
@@ -408,7 +409,7 @@ if ( bUsePassedData )
_fnAddData( oSettings, oInit.aaData[ i ] );
}
}
-else if ( oSettings.bDeferLoading || oSettings.sAjaxSource === null )
+else if ( oSettings.bDeferLoading || (oSettings.sAjaxSource === null && oSettings.ajax === null) )
{
/* Grab the data from the page - only do this when deferred loading or no Ajax
* source since there is no point in reading the DOM data if we are then going
@@ -64,13 +64,11 @@ function _fnInitialise ( oSettings )
}
/* if there is an ajax source load the data */
- if ( oSettings.sAjaxSource !== null && !oSettings.oFeatures.bServerSide )
+ if ( (oSettings.sAjaxSource || oSettings.ajax) && !oSettings.oFeatures.bServerSide )
{
var aoData = [];
- _fnServerParams( oSettings, aoData );
- oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData, function(json) {
- var aData = (oSettings.sAjaxDataProp !== "") ?
- _fnGetObjectDataFn( oSettings.sAjaxDataProp )(json) : json;
+ _fnBuildAjax( oSettings, [], function(json) {
+ var aData = _fnAjaxDataSrc( oSettings, json );
/* Got the data - add it to the table */
for ( i=0 ; i<aData.length ; i++ )
@@ -158,7 +158,7 @@ function _fnMap( oRet, oSrc, sName, sMappedName )
* Extend objects - very similar to jQuery.extend, but deep copy objects, and shallow
* copy arrays. The reason we need to do this, is that we don't want to deep copy array
* init values (such as aaSorting) since the dev wouldn't be able to override them, but
- * we do want to deep copy arrays.
+ * we do want to deep copy objects.
* @param {object} oOut Object to extend
* @param {object} oExtender Object from which the properties will be applied to oOut
* @returns {object} oOut Reference, just for convenience - oOut === the return.
@@ -175,8 +175,12 @@ function _fnExtend( oOut, oExtender )
{
val = oExtender[prop];
- if ( typeof oExtender[prop] === 'object' && val !== null && $.isArray(val) === false )
+ if ( $.isPlainObject( val ) )
{
+ if ( ! oOut[prop] )
+ {
+ oOut[prop] = {};
+ }
$.extend( true, oOut[prop], val );
}
else
Oops, something went wrong.

0 comments on commit 2b67880

Please sign in to comment.