1 |
/** |
2 |
* Add a data array to the table, creating DOM node etc. This is the parallel to |
3 |
* _fnGatherData, but for adding rows from a Javascript source, rather than a |
4 |
* DOM source. |
5 |
* @param {object} oSettings dataTables settings object |
6 |
* @param {array} aData data array to be added |
7 |
* @returns {int} >=0 if successful (index of new aoData entry), -1 if failed |
8 |
* @memberof DataTable#oApi |
9 |
*/ |
10 |
function _fnAddData ( oSettings, aDataSupplied ) |
11 |
{ |
12 |
var oCol; |
13 |
|
14 |
/* Take an independent copy of the data source so we can bash it about as we wish */ |
15 |
var aDataIn = ($.isArray(aDataSupplied)) ? |
16 |
aDataSupplied.slice() : |
17 |
$.extend( true, {}, aDataSupplied ); |
18 |
|
19 |
/* Create the object for storing information about this new row */ |
20 |
var iRow = oSettings.aoData.length; |
21 |
var oData = $.extend( true, {}, DataTable.models.oRow ); |
22 |
oData._aData = aDataIn; |
23 |
oSettings.aoData.push( oData ); |
24 |
|
25 |
/* Create the cells */ |
26 |
var nTd, sThisType; |
27 |
for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) |
28 |
{ |
29 |
oCol = oSettings.aoColumns[i]; |
30 |
|
31 |
/* Use rendered data for filtering / sorting */ |
32 |
if ( typeof oCol.fnRender === 'function' && oCol.bUseRendered && oCol.mData !== null ) |
33 |
{ |
34 |
_fnSetCellData( oSettings, iRow, i, _fnRender(oSettings, iRow, i) ); |
35 |
} |
36 |
else |
37 |
{ |
38 |
_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) ); |
39 |
} |
40 |
|
41 |
/* See if we should auto-detect the column type */ |
42 |
if ( oCol._bAutoType && oCol.sType != 'string' ) |
43 |
{ |
44 |
/* Attempt to auto detect the type - same as _fnGatherData() */ |
45 |
var sVarType = _fnGetCellData( oSettings, iRow, i, 'type' ); |
46 |
if ( sVarType !== null && sVarType !== '' ) |
47 |
{ |
48 |
sThisType = _fnDetectType( sVarType ); |
49 |
if ( oCol.sType === null ) |
50 |
{ |
51 |
oCol.sType = sThisType; |
52 |
} |
53 |
else if ( oCol.sType != sThisType && oCol.sType != "html" ) |
54 |
{ |
55 |
/* String is always the 'fallback' option */ |
56 |
oCol.sType = 'string'; |
57 |
} |
58 |
} |
59 |
} |
60 |
} |
61 |
|
62 |
/* Add to the display array */ |
63 |
oSettings.aiDisplayMaster.push( iRow ); |
64 |
|
65 |
/* Create the DOM information */ |
66 |
if ( !oSettings.oFeatures.bDeferRender ) |
67 |
{ |
68 |
_fnCreateTr( oSettings, iRow ); |
69 |
} |
70 |
|
71 |
return iRow; |
72 |
} |
73 |
|
74 |
|
75 |
/** |
76 |
* Read in the data from the target table from the DOM |
77 |
* @param {object} oSettings dataTables settings object |
78 |
* @memberof DataTable#oApi |
79 |
*/ |
80 |
function _fnGatherData( oSettings ) |
81 |
{ |
82 |
var iLoop, i, iLen, j, jLen, jInner, |
83 |
nTds, nTrs, nTd, nTr, aLocalData, iThisIndex, |
84 |
iRow, iRows, iColumn, iColumns, sNodeName, |
85 |
oCol, oData; |
86 |
|
87 |
/* |
88 |
* Process by row first |
89 |
* Add the data object for the whole table - storing the tr node. Note - no point in getting |
90 |
* DOM based data if we are going to go and replace it with Ajax source data. |
91 |
*/ |
92 |
if ( oSettings.bDeferLoading || oSettings.sAjaxSource === null ) |
93 |
{ |
94 |
nTr = oSettings.nTBody.firstChild; |
95 |
while ( nTr ) |
96 |
{ |
97 |
if ( nTr.nodeName.toUpperCase() == "TR" ) |
98 |
{ |
99 |
iThisIndex = oSettings.aoData.length; |
100 |
nTr._DT_RowIndex = iThisIndex; |
101 |
oSettings.aoData.push( $.extend( true, {}, DataTable.models.oRow, { |
102 |
"nTr": nTr |
103 |
} ) ); |
104 |
|
105 |
oSettings.aiDisplayMaster.push( iThisIndex ); |
106 |
nTd = nTr.firstChild; |
107 |
jInner = 0; |
108 |
while ( nTd ) |
109 |
{ |
110 |
sNodeName = nTd.nodeName.toUpperCase(); |
111 |
if ( sNodeName == "TD" || sNodeName == "TH" ) |
112 |
{ |
113 |
_fnSetCellData( oSettings, iThisIndex, jInner, $.trim(nTd.innerHTML) ); |
114 |
jInner++; |
115 |
} |
116 |
nTd = nTd.nextSibling; |
117 |
} |
118 |
} |
119 |
nTr = nTr.nextSibling; |
120 |
} |
121 |
} |
122 |
|
123 |
/* Gather in the TD elements of the Table - note that this is basically the same as |
124 |
* fnGetTdNodes, but that function takes account of hidden columns, which we haven't yet |
125 |
* setup! |
126 |
*/ |
127 |
nTrs = _fnGetTrNodes( oSettings ); |
128 |
nTds = []; |
129 |
for ( i=0, iLen=nTrs.length ; i<iLen ; i++ ) |
130 |
{ |
131 |
nTd = nTrs[i].firstChild; |
132 |
while ( nTd ) |
133 |
{ |
134 |
sNodeName = nTd.nodeName.toUpperCase(); |
135 |
if ( sNodeName == "TD" || sNodeName == "TH" ) |
136 |
{ |
137 |
nTds.push( nTd ); |
138 |
} |
139 |
nTd = nTd.nextSibling; |
140 |
} |
141 |
} |
142 |
|
143 |
/* Now process by column */ |
144 |
for ( iColumn=0, iColumns=oSettings.aoColumns.length ; iColumn<iColumns ; iColumn++ ) |
145 |
{ |
146 |
oCol = oSettings.aoColumns[iColumn]; |
147 |
|
148 |
/* Get the title of the column - unless there is a user set one */ |
149 |
if ( oCol.sTitle === null ) |
150 |
{ |
151 |
oCol.sTitle = oCol.nTh.innerHTML; |
152 |
} |
153 |
|
154 |
var |
155 |
bAutoType = oCol._bAutoType, |
156 |
bRender = typeof oCol.fnRender === 'function', |
157 |
bClass = oCol.sClass !== null, |
158 |
bVisible = oCol.bVisible, |
159 |
nCell, sThisType, sRendered, sValType; |
160 |
|
161 |
/* A single loop to rule them all (and be more efficient) */ |
162 |
if ( bAutoType || bRender || bClass || !bVisible ) |
163 |
{ |
164 |
for ( iRow=0, iRows=oSettings.aoData.length ; iRow<iRows ; iRow++ ) |
165 |
{ |
166 |
oData = oSettings.aoData[iRow]; |
167 |
nCell = nTds[ (iRow*iColumns) + iColumn ]; |
168 |
|
169 |
/* Type detection */ |
170 |
if ( bAutoType && oCol.sType != 'string' ) |
171 |
{ |
172 |
sValType = _fnGetCellData( oSettings, iRow, iColumn, 'type' ); |
173 |
if ( sValType !== '' ) |
174 |
{ |
175 |
sThisType = _fnDetectType( sValType ); |
176 |
if ( oCol.sType === null ) |
177 |
{ |
178 |
oCol.sType = sThisType; |
179 |
} |
180 |
else if ( oCol.sType != sThisType && |
181 |
oCol.sType != "html" ) |
182 |
{ |
183 |
/* String is always the 'fallback' option */ |
184 |
oCol.sType = 'string'; |
185 |
} |
186 |
} |
187 |
} |
188 |
|
189 |
if ( oCol.mRender ) |
190 |
{ |
191 |
// mRender has been defined, so we need to get the value and set it |
192 |
nCell.innerHTML = _fnGetCellData( oSettings, iRow, iColumn, 'display' ); |
193 |
} |
194 |
else if ( oCol.mData !== iColumn ) |
195 |
{ |
196 |
// If mData is not the same as the column number, then we need to |
197 |
// get the dev set value. If it is the column, no point in wasting |
198 |
// time setting the value that is already there! |
199 |
nCell.innerHTML = _fnGetCellData( oSettings, iRow, iColumn, 'display' ); |
200 |
} |
201 |
|
202 |
/* Rendering */ |
203 |
if ( bRender ) |
204 |
{ |
205 |
sRendered = _fnRender( oSettings, iRow, iColumn ); |
206 |
nCell.innerHTML = sRendered; |
207 |
if ( oCol.bUseRendered ) |
208 |
{ |
209 |
/* Use the rendered data for filtering / sorting */ |
210 |
_fnSetCellData( oSettings, iRow, iColumn, sRendered ); |
211 |
} |
212 |
} |
213 |
|
214 |
/* Classes */ |
215 |
if ( bClass ) |
216 |
{ |
217 |
nCell.className += ' '+oCol.sClass; |
218 |
} |
219 |
|
220 |
/* Column visibility */ |
221 |
if ( !bVisible ) |
222 |
{ |
223 |
oData._anHidden[iColumn] = nCell; |
224 |
nCell.parentNode.removeChild( nCell ); |
225 |
} |
226 |
else |
227 |
{ |
228 |
oData._anHidden[iColumn] = null; |
229 |
} |
230 |
|
231 |
if ( oCol.fnCreatedCell ) |
232 |
{ |
233 |
oCol.fnCreatedCell.call( oSettings.oInstance, |
234 |
nCell, _fnGetCellData( oSettings, iRow, iColumn, 'display' ), oData._aData, iRow, iColumn |
235 |
); |
236 |
} |
237 |
} |
238 |
} |
239 |
} |
240 |
|
241 |
/* Row created callbacks */ |
242 |
if ( oSettings.aoRowCreatedCallback.length !== 0 ) |
243 |
{ |
244 |
for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ ) |
245 |
{ |
246 |
oData = oSettings.aoData[i]; |
247 |
_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [oData.nTr, oData._aData, i] ); |
248 |
} |
249 |
} |
250 |
} |
251 |
|
252 |
|
253 |
/** |
254 |
* Take a TR element and convert it to an index in aoData |
255 |
* @param {object} oSettings dataTables settings object |
256 |
* @param {node} n the TR element to find |
257 |
* @returns {int} index if the node is found, null if not |
258 |
* @memberof DataTable#oApi |
259 |
*/ |
260 |
function _fnNodeToDataIndex( oSettings, n ) |
261 |
{ |
262 |
return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null; |
263 |
} |
264 |
|
265 |
|
266 |
/** |
267 |
* Take a TD element and convert it into a column data index (not the visible index) |
268 |
* @param {object} oSettings dataTables settings object |
269 |
* @param {int} iRow The row number the TD/TH can be found in |
270 |
* @param {node} n The TD/TH element to find |
271 |
* @returns {int} index if the node is found, -1 if not |
272 |
* @memberof DataTable#oApi |
273 |
*/ |
274 |
function _fnNodeToColumnIndex( oSettings, iRow, n ) |
275 |
{ |
276 |
var anCells = _fnGetTdNodes( oSettings, iRow ); |
277 |
|
278 |
for ( var i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ ) |
279 |
{ |
280 |
if ( anCells[i] === n ) |
281 |
{ |
282 |
return i; |
283 |
} |
284 |
} |
285 |
return -1; |
286 |
} |
287 |
|
288 |
|
289 |
/** |
290 |
* Get an array of data for a given row from the internal data cache |
291 |
* @param {object} oSettings dataTables settings object |
292 |
* @param {int} iRow aoData row id |
293 |
* @param {string} sSpecific data get type ('type' 'filter' 'sort') |
294 |
* @param {array} aiColumns Array of column indexes to get data from |
295 |
* @returns {array} Data array |
296 |
* @memberof DataTable#oApi |
297 |
*/ |
298 |
function _fnGetRowData( oSettings, iRow, sSpecific, aiColumns ) |
299 |
{ |
300 |
var out = []; |
301 |
for ( var i=0, iLen=aiColumns.length ; i<iLen ; i++ ) |
302 |
{ |
303 |
out.push( _fnGetCellData( oSettings, iRow, aiColumns[i], sSpecific ) ); |
304 |
} |
305 |
return out; |
306 |
} |
307 |
|
308 |
|
309 |
/** |
310 |
* Get the data for a given cell from the internal cache, taking into account data mapping |
311 |
* @param {object} oSettings dataTables settings object |
312 |
* @param {int} iRow aoData row id |
313 |
* @param {int} iCol Column index |
314 |
* @param {string} sSpecific data get type ('display', 'type' 'filter' 'sort') |
315 |
* @returns {*} Cell data |
316 |
* @memberof DataTable#oApi |
317 |
*/ |
318 |
function _fnGetCellData( oSettings, iRow, iCol, sSpecific ) |
319 |
{ |
320 |
var sData; |
321 |
var oCol = oSettings.aoColumns[iCol]; |
322 |
var oData = oSettings.aoData[iRow]._aData; |
323 |
|
324 |
if ( (sData=oCol.fnGetData( oData, sSpecific )) === undefined ) |
325 |
{ |
326 |
if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null ) |
327 |
{ |
328 |
_fnLog( oSettings, 0, "Requested unknown parameter "+ |
329 |
(typeof oCol.mData=='function' ? '{mData function}' : "'"+oCol.mData+"'")+ |
330 |
" from the data source for row "+iRow ); |
331 |
oSettings.iDrawError = oSettings.iDraw; |
332 |
} |
333 |
return oCol.sDefaultContent; |
334 |
} |
335 |
|
336 |
/* When the data source is null, we can use default column data */ |
337 |
if ( sData === null && oCol.sDefaultContent !== null ) |
338 |
{ |
339 |
sData = oCol.sDefaultContent; |
340 |
} |
341 |
else if ( typeof sData === 'function' ) |
342 |
{ |
343 |
/* If the data source is a function, then we run it and use the return */ |
344 |
return sData(); |
345 |
} |
346 |
|
347 |
if ( sSpecific == 'display' && sData === null ) |
348 |
{ |
349 |
return ''; |
350 |
} |
351 |
return sData; |
352 |
} |
353 |
|
354 |
|
355 |
/** |
356 |
* Set the value for a specific cell, into the internal data cache |
357 |
* @param {object} oSettings dataTables settings object |
358 |
* @param {int} iRow aoData row id |
359 |
* @param {int} iCol Column index |
360 |
* @param {*} val Value to set |
361 |
* @memberof DataTable#oApi |
362 |
*/ |
363 |
function _fnSetCellData( oSettings, iRow, iCol, val ) |
364 |
{ |
365 |
var oCol = oSettings.aoColumns[iCol]; |
366 |
var oData = oSettings.aoData[iRow]._aData; |
367 |
|
368 |
oCol.fnSetData( oData, val ); |
369 |
} |
370 |
|
371 |
|
372 |
// Private variable that is used to match array syntax in the data property object |
373 |
var __reArray = /\[.*?\]$/; |
374 |
|
375 |
/** |
376 |
* Return a function that can be used to get data from a source object, taking |
377 |
* into account the ability to use nested objects as a source |
378 |
* @param {string|int|function} mSource The data source for the object |
379 |
* @returns {function} Data get function |
380 |
* @memberof DataTable#oApi |
381 |
*/ |
382 |
function _fnGetObjectDataFn( mSource ) |
383 |
{ |
384 |
if ( mSource === null ) |
385 |
{ |
386 |
/* Give an empty string for rendering / sorting etc */ |
387 |
return function (data, type) { |
388 |
return null; |
389 |
}; |
390 |
} |
391 |
else if ( typeof mSource === 'function' ) |
392 |
{ |
393 |
return function (data, type, extra) { |
394 |
return mSource( data, type, extra ); |
395 |
}; |
396 |
} |
397 |
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) ) |
398 |
{ |
399 |
/* If there is a . in the source string then the data source is in a |
400 |
* nested object so we loop over the data for each level to get the next |
401 |
* level down. On each loop we test for undefined, and if found immediately |
402 |
* return. This allows entire objects to be missing and sDefaultContent to |
403 |
* be used if defined, rather than throwing an error |
404 |
*/ |
405 |
var fetchData = function (data, type, src) { |
406 |
var a = src.split('.'); |
407 |
var arrayNotation, out, innerSrc; |
408 |
|
409 |
if ( src !== "" ) |
410 |
{ |
411 |
for ( var i=0, iLen=a.length ; i<iLen ; i++ ) |
412 |
{ |
413 |
// Check if we are dealing with an array notation request |
414 |
arrayNotation = a[i].match(__reArray); |
415 |
|
416 |
if ( arrayNotation ) { |
417 |
a[i] = a[i].replace(__reArray, ''); |
418 |
|
419 |
// Condition allows simply [] to be passed in |
420 |
if ( a[i] !== "" ) { |
421 |
data = data[ a[i] ]; |
422 |
} |
423 |
out = []; |
424 |
|
425 |
// Get the remainder of the nested object to get |
426 |
a.splice( 0, i+1 ); |
427 |
innerSrc = a.join('.'); |
428 |
|
429 |
// Traverse each entry in the array getting the properties requested |
430 |
for ( var j=0, jLen=data.length ; j<jLen ; j++ ) { |
431 |
out.push( fetchData( data[j], type, innerSrc ) ); |
432 |
} |
433 |
|
434 |
// If a string is given in between the array notation indicators, that |
435 |
// is used to join the strings together, otherwise an array is returned |
436 |
var join = arrayNotation[0].substring(1, arrayNotation[0].length-1); |
437 |
data = (join==="") ? out : out.join(join); |
438 |
|
439 |
// The inner call to fetchData has already traversed through the remainder |
440 |
// of the source requested, so we exit from the loop |
441 |
break; |
442 |
} |
443 |
|
444 |
if ( data === null || data[ a[i] ] === undefined ) |
445 |
{ |
446 |
return undefined; |
447 |
} |
448 |
data = data[ a[i] ]; |
449 |
} |
450 |
} |
451 |
|
452 |
return data; |
453 |
}; |
454 |
|
455 |
return function (data, type) { |
456 |
return fetchData( data, type, mSource ); |
457 |
}; |
458 |
} |
459 |
else |
460 |
{ |
461 |
/* Array or flat object mapping */ |
462 |
return function (data, type) { |
463 |
return data[mSource]; |
464 |
}; |
465 |
} |
466 |
} |
467 |
|
468 |
|
469 |
/** |
470 |
* Return a function that can be used to set data from a source object, taking |
471 |
* into account the ability to use nested objects as a source |
472 |
* @param {string|int|function} mSource The data source for the object |
473 |
* @returns {function} Data set function |
474 |
* @memberof DataTable#oApi |
475 |
*/ |
476 |
function _fnSetObjectDataFn( mSource ) |
477 |
{ |
478 |
if ( mSource === null ) |
479 |
{ |
480 |
/* Nothing to do when the data source is null */ |
481 |
return function (data, val) {}; |
482 |
} |
483 |
else if ( typeof mSource === 'function' ) |
484 |
{ |
485 |
return function (data, val) { |
486 |
mSource( data, 'set', val ); |
487 |
}; |
488 |
} |
489 |
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1) ) |
490 |
{ |
491 |
/* Like the get, we need to get data from a nested object */ |
492 |
var setData = function (data, val, src) { |
493 |
var a = src.split('.'), b; |
494 |
var arrayNotation, o, innerSrc; |
495 |
|
496 |
for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ ) |
497 |
{ |
498 |
// Check if we are dealing with an array notation request |
499 |
arrayNotation = a[i].match(__reArray); |
500 |
|
501 |
if ( arrayNotation ) |
502 |
{ |
503 |
a[i] = a[i].replace(__reArray, ''); |
504 |
data[ a[i] ] = []; |
505 |
|
506 |
// Get the remainder of the nested object to set so we can recurse |
507 |
b = a.slice(); |
508 |
b.splice( 0, i+1 ); |
509 |
innerSrc = b.join('.'); |
510 |
|
511 |
// Traverse each entry in the array setting the properties requested |
512 |
for ( var j=0, jLen=val.length ; j<jLen ; j++ ) |
513 |
{ |
514 |
o = {}; |
515 |
setData( o, val[j], innerSrc ); |
516 |
data[ a[i] ].push( o ); |
517 |
} |
518 |
|
519 |
// The inner call to setData has already traversed through the remainder |
520 |
// of the source and has set the data, thus we can exit here |
521 |
return; |
522 |
} |
523 |
|
524 |
// If the nested object doesn't currently exist - since we are |
525 |
// trying to set the value - create it |
526 |
if ( data[ a[i] ] === null || data[ a[i] ] === undefined ) |
527 |
{ |
528 |
data[ a[i] ] = {}; |
529 |
} |
530 |
data = data[ a[i] ]; |
531 |
} |
532 |
|
533 |
// If array notation is used, we just want to strip it and use the property name |
534 |
// and assign the value. If it isn't used, then we get the result we want anyway |
535 |
data[ a[a.length-1].replace(__reArray, '') ] = val; |
536 |
}; |
537 |
|
538 |
return function (data, val) { |
539 |
return setData( data, val, mSource ); |
540 |
}; |
541 |
} |
542 |
else |
543 |
{ |
544 |
/* Array or flat object mapping */ |
545 |
return function (data, val) { |
546 |
data[mSource] = val; |
547 |
}; |
548 |
} |
549 |
} |
550 |
|
551 |
|
552 |
/** |
553 |
* Return an array with the full table data |
554 |
* @param {object} oSettings dataTables settings object |
555 |
* @returns array {array} aData Master data array |
556 |
* @memberof DataTable#oApi |
557 |
*/ |
558 |
function _fnGetDataMaster ( oSettings ) |
559 |
{ |
560 |
var aData = []; |
561 |
var iLen = oSettings.aoData.length; |
562 |
for ( var i=0 ; i<iLen; i++ ) |
563 |
{ |
564 |
aData.push( oSettings.aoData[i]._aData ); |
565 |
} |
566 |
return aData; |
567 |
} |
568 |
|
569 |
|
570 |
/** |
571 |
* Nuke the table |
572 |
* @param {object} oSettings dataTables settings object |
573 |
* @memberof DataTable#oApi |
574 |
*/ |
575 |
function _fnClearTable( oSettings ) |
576 |
{ |
577 |
oSettings.aoData.splice( 0, oSettings.aoData.length ); |
578 |
oSettings.aiDisplayMaster.splice( 0, oSettings.aiDisplayMaster.length ); |
579 |
oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length ); |
580 |
_fnCalculateEnd( oSettings ); |
581 |
} |
582 |
|
583 |
|
584 |
/** |
585 |
* Take an array of integers (index array) and remove a target integer (value - not |
586 |
* the key!) |
587 |
* @param {array} a Index array to target |
588 |
* @param {int} iTarget value to find |
589 |
* @memberof DataTable#oApi |
590 |
*/ |
591 |
function _fnDeleteIndex( a, iTarget ) |
592 |
{ |
593 |
var iTargetIndex = -1; |
594 |
|
595 |
for ( var i=0, iLen=a.length ; i<iLen ; i++ ) |
596 |
{ |
597 |
if ( a[i] == iTarget ) |
598 |
{ |
599 |
iTargetIndex = i; |
600 |
} |
601 |
else if ( a[i] > iTarget ) |
602 |
{ |
603 |
a[i]--; |
604 |
} |
605 |
} |
606 |
|
607 |
if ( iTargetIndex != -1 ) |
608 |
{ |
609 |
a.splice( iTargetIndex, 1 ); |
610 |
} |
611 |
} |
612 |
|
613 |
|
614 |
/** |
615 |
* Call the developer defined fnRender function for a given cell (row/column) with |
616 |
* the required parameters and return the result. |
617 |
* @param {object} oSettings dataTables settings object |
618 |
* @param {int} iRow aoData index for the row |
619 |
* @param {int} iCol aoColumns index for the column |
620 |
* @returns {*} Return of the developer's fnRender function |
621 |
* @memberof DataTable#oApi |
622 |
*/ |
623 |
function _fnRender( oSettings, iRow, iCol ) |
624 |
{ |
625 |
var oCol = oSettings.aoColumns[iCol]; |
626 |
|
627 |
return oCol.fnRender( { |
628 |
"iDataRow": iRow, |
629 |
"iDataColumn": iCol, |
630 |
"oSettings": oSettings, |
631 |
"aData": oSettings.aoData[iRow]._aData, |
632 |
"mDataProp": oCol.mData |
633 |
}, _fnGetCellData(oSettings, iRow, iCol, 'display') ); |
634 |
} |