/* * Function: fnAddDataEx * Purpose: Add new row(s) into the table with extended cell attributes * Returns: array int: array of indexes (aoData) which have been added (zero length on error) * Inputs: array:mData - the data to be added. The length must match * the original data from the DOM * or * array array:mData - 2D array of data to be added * array item is javascript object { data: '{cell_value}', cell_class: '{cell_class}' } * bool:bRedraw - redraw the table or not - default true * Notes: Warning - the refilter here will cause the table to redraw * starting at zero * Notes: Thanks to Yekimov Denis for contributing the basis for this function! */ this.fnAddDataEx = function(mData, bRedraw) { if (mData.length === 0) { return []; } if (mData[0].length === 0) { return []; } var aiReturn = []; var iTest; /* Find settings from table node */ var oSettings = _fnSettingsFromNode(this[_oExt.iApiIndex]); /* Check if we want to add multiple rows or not */ if (typeof mData[0][0] == "object") { for (var i = 0; i < mData.length; i++) { iTest = _fnAddDataEx(oSettings, mData[i]); if (iTest == -1) { return aiReturn; } aiReturn.push(iTest); } } else { iTest = _fnAddDataEx(oSettings, mData); if (iTest == -1) { return aiReturn; } aiReturn.push(iTest); } oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); if (typeof bRedraw == 'undefined' || bRedraw) { _fnReDraw(oSettings); } return aiReturn; }; /* * Function: _fnAddDataEx * Purpose: Add a data array to the table, creating DOM node etc * Returns: int: - >=0 if successful (index of new aoData entry), -1 if failed * Inputs: object:oSettings - dataTables settings object * array:aData - data array to be added * array item is javascript object { data: '{cell_value}', cell_class: '{cell_class}' } * Notes: There are two basic methods for DataTables to get data to display - a JS array * (which is dealt with by this function), and the DOM, which has it's own optimised * function (_fnGatherData). Be careful to make the same changes here as there and vice-versa */ function _fnAddDataEx(oSettings, aDataSupplied) { /* Sanity check the length of the new array */ if (aDataSupplied.length != oSettings.aoColumns.length && oSettings.iDrawError != oSettings.iDraw) { _fnLog(oSettings, 0, "Added data (size " + aDataSupplied.length + ") does not match known " + "number of columns (" + oSettings.aoColumns.length + ")"); oSettings.iDrawError = oSettings.iDraw; return -1; } /* Create the object for storing information about this new row */ var aData = aDataSupplied.slice(); var aDataValues = []; for (var i = 0; i < aData.length; i++) { if ((aData[i].data === null) || (aData[i].data === undefined)) { aDataValues.push(''); } else { /* Cast everything as a string - so we can treat everything equally when sorting */ if (typeof aData[i].data != 'string') { aData[i].data += ""; } aData[i].data = $.trim(aData[i].data); aDataValues.push(aData[i].data); } } var iThisIndex = oSettings.aoData.length; oSettings.aoData.push({ "nTr": document.createElement('tr'), "_iId": oSettings.iNextId++, "_aData": aDataValues, "_anHidden": [], "_sRowStripe": '' }); /* Create the cells */ var nTd, sThisType; for (var i = 0; i < aData.length; i++) { nTd = document.createElement('td'); /* Allow null data (from a data array) - simply deal with it as a blank string */ if (aData[i] === null) { aData[i] = { data: '', cell_class: '' }; } if (typeof oSettings.aoColumns[i].fnRender == 'function') { var sRendered = oSettings.aoColumns[i].fnRender({ "iDataRow": iThisIndex, "iDataColumn": i, "aData": aDataValues, "oSettings": oSettings }); nTd.innerHTML = sRendered; if (oSettings.aoColumns[i].bUseRendered) { /* Use the rendered data for filtering/sorting */ oSettings.aoData[iThisIndex]._aData[i] = sRendered; } } else { nTd.innerHTML = aData[i].data; } /* Add user defined column class */ if (oSettings.aoColumns[i].sClass !== null) { nTd.className = oSettings.aoColumns[i].sClass; } /* Add cell class */ nTd.className += " " + aData[i].cell_class; /* See if we should auto-detect the column type */ if (oSettings.aoColumns[i]._bAutoType && oSettings.aoColumns[i].sType != 'string') { /* Attempt to auto detect the type - same as _fnGatherData() */ sThisType = _fnDetectType(oSettings.aoData[iThisIndex]._aData[i]); if (oSettings.aoColumns[i].sType === null) { oSettings.aoColumns[i].sType = sThisType; } else if (oSettings.aoColumns[i].sType != sThisType) { /* String is always the 'fallback' option */ oSettings.aoColumns[i].sType = 'string'; } } if (oSettings.aoColumns[i].bVisible) { oSettings.aoData[iThisIndex].nTr.appendChild(nTd); oSettings.aoData[iThisIndex]._anHidden[i] = null; } else { oSettings.aoData[iThisIndex]._anHidden[i] = nTd; } } /* Add to the display array */ oSettings.aiDisplayMaster.push(iThisIndex); return iThisIndex; }