From 745bcbeabdf5794b5f3185fcd497dfce04f09b84 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 13 Feb 2013 18:07:27 -0600 Subject: Got results displaying for BXD and fixed genofile_parser.py to work for all of our genofiles --- .../wqflask/marker_regression/marker_regression.py | 26 +- wqflask/wqflask/my_pylmm/data/genofile_parser.py | 31 +- wqflask/wqflask/my_pylmm/pyLMM/lmm.py | 48 +- .../new/packages/DataTables/css/demo_page.css | 17 +- .../new/packages/DataTables/css/demo_table.css | 3 +- .../new/packages/DataTables/css/demo_table_jui.css | 25 - .../packages/DataTables/css/jquery.dataTables.css | 3 +- .../css/jquery.dataTables_themeroller.css | 1 - .../packages/DataTables/js/jquery.dataTables.js | 1412 ++++++++++++-------- .../DataTables/js/jquery.dataTables.min.js | 277 ++-- .../static/new/packages/DataTables/js/jquery.js | 6 +- .../new/packages/DataTables/src/DataTables.js | 37 +- .../packages/DataTables/src/api/api.internal.js | 6 +- .../new/packages/DataTables/src/api/api.methods.js | 72 +- .../new/packages/DataTables/src/core/core.ajax.js | 6 +- .../packages/DataTables/src/core/core.columns.js | 108 +- .../DataTables/src/core/core.constructor.js | 49 +- .../new/packages/DataTables/src/core/core.data.js | 174 ++- .../new/packages/DataTables/src/core/core.draw.js | 40 +- .../packages/DataTables/src/core/core.filter.js | 56 +- .../new/packages/DataTables/src/core/core.info.js | 24 +- .../packages/DataTables/src/core/core.length.js | 2 +- .../new/packages/DataTables/src/core/core.page.js | 2 +- .../packages/DataTables/src/core/core.scrolling.js | 118 +- .../packages/DataTables/src/core/core.sizing.js | 12 +- .../new/packages/DataTables/src/core/core.sort.js | 87 +- .../new/packages/DataTables/src/core/core.state.js | 51 +- .../packages/DataTables/src/core/core.support.js | 54 +- .../new/packages/DataTables/src/ext/ext.paging.js | 31 +- .../packages/DataTables/src/model/model.column.js | 47 +- .../DataTables/src/model/model.defaults.columns.js | 276 ++-- .../DataTables/src/model/model.defaults.js | 136 +- .../new/packages/DataTables/src/model/model.ext.js | 8 +- .../new/packages/DataTables/src/model/model.row.js | 2 +- .../DataTables/src/model/model.settings.js | 16 +- .../tests_onhold/5_ajax_objects/_zero_config.js | 10 +- .../_zero_config_arrays_subobjects.js | 6 +- .../5_ajax_objects/_zero_config_deep.js | 10 +- .../5_ajax_objects/_zero_config_null_source.js | 2 +- .../5_ajax_objects/_zero_config_objects.js | 10 +- .../_zero_config_objects_subarrays.js | 10 +- .../tests_onhold/5_ajax_objects/aaSorting.js | 140 +- .../tests_onhold/5_ajax_objects/aaSortingFixed.js | 30 +- .../5_ajax_objects/aoColumns.bSearchable.js | 30 +- .../5_ajax_objects/aoColumns.bSortable.js | 30 +- .../5_ajax_objects/aoColumns.bUseRendered.js | 30 +- .../5_ajax_objects/aoColumns.bVisible.js | 30 +- .../5_ajax_objects/aoColumns.fnRender.js | 62 +- .../5_ajax_objects/aoColumns.iDataSort.js | 20 +- .../5_ajax_objects/aoColumns.sClass.js | 30 +- .../tests_onhold/5_ajax_objects/aoColumns.sName.js | 10 +- .../5_ajax_objects/aoColumns.sTitle.js | 30 +- .../5_ajax_objects/aoColumns.sWidth.js | 30 +- .../tests_onhold/5_ajax_objects/aoSearchCols.js | 60 +- .../tests_onhold/5_ajax_objects/asStripClasses.js | 40 +- .../tests_onhold/5_ajax_objects/bAutoWidth.js | 30 +- .../tests_onhold/5_ajax_objects/bFilter.js | 30 +- .../tests_onhold/5_ajax_objects/bInfo.js | 30 +- .../tests_onhold/5_ajax_objects/bLengthChange.js | 30 +- .../tests_onhold/5_ajax_objects/bPaginate.js | 30 +- .../tests_onhold/5_ajax_objects/bProcessing.js | 30 +- .../tests_onhold/5_ajax_objects/bServerSide.js | 10 +- .../tests_onhold/5_ajax_objects/bSort.js | 30 +- .../tests_onhold/5_ajax_objects/bSortClasses.js | 30 +- .../tests_onhold/5_ajax_objects/fnDrawCallback.js | 40 +- .../5_ajax_objects/fnHeaderCallback.js | 90 +- .../tests_onhold/5_ajax_objects/fnInitComplete.js | 50 +- .../tests_onhold/5_ajax_objects/fnRowCallback.js | 60 +- .../tests_onhold/5_ajax_objects/fnServerData.js | 40 +- .../tests_onhold/5_ajax_objects/iDisplayLength.js | 40 +- .../5_ajax_objects/oLanguage.oPaginate.js | 20 +- .../tests_onhold/5_ajax_objects/oLanguage.sInfo.js | 70 +- .../5_ajax_objects/oLanguage.sInfoEmpty.js | 30 +- .../5_ajax_objects/oLanguage.sInfoPostFix.js | 40 +- .../5_ajax_objects/oLanguage.sLengthMenu.js | 40 +- .../5_ajax_objects/oLanguage.sProcessing.js | 20 +- .../5_ajax_objects/oLanguage.sSearch.js | 30 +- .../tests_onhold/5_ajax_objects/oLanguage.sUrl.js | 20 +- .../5_ajax_objects/oLanguage.sZeroRecords.js | 20 +- .../tests_onhold/5_ajax_objects/oSearch.js | 60 +- .../tests_onhold/5_ajax_objects/sAjaxSource.js | 10 +- .../tests_onhold/5_ajax_objects/sDom.js | 70 +- .../tests_onhold/5_ajax_objects/sPaginationType.js | 20 +- .../static/packages/DT_bootstrap/DT_bootstrap.css | 179 +++ .../static/packages/DT_bootstrap/DT_bootstrap.js | 159 +++ .../wqflask/static/packages/DT_bootstrap/images | 1 + wqflask/wqflask/templates/marker_regression.html | 26 +- 87 files changed, 3058 insertions(+), 2210 deletions(-) create mode 100644 wqflask/wqflask/static/packages/DT_bootstrap/DT_bootstrap.css create mode 100644 wqflask/wqflask/static/packages/DT_bootstrap/DT_bootstrap.js create mode 120000 wqflask/wqflask/static/packages/DT_bootstrap/images (limited to 'wqflask') diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index c06ab7e8..81bf3825 100755 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -462,6 +462,11 @@ class MarkerRegression(object): no_val_samples = self.identify_empty_samples() trimmed_genotype_data = self.trim_genotypes(genotype_data, no_val_samples) + + #for i, marker in enumerate(trimmed_genotype_data): + # if i > 10: + # break + # print("genotype is:", pf(marker)) #print("trimmed genotype data is:", pf(trimmed_genotype_data)) @@ -471,8 +476,17 @@ class MarkerRegression(object): #prep_data.PrepData(self.vals, genotype_data) pheno_vector = np.array([float(val) for val in self.vals if val!="x"]) + print("genotypes was:", pf(trimmed_genotype_data)) + for item in trimmed_genotype_data: + if type(item) != type(list()): + print(" --->", type(item)) + for counter, part in enumerate(item): + if type(part) != type(float()): + print(" ------>", type(part), " : ", part) + if counter % 100 == 0: + print(" ------>", type(part)) genotypes = np.array(trimmed_genotype_data).T - print("genotypes is", pf(genotypes)) + print("genotypes is:", pf(genotypes)) #genotypes = np.genfromtxt(os.path.join(webqtlConfig.TMPDIR, # self.dataset.group.name + '.snps.new')).T @@ -491,7 +505,7 @@ class MarkerRegression(object): REML=True, refit=False) - print("p_values is:", pf(len(p_values))) + #print("p_values is:", pf(len(p_values))) self.dataset.group.markers.add_pvalues(p_values) @@ -503,11 +517,11 @@ class MarkerRegression(object): # nperm=self.num_perm) self.lrs_values = [marker['lrs_value'] for marker in self.dataset.group.markers.markers] - print("self.lrs_values is:", pf(self.lrs_values)) + #print("self.lrs_values is:", pf(self.lrs_values)) lrs_values_sorted = sorted(self.lrs_values) - print("lrs_values_sorted is:", pf(lrs_values_sorted)) - print("int(self.num_perm*0.37-1)", pf(int(self.num_perm*0.37-1))) + #print("lrs_values_sorted is:", pf(lrs_values_sorted)) + #print("int(self.num_perm*0.37-1)", pf(int(self.num_perm*0.37-1))) lrs_values_length = len(lrs_values_sorted) @@ -705,6 +719,8 @@ class MarkerRegression(object): try: genotype = float(genotype) except ValueError: + genotype = np.nan + print("Couldn't convert to float:", genotype) pass new_genotypes.append(genotype) trimmed_genotype_data.append(new_genotypes) diff --git a/wqflask/wqflask/my_pylmm/data/genofile_parser.py b/wqflask/wqflask/my_pylmm/data/genofile_parser.py index 8c74fe74..b926592b 100644 --- a/wqflask/wqflask/my_pylmm/data/genofile_parser.py +++ b/wqflask/wqflask/my_pylmm/data/genofile_parser.py @@ -28,11 +28,10 @@ class Marker(object): class ConvertGenoFile(object): - def __init__(self, input_file, output_file, file_type): + def __init__(self, input_file, output_file): self.input_file = input_file self.output_file = output_file - self.file_type = file_type self.mb_exists = False self.markers = [] @@ -58,10 +57,10 @@ class ConvertGenoFile(object): self.input_fh = open(self.input_file) with open(self.output_file, "w") as self.output_fh: - if self.file_type == "geno": - self.process_csv() - elif self.file_type == "snps": - self.process_snps_file() + #if self.file_type == "geno": + self.process_csv() + #elif self.file_type == "snps": + # self.process_snps_file() #def process_row(self, row): @@ -87,7 +86,10 @@ class ConvertGenoFile(object): else: genotypes = row_items[3:] for item_count, genotype in enumerate(genotypes): - this_marker.genotypes.append(self.configurations[genotype.upper()]) + if genotype.upper() in self.configurations: + this_marker.genotypes.append(self.configurations[genotype.upper()]) + else: + this_marker.genotypes.append("NA") #print("this_marker is:", pf(this_marker.__dict__)) @@ -111,6 +113,8 @@ class ConvertGenoFile(object): for self.latest_row_pos, row in enumerate(self.input_fh): self.latest_row_value = row # Take care of headers + if not row.strip(): + continue if row.startswith('#'): continue if row.startswith('Chr'): @@ -134,7 +138,8 @@ class ConvertGenoFile(object): for input_file in glob.glob("*.geno"): group_name = input_file.split('.')[0] output_file = os.path.join(new_directory, group_name + ".json") - print("%s -> %s" % (input_file, output_file)) + print("%s -> %s" % ( + os.path.join(old_directory, input_file), output_file)) convertob = ConvertGenoFile(input_file, output_file) try: convertob.convert() @@ -146,16 +151,16 @@ class ConvertGenoFile(object): print(" Exception:", why) print(traceback.print_exc()) - print(" Found in row %i at tabular column %i" % (convertob.latest_row_pos, + print(" Found in row %s at tabular column %s" % (convertob.latest_row_pos, convertob.latest_col_pos)) print(" Column is:", convertob.latest_col_value) print(" Row is:", convertob.latest_row_value) break - def process_snps_file(cls, snps_file, new_directory): - output_file = os.path.join(new_directory, "mouse_families.json") - print("%s -> %s" % (snps_file, output_file)) - convertob = ConvertGenoFile(input_file, output_file) + #def process_snps_file(cls, snps_file, new_directory): + # output_file = os.path.join(new_directory, "mouse_families.json") + # print("%s -> %s" % (snps_file, output_file)) + # convertob = ConvertGenoFile(input_file, output_file) diff --git a/wqflask/wqflask/my_pylmm/pyLMM/lmm.py b/wqflask/wqflask/my_pylmm/pyLMM/lmm.py index 015c2e14..d0f379dd 100644 --- a/wqflask/wqflask/my_pylmm/pyLMM/lmm.py +++ b/wqflask/wqflask/my_pylmm/pyLMM/lmm.py @@ -54,27 +54,33 @@ def matrixMult(A,B): return linalg.fblas.dgemm(alpha=1.,a=AA,b=BB,trans_a=transA,trans_b=transB) def calculateKinship(W): - """ - W is an n x m matrix encoding SNP minor alleles. - - This function takes a matrix oF SNPs, imputes missing values with the maf, - normalizes the resulting vectors and returns the RRM matrix. - """ - n = W.shape[0] - m = W.shape[1] - keep = [] - for i in range(m): - mn = W[True - np.isnan(W[:,i]),i].mean() - W[np.isnan(W[:,i]),i] = mn - vr = W[:,i].var() - if vr == 0: continue - - keep.append(i) - W[:,i] = (W[:,i] - mn) / np.sqrt(vr) - - W = W[:,keep] - K = matrixMult(W,W.T) * 1.0/float(m) - return K + """ + W is an n x m matrix encoding SNP minor alleles. + + This function takes a matrix oF SNPs, imputes missing values with the maf, + normalizes the resulting vectors and returns the RRM matrix. + """ + n = W.shape[0] + m = W.shape[1] + print("n is:", n) + print("m is:", m) + keep = [] + for i in range(m): + print("type of W[:,i]:", pf(W[:,i])) + foo = np.isnan(W[:,i]) + print("type of foo:", type(foo)) + mn = W[True - foo,i] + print("type of mn is:", type(mn)) + mn = mn.mean() + W[np.isnan(W[:,i]),i] = mn + vr = W[:,i].var() + if vr == 0: + continue + keep.append(i) + W[:,i] = (W[:,i] - mn) / np.sqrt(vr) + W = W[:,keep] + K = np.dot(W,W.T) * 1.0/float(m) + return K def GWAS(Y, X, K, Kva=[], Kve=[], X0=None, REML=True, refit=False): """ diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css index 89c62bb7..ba5b2a6c 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css @@ -104,4 +104,19 @@ height: 100px; width: 100%; overflow: auto; -} \ No newline at end of file +} + +#dt_example code { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + padding: 2px 4px !important; + white-space: nowrap; + font-size: 0.9em; + + color: #D14; + background-color: #F7F7F9; + + border: 1px solid #E1E1E8; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css index f41a0042..12f352da 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css @@ -201,7 +201,8 @@ table.display td.center { background: url('../images/sort_desc_disabled.png') no-repeat center right; } -th:active { +table.display thead th:active, +table.display thead td:active { outline: none; } diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css index de7c8426..a210af51 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css @@ -82,7 +82,6 @@ div.dataTables_wrapper .ui-widget-header { table.display thead th div.DataTables_sort_wrapper { position: relative; padding-right: 20px; - padding-right: 20px; } table.display thead th div.DataTables_sort_wrapper span { @@ -147,30 +146,6 @@ table.display thead th div.DataTables_sort_wrapper span { text-align: right; } -/* Pagination nested */ -.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next { - height: 19px; - width: 19px; - margin-left: 3px; - float: left; -} - -.paginate_disabled_previous { - background-image: url('../images/back_disabled.jpg'); -} - -.paginate_enabled_previous { - background-image: url('../images/back_enabled.jpg'); -} - -.paginate_disabled_next { - background-image: url('../images/forward_disabled.jpg'); -} - -.paginate_enabled_next { - background-image: url('../images/forward_enabled.jpg'); -} - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css index 83df98ea..7da7faec 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css @@ -201,7 +201,8 @@ table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } .sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } .sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } -table.dataTable th:active { +table.dataTable thead th:active, +table.dataTable thead td:active { outline: none; } diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css index 55661c6d..cf1d4ed7 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css @@ -216,7 +216,6 @@ table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } table.dataTable thead th div.DataTables_sort_wrapper { position: relative; padding-right: 20px; - padding-right: 20px; } table.dataTable thead th div.DataTables_sort_wrapper span { diff --git a/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js b/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js index ae5d1750..1d8a220b 100644 --- a/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js +++ b/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js @@ -1,7 +1,7 @@ /** * @summary DataTables * @description Paginate, search and sort HTML tables - * @version 1.9.2 + * @version 1.9.4 * @file jquery.dataTables.js * @author Allan Jardine (www.sprymedia.co.uk) * @contact www.sprymedia.co.uk/contact @@ -21,9 +21,28 @@ */ /*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,_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,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/ +/*globals $, 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,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros,_fnBrowserDetect,_fnGetColumns*/ -(/** @lends */function($, window, document, undefined) { +(/** @lends */function( window, document, undefined ) { + +(function( factory ) { + "use strict"; + + // Define as an AMD module if possible + if ( typeof define === 'function' && define.amd ) + { + define( ['jquery'], factory ); + } + /* Define using browser globals otherwise + * Prevent multiple instantiations if the script is loaded twice + */ + else if ( jQuery && !jQuery.fn.dataTable ) + { + factory( jQuery ); + } +} +(/** @lends */function( $ ) { + "use strict"; /** * DataTables is a plug-in for the jQuery Javascript library. It is a * highly flexible tool, based upon the foundations of progressive @@ -76,7 +95,7 @@ "nTh": nTh ? nTh : document.createElement('th'), "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol + "mData": oDefaults.mData ? oDefaults.oDefaults : iCol } ); oSettings.aoColumns.push( oCol ); @@ -115,7 +134,7 @@ * Apply options for a column * @param {object} oSettings dataTables settings object * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable + * @param {object} oOptions object with sType, bVisible and bSearchable etc * @memberof DataTable#oApi */ function _fnColumnOptions( oSettings, iCol, oOptions ) @@ -125,6 +144,12 @@ /* User specified column options */ if ( oOptions !== undefined && oOptions !== null ) { + /* Backwards compatibility for mDataProp */ + if ( oOptions.mDataProp && !oOptions.mData ) + { + oOptions.mData = oOptions.mDataProp; + } + if ( oOptions.sType !== undefined ) { oCol.sType = oOptions.sType; @@ -145,8 +170,19 @@ } /* Cache the data get and set functions for speed */ - oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp ); - oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp ); + var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; + var mData = _fnGetObjectDataFn( oCol.mData ); + + oCol.fnGetData = function (oData, sSpecific) { + var innerData = mData( oData, sSpecific ); + + if ( oCol.mRender && (sSpecific && sSpecific !== '') ) + { + return mRender( innerData, sSpecific, oData ); + } + return innerData; + }; + oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); /* Feature sorting overrides column specific when off */ if ( !oSettings.oFeatures.bSort ) @@ -161,11 +197,10 @@ oCol.sSortingClass = oSettings.oClasses.sSortableNone; oCol.sSortingClassJUI = ""; } - else if ( oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; + oCol.sSortingClass = oSettings.oClasses.sSortable; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; } else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) { @@ -188,7 +223,7 @@ */ function _fnAdjustColumnSizing ( oSettings ) { - /* Not interested in doing column width calculation if autowidth is disabled */ + /* Not interested in doing column width calculation if auto-width is disabled */ if ( oSettings.oFeatures.bAutoWidth === false ) { return false; @@ -212,22 +247,11 @@ */ function _fnVisibleToColumnIndex( oSettings, iMatch ) { - var iColumn = -1; - - for ( var i=0 ; i tag - remove it */ - sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,""); + sSearch = $('
').html(sSearch).text(); } - return sSearch; + // Strip newline characters + return sSearch.replace( /[\n\r]/g, " " ); } /** @@ -2280,7 +2393,7 @@ * @param {string} sSearch string to search for * @param {bool} bRegex treat as a regular expression or not * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not + * @param {bool} bCaseInsensitive Do case insensitive matching or not * @returns {RegExp} constructed object * @memberof DataTable#oApi */ @@ -2335,7 +2448,7 @@ /** - * scape a string stuch that it can be used in a regular expression + * scape a string such that it can be used in a regular expression * @param {string} sVal string to escape * @returns {string} escaped string * @memberof DataTable#oApi @@ -2348,7 +2461,6 @@ } - /** * Generate the node required for the info display * @param {object} oSettings dataTables settings object @@ -2399,25 +2511,20 @@ iTotal = oSettings.fnRecordsDisplay(), sOut; - if ( iTotal === 0 && iTotal == iMax ) + if ( iTotal === 0 ) { /* Empty record set */ sOut = oLang.sInfoEmpty; } - else if ( iTotal === 0 ) - { - /* Empty record set after filtering */ - sOut = oLang.sInfoEmpty +' '+ oLang.sInfoFiltered; - } - else if ( iTotal == iMax ) - { + else { /* Normal record set */ sOut = oLang.sInfo; } - else + + if ( iTotal != iMax ) { /* Record set after filtering */ - sOut = oLang.sInfo +' '+ oLang.sInfoFiltered; + sOut += ' ' + oLang.sInfoFiltered; } // Convert the macros @@ -2458,10 +2565,10 @@ } return str. - replace('_START_', sStart). - replace('_END_', sEnd). - replace('_TOTAL_', sTotal). - replace('_MAX_', sMax); + replace(/_START_/g, sStart). + replace(/_END_/g, sEnd). + replace(/_TOTAL_/g, sTotal). + replace(/_MAX_/g, sMax); } @@ -2712,7 +2819,7 @@ /** - * Rcalculate the end point based on the start point + * Recalculate the end point based on the start point * @param {object} oSettings dataTables settings object * @memberof DataTable#oApi */ @@ -2816,7 +2923,7 @@ oSettings._iDisplayStart - oSettings._iDisplayLength : 0; - /* Correct for underrun */ + /* Correct for under-run */ if ( oSettings._iDisplayStart < 0 ) { oSettings._iDisplayStart = 0; @@ -2902,8 +3009,6 @@ $(oSettings.oInstance).trigger('processing', [oSettings, bShow]); } - - /** * Add any control elements for the table - specifically scrolling * @param {object} oSettings dataTables settings object @@ -3012,7 +3117,7 @@ /* * Sizing */ - /* When xscrolling add the width and a scroller to move the header with the body */ + /* When x-scrolling add the width and a scroller to move the header with the body */ if ( oSettings.oScroll.sX !== "" ) { nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX ); @@ -3095,10 +3200,18 @@ nScrollBody = o.nTable.parentNode, i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, nTheadSize, nTfootSize, - iWidth, aApplied=[], iSanityWidth, + iWidth, aApplied=[], aAppliedFooter=[], iSanityWidth, nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, - ie67 = $.browser.msie && $.browser.version <= 7; + ie67 = o.oBrowser.bScrollOversize, + zeroOut = function(nSizer) { + oStyle = nSizer.style; + oStyle.paddingTop = "0"; + oStyle.paddingBottom = "0"; + oStyle.borderTopWidth = "0"; + oStyle.borderBottomWidth = "0"; + oStyle.height = 0; + }; /* * 1. Re-create the table inside the scrolling div @@ -3110,11 +3223,15 @@ /* Clone the current header and footer elements and then place it into the inner table */ nTheadSize = $(o.nTHead).clone()[0]; o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); + anHeadToSize = o.nTHead.getElementsByTagName('tr'); + anHeadSizers = nTheadSize.getElementsByTagName('tr'); if ( o.nTFoot !== null ) { nTfootSize = $(o.nTFoot).clone()[0]; o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); + anFootToSize = o.nTFoot.getElementsByTagName('tr'); + anFootSizers = nTfootSize.getElementsByTagName('tr'); } /* @@ -3123,7 +3240,7 @@ /* Remove old sizing and apply the calculated column widths * Get the unique column headers in the newly created (cloned) header. We want to apply the - * calclated sizes to this header + * calculated sizes to this header */ if ( o.oScroll.sX === "" ) { @@ -3142,7 +3259,7 @@ { _fnApplyToChildren( function(n) { n.style.width = ""; - }, nTfootSize.getElementsByTagName('tr') ); + }, anFootSizers ); } // If scroll collapse is enabled, when we put the headers back into the body for sizing, we @@ -3204,41 +3321,38 @@ /* We want the hidden header to have zero height, so remove padding and borders. Then * set the width based on the real headers */ - anHeadToSize = o.nTHead.getElementsByTagName('tr'); - anHeadSizers = nTheadSize.getElementsByTagName('tr'); - _fnApplyToChildren( function(nSizer, nToSize) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - - iWidth = $(nSizer).width(); - nToSize.style.width = _fnStringToCss( iWidth ); - aApplied.push( iWidth ); - }, anHeadSizers, anHeadToSize ); + // Apply all styles in one pass. Invalidates layout only once because we don't read any + // DOM properties. + _fnApplyToChildren( zeroOut, anHeadSizers ); + + // Read all widths in next pass. Forces layout only once because we do not change + // any DOM properties. + _fnApplyToChildren( function(nSizer) { + aApplied.push( _fnStringToCss( $(nSizer).width() ) ); + }, anHeadSizers ); + + // Apply all widths in final pass. Invalidates layout only once because we do not + // read any DOM properties. + _fnApplyToChildren( function(nToSize, i) { + nToSize.style.width = aApplied[i]; + }, anHeadToSize ); + $(anHeadSizers).height(0); + /* Same again with the footer if we have one */ if ( o.nTFoot !== null ) { - /* Clone the current footer and then place it into the body table as a "hidden header" */ - anFootSizers = nTfootSize.getElementsByTagName('tr'); - anFootToSize = o.nTFoot.getElementsByTagName('tr'); - - _fnApplyToChildren( function(nSizer, nToSize) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - - iWidth = $(nSizer).width(); - nToSize.style.width = _fnStringToCss( iWidth ); - aApplied.push( iWidth ); - }, anFootSizers, anFootToSize ); + _fnApplyToChildren( zeroOut, anFootSizers ); + + _fnApplyToChildren( function(nSizer) { + aAppliedFooter.push( _fnStringToCss( $(nSizer).width() ) ); + }, anFootSizers ); + + _fnApplyToChildren( function(nToSize, i) { + nToSize.style.width = aAppliedFooter[i]; + }, anFootToSize ); + $(anFootSizers).height(0); } @@ -3249,16 +3363,16 @@ /* "Hide" the header and footer that we used for the sizing. We want to also fix their width * to what they currently are */ - _fnApplyToChildren( function(nSizer) { + _fnApplyToChildren( function(nSizer, i) { nSizer.innerHTML = ""; - nSizer.style.width = _fnStringToCss( aApplied.shift() ); + nSizer.style.width = aApplied[i]; }, anHeadSizers ); if ( o.nTFoot !== null ) { - _fnApplyToChildren( function(nSizer) { + _fnApplyToChildren( function(nSizer, i) { nSizer.innerHTML = ""; - nSizer.style.width = _fnStringToCss( aApplied.shift() ); + nSizer.style.width = aAppliedFooter[i]; }, anFootSizers ); } @@ -3281,11 +3395,11 @@ /* Apply the calculated minimum width to the table wrappers */ nScrollBody.style.width = _fnStringToCss( iCorrection ); - nScrollHeadInner.parentNode.style.width = _fnStringToCss( iCorrection ); + o.nScrollHead.style.width = _fnStringToCss( iCorrection ); if ( o.nTFoot !== null ) { - nScrollFootInner.parentNode.style.width = _fnStringToCss( iCorrection ); + o.nScrollFoot.style.width = _fnStringToCss( iCorrection ); } /* And give the user a warning that we've stopped the table getting too small */ @@ -3304,11 +3418,11 @@ else { nScrollBody.style.width = _fnStringToCss( '100%' ); - nScrollHeadInner.parentNode.style.width = _fnStringToCss( '100%' ); + o.nScrollHead.style.width = _fnStringToCss( '100%' ); if ( o.nTFoot !== null ) { - nScrollFootInner.parentNode.style.width = _fnStringToCss( '100%' ); + o.nScrollFoot.style.width = _fnStringToCss( '100%' ); } } @@ -3357,7 +3471,7 @@ nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; } - /* Adjust the position of the header incase we loose the y-scrollbar */ + /* Adjust the position of the header in case we loose the y-scrollbar */ $(nScrollBody).scroll(); /* If sorting or filtering has occurred, jump the scrolling back to the top */ @@ -3378,27 +3492,34 @@ */ function _fnApplyToChildren( fn, an1, an2 ) { - for ( var i=0, iLen=an1.length ; i= iColumns ) + for (i = 0, iClass = 1; i < aaSort.length; i++) { - for ( i=0 ; i 0 && sCurrentClass.indexOf(sNewClass) == -1 ) { - iClass++; + /* We need to add a class */ + nTds[i].className = sCurrentClass + " " + sNewClass; } } } @@ -4344,7 +4456,7 @@ $.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols ); /* Column visibility state - * Pass back visibiliy settings to the init handler, but to do not here override + * Pass back visibility settings to the init handler, but to do not here override * the init object that the user might have passed in */ oInit.saved_aoColumns = []; @@ -4396,35 +4508,50 @@ } /* Are we going to go over the cookie limit of 4KiB? If so, try to delete a cookies - * belonging to DataTables. This is FAR from bullet proof + * belonging to DataTables. */ - var sOldName="", iOldTime=9999999999999; - var iLength = _fnReadCookie( sNameFile )!==null ? document.cookie.length : - sFullCookie.length + document.cookie.length; + var + aCookies =document.cookie.split(';'), + iNewCookieLen = sFullCookie.split(';')[0].length, + aOldCookies = []; - if ( iLength+10 > 4096 ) /* Magic 10 for padding */ + if ( iNewCookieLen+document.cookie.length+10 > 4096 ) /* Magic 10 for padding */ { - var aCookies =document.cookie.split(';'); for ( var i=0, iLen=aCookies.length ; i'+ + '
'+ + '
'+ + '
'+ + '
')[0]; + + document.body.appendChild( n ); + oSettings.oBrowser.bScrollOversize = $('#DT_BrowserTest', n)[0].offsetWidth === 100 ? true : false; + document.body.removeChild( n ); + } + /** * Perform a jQuery selector action on the table's TR elements (from the tbody) and * return the resulting jQuery object. @@ -4913,11 +5068,11 @@ /** * Almost identical to $ in operation, but in this case returns the data for the matched * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes - * rather than any decendents, so the data can be obtained for the row/cell. If matching + * rather than any descendants, so the data can be obtained for the row/cell. If matching * rows are found, the data returned is the original data array/object that was used to * create the row (or a generated array if from a DOM source). * - * This method is often useful incombination with $ where both functions are given the + * This method is often useful in-combination with $ where both functions are given the * same parameters and the array indexes will match identically. * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on * @param {object} [oOpts] Optional parameters for modifying the rows to be included @@ -4981,8 +5136,8 @@ *
    *
  • 1D array of data - add a single row with the data provided
  • *
  • 2D array of arrays - add multiple rows in a single call
  • - *
  • object - data object when using mDataProp
  • - *
  • array of objects - multiple data objects when using mDataProp
  • + *
  • object - data object when using mData
  • + *
  • array of objects - multiple data objects when using mData
  • *
* @param {bool} [bRedraw=true] redraw the table or not * @returns {array} An array of integers, representing the list of indexes in @@ -5256,20 +5411,23 @@ var nBody = oSettings.nTBody; var i, iLen; - bRemove = (bRemove===undefined) ? false : true; + bRemove = (bRemove===undefined) ? false : bRemove; /* Flag to note that the table is currently being destroyed - no action should be taken */ oSettings.bDestroying = true; /* Fire off the destroy callbacks for plug-ins etc */ _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); - - /* Restore hidden columns */ - for ( i=0, iLen=oSettings.aoColumns.length ; i