Changeset 62


Ignore:
Timestamp:
May 30, 2011, 5:05:18 PM (6 years ago)
Author:
robert@…
Message:

Implemented classification views: percentages classified and overview of classification

Location:
trunk
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/nl/tno/massSequencing/AssaySampleController.groovy

    r59 r62  
    55class AssaySampleController {
    66        def fastaService
     7        def sampleExcelService
    78
    89        /**
     
    117118                }
    118119        }
     120       
     121        /**
     122         * Export metadata of selected samples in excel format
     123         */
     124        def exportMetaData = {
     125                def assaySamples = getAssaySamples( params );
     126                def name
     127
     128                if( assaySamples?.size() == 0 ) {
     129                        flash.error = "No samples selected";
     130                        redirect( action: "list" );
     131                        return;
     132                }
     133
     134                name = "samples";
     135
     136                // Export the metadata
     137                try {
     138                        // The export functionality needs a assaysSample-tag list, but it
     139                        // should be empty when only exporting metadata
     140                        def tags = [];
     141                        assaySamples.unique().each { assaySample ->
     142                                tags << [assaySampleId: assaySample.id, sampleName: assaySample.sample.name, assayName: assaySample.assay.name, studyName: assaySample.assay.study.name, tag: "-"]
     143                        }
     144                        response.setHeader "Content-disposition", "attachment; filename=${name}.xls"
     145
     146                        if( !sampleExcelService.exportExcelSampleData( assaySamples.unique(), tags, response.outputStream ) ) {
     147                                flash.error = "An error occurred while fetching sample data. Maybe the session has timed out.";
     148                                response.setHeader( "Content-disposition", "" );
     149                                redirect( action: "index" );
     150                        }
     151                        response.outputStream.flush();
     152                } catch( Exception e ) {
     153                        log.error( "Exception occurred during export of sequences. Probably the user has cancelled the download." );
     154                        e.printStackTrace();
     155                }
     156        }
    119157
    120158        /**
  • trunk/grails-app/controllers/nl/tno/massSequencing/classification/ClassificationController.groovy

    r61 r62  
    44
    55class ClassificationController {
     6        def classificationService;
     7       
     8    def percentageClassified = {
     9                def assaySamples = getAssaySamples();
     10               
     11                if( !assaySamples ) {
     12                        flash.error = "No samples selected"
     13                        redirect( controller: "run", action: "list" );
     14                        return;
     15                }
    616
    7     def percentageClassified = {
     17                def result = Classification.percentagesClassified( assaySamples );
     18                result[ "assaySamples" ] = assaySamples;
    819               
     20                // Determine URL to return to
     21                def entityType = params.get( 'entityType', 'run' );
     22                def entityId = params.long( 'entityId' );
     23                def returnUrl = g.createLink( controller: entityType, action: "show", id: entityId );
     24               
     25                result[ 'returnUrl'] = returnUrl;
     26                result[ "entityType" ] = entityType
     27                result[ "entityId" ] = entityId
     28               
     29                return result;
     30        }
     31       
     32        def show = {
     33                def assaySamples = getAssaySamples();
     34               
     35                if( !assaySamples ) {
     36                        flash.error = "No samples selected"
     37                        redirect( controller: "run", action: "list" );
     38                        return;
     39        }
     40               
     41                def classifications = classificationService.retrieveClassifications( assaySamples );
     42               
     43                // Filter the list of classifications on the level selected
     44                def level = params.int( 'level' );
     45                def showClassifications
     46               
     47                if( level > 0 ) {
     48                        showClassifications = classifications.findAll { it[ 0 ] == level }
     49                } else {
     50                        showClassifications = classifications;
     51                }
     52               
     53                // Determine the min/max levels and level names
     54                def (maxLevel, minLevel) = Classification.determineMinAndMaxLevels( assaySamples );
     55               
     56                def levelNames = [:];
     57                minLevel.upto( maxLevel ) { levelNumber ->
     58                        def levelEnum = Taxon.Level.find { it.number() == levelNumber }
     59                        levelNames[ levelNumber ] = levelEnum?.description();
     60                }
     61               
     62                // Determine the output type. Numbers are converted to percentages (if needed) in the view.
     63                def outputType = params.outputType == "absolute" ? "absolute" : "percentages";
     64               
     65                def entityType = params.get( 'entityType', 'run' );
     66                def entityId = params.long( 'entityId' );
     67                def returnUrl = g.createLink( controller: entityType, action: "show", id: entityId );
     68               
     69                return [
     70                        "assaySamples":                 assaySamples,
     71                        "level":                                level,
     72                        "showClassifications":  showClassifications,
     73                        "total":                                classifications[ 0 ],
     74                       
     75                        "maxLevel":                     maxLevel,
     76                        "minLevel":                     minLevel,
     77                        "levelNames":                   levelNames,
     78                       
     79                        "outputType":                   outputType,
     80                       
     81                        'returnUrl':                    returnUrl,
     82                        "entityType":                   entityType,
     83                        "entityId":                     entityId
     84          ];
     85        }
     86       
     87        def export = {
     88                def assaySamples = getAssaySamples();
     89               
     90                if( !assaySamples ) {
     91                        flash.error = "No samples selected"
     92                        redirect( controller: "run", action: "list" );
     93                        return;
     94                }
     95               
     96                // Return headers and classification data
     97                response.setHeader "Content-disposition", "attachment; filename=classifications.txt"
     98                classificationService.exportClassifications( assaySamples, response.outputStream );
     99                response.outputStream.flush();
     100        }
     101       
     102        protected List getAssaySamples() {
    9103                // Retrieve assaySamples from ids
    10104                def assaySampleIds = params.list( 'ids' );
     
    18112                }
    19113               
    20                 def result = Classification.percentagesClassified( assaySamples );
    21                 result[ "assaySamples" ] = assaySamples;
    22                
    23                 return result;
     114                return assaySamples;
    24115        }
    25116}
  • trunk/grails-app/domain/nl/tno/massSequencing/classification/Classification.groovy

    r61 r62  
    3939         * @return
    4040         */
    41         public static percentagesClassified( List assaySamples ) {
     41        public static Map percentagesClassified( List assaySamples ) {
     42                if( !assaySamples )
     43                        return [:]
     44               
    4245                // Create a hashmap with number of sequences and unclassified for each assaysample
    4346                def classifications = Classification.executeQuery( "SELECT a.id, ( SELECT SUM(c.unclassified) FROM Classification c WHERE c.assaySample = a), (SELECT SUM(sd.numSequences) FROM SequenceData sd WHERE sd.sample = a) FROM AssaySample a WHERE a IN (:assaySamples) GROUP BY a.id", [ "assaySamples": assaySamples ] );
     
    125128         */
    126129        public static determineMinAndMaxLevels( List assaySamples ) {
    127                 return Classification.executeQuery( "SELECT MAX(t.level), MIN(t.level) FROM Classification c LEFT JOIN c.taxon t LEFT JOIN c.assaySample a WHERE a IN (:assaySamples)", [ "assaySamples": assaySamples ] )[ 0 ];
     130                def levels = Classification.executeQuery( "SELECT MAX(t.level), MIN(t.level) FROM Classification c LEFT JOIN c.taxon t LEFT JOIN c.assaySample a WHERE a IN (:assaySamples)", [ "assaySamples": assaySamples ] )[ 0 ];
     131               
     132                if( levels[ 0 ] == null )
     133                        levels[ 0 ] = 6;                // Default maximum level
     134                         
     135                if( levels[ 1 ] == null )
     136                        levels[ 1 ] = 1;                // Default minimun level
     137                       
     138                return levels;
     139               
    128140        }
    129141
  • trunk/grails-app/services/nl/tno/massSequencing/ClassificationService.groovy

    r61 r62  
    326326                return inputFiles.find { it.type == type && it.numLines == numLines && !alreadyStored?.contains( it.filename ) };
    327327        }
    328 
    329         /**
    330          * Exports all known data about the classifications of these samples to an excel file
    331          * @param assaySamples  Assaysamples to export information about
    332          * @param stream                        Outputstream to write the data to
    333          * @return
    334          */
    335         def exportClassifications( def assaySamples, OutputStream stream ) {
    336                 if( assaySamples == null )
    337                         assaySamples = []
    338 
    339                 // Create csv file; sheetIndex is ignored
    340                 def sheetIndex = 0;
    341 
    342                 // Create headerrow
    343                 def headers = [ "level", "rankId", "taxon" ];
    344                 def ids = [];
    345                 assaySamples.each {
    346                         headers << it.sample.name
    347                         ids << it.id
    348                 }
    349                
     328       
     329        /**
     330         * Retrieves a list of classifications for the given assaysamples
     331         *
     332         * @param assaySamples  List of assaysamples
     333         * @param prefix                (optional) prefix that is prepended to the taxon name. e.g. '  ' can be used to indent every new level
     334         * @return                              List with classification data
     335         *
     336         * The list is returned like:
     337         *
     338         * 0    0               root                                    12      0       15      16
     339         * 1    0.1             Bacteria                                7               15      13
     340         * 2    0.1.1   Firmicutes                              6                       11
     341         * 2    0.1.2   Unclassified bacteria   1               15      2
     342         * 1    0.2             Unclassified                    5                       3
     343         *
     344         * Where the columns are:
     345         *      1.      Level number of the taxon on that line
     346         *      2.      rank ID: identifier for the given line. The identifier is unique per output file, but can be reused in new output files.
     347         *      3.      Taxon name
     348         *      4.      Every column shows the number of sequences for that taxon in a an assaysample. The first column matches the first assaySample given etc.
     349         */
     350        def retrieveClassifications( def assaySamples, String prefix = "" ) {
    350351                // Structure to store the data in
    351352                def data = [];
     
    355356
    356357                // Find the maximum level present in this classification list
    357                 def levels = Classification.determineMinAndMaxLevels( assaySamples ); 
     358                def levels = Classification.determineMinAndMaxLevels( assaySamples );
    358359                def maxLevel = levels[ 0 ]
    359360                def minLevel = levels[ 1 ]
     
    392393                for( def i = 0; i < assaySamples.size(); i++ ) {
    393394                        assaySampleIndex[ assaySamples[ i ].id ] = i;
    394                 } 
     395                }
    395396               
    396397                // Append classifications entry to the list with details about the numbers of unclassified sequences
    397398                //  AND a.id IN (:assaySampleIds)
    398399                def extraClassifications = Classification.executeQuery( "SELECT a.id, SUM( c.unclassified ), (SELECT SUM(sd.numSequences) FROM SequenceData sd WHERE sd.sample = a) FROM AssaySample a, Classification c WHERE c.assaySample = a AND  a IN (:assaySamples) GROUP BY a.id", [ "assaySamples": assaySamples ] );
    399                 def rootLine = [ minLevel - 1, rootId, "root" ]
     400                def rootLine = [ minLevel - 1, rootId, "root" ] + [ 0 ] * assaySamples.size();
    400401                extraClassifications.each {
    401                         // Add a classification in order to show the 'unclassified' values 
     402                        // Add a classification in order to show the 'unclassified' values
    402403                        classifications << [
    403404                                [ 'total': it[ 2 ], 'unclassified': it[ 2 ] - it[ 1 ] ],
     
    406407                        ]
    407408                       
    408                         // Create a root line
    409                         rootLine[ assaySampleIndex[ it[ 0 ] ] + 3 ] = it[ 2 ];
     409                        // Create a root line with total numbers of sequences for the given sample
     410                        rootLine[ assaySampleIndex[ it[ 0 ] ] + 3 ] = it[ 2 ] ?: 0;
    410411                }
    411412                data << rootLine;
     
    439440                                                        // Each unclassified line should be repeated up to the highest level, in order
    440441                                                        // to have the same number of sequences at every level.
    441                                                         def ucl = unClassifiedLines.remove( lvl ); 
     442                                                        def ucl = unClassifiedLines.remove( lvl );
    442443                                                        lvl.upto( maxLevel - 1 ) { unclassifiedLevel ->
    443                                                                 def newLine = [ unclassifiedLevel + 1 ] + rankId( unclassifiedLevel + 1 ) + ucl[2..-1];
     444                                                                def name = ( prefix * ( unclassifiedLevel + 1 ) ) + ucl[ 2 ]
     445                                                                def newLine = [ unclassifiedLevel + 1 ] + rankId( unclassifiedLevel + 1 ) + name + ucl[3..-1];
    444446                                                                data << newLine;
    445                                                         } 
     447                                                        }
    446448                                                }
    447449                                        }
     
    456458                               
    457459                                // Create a new line, because we arrived at a new taxon
    458                                 currentLine = [ taxon.level, rank, taxon.name ]
     460                                currentLine = [ taxon.level, rank, ( prefix * Math.max( 0, taxon.level ) ) + taxon.name ]
    459461                                hasValues = false;
    460462                               
     
    464466                               
    465467                                // Create as many entries in the list as there are samples
    466                                 numAssaySamples.times { 
     468                                numAssaySamples.times {
    467469                                        currentLine << ""
    468                                         unClassifiedLine << "" 
     470                                        unClassifiedLine << ""
    469471                                }
    470472                               
     
    493495                }
    494496               
     497                return data;
     498        }
     499       
     500        /**
     501         * Exports all known data about the classifications of these samples to an excel file
     502         * @param assaySamples  Assaysamples to export information about
     503         * @param stream                Outputstream to write the data to
     504         * @return
     505         */
     506        def exportClassifications( def assaySamples, OutputStream stream ) {
     507                if( assaySamples == null )
     508                        assaySamples = []
     509
     510                // Create csv file; sheetIndex is ignored
     511                def sheetIndex = 0;
     512
     513                // Create headerrow
     514                def headers = [ "level", "rankId", "taxon" ];
     515                def ids = [];
     516                assaySamples.each {
     517                        headers << it.sample.name
     518                        ids << it.id
     519                }
     520               
     521                def data = retrieveClassifications( assaySamples );
     522               
    495523                // Create an excel sheet
    496524                def wb = csvService.create();
  • trunk/grails-app/views/assay/show.gsp

    r60 r62  
    6565        </g:if>
    6666        <g:else>
    67                 <form id="sampleForm"><input type="hidden" name="assayId" value="${assay.id}" /></form>
     67                <form id="sampleForm"><input type="hidden" name="assayId" value="${assay.id}" /><input type="hidden" name="entityType" value="assay" /><input type="hidden" name="entityId" value="${assay.id}" /></form>
    6868                <table class="paginate serverside" rel="<g:createLink controller="assay" action="showSampleData" id="${assay.id}" />" id="samples">
    6969                        <thead>
     
    115115                                       
    116116                <p class="options multiple">
    117                         <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportAsFasta" />', '#samples', 'Please select one or more samples to export' ); return false;">Export as fasta</a>
     117                        <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportAsFasta" />', '#samples', 'Please select one or more samples to export' ); return false;">Export as fasta</a><br />
     118                        <a class="excel" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportMetaData" />', '#samples', 'Please select one or more samples to export' ); return false;">Export metadata</a><br />
     119                        <a class="classification_export" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="export" />', '#samples', 'Please select one or more samples to export' ); return false;">Export classification</a><br />
    118120                </p>
     121               
     122                <p class="options multiple last">
     123                        <a class="classification" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="show" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Show classification</a><br />
     124                        <a class="classification_percentage" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="percentageClassified" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Percentage classified</a><br />
     125                </p>           
    119126               
    120127                <div style="clear: both;"></div>
  • trunk/grails-app/views/classification/percentageClassified.gsp

    r61 r62  
    77                <h1>Percentages classified</h1>
    88               
    9                 <table border="0" class="paginate">
     9                <table border="0" class="sortable">
    1010                        <thead>
    1111                                <tr>
     
    1616                                       
    1717                                        <g:each in="${levels}" var="level">
    18                                                 <th>${level.value}</th>
     18                                                <th class="formatted_num">${level.value}</th>
    1919                                        </g:each>
    2020                                </tr>
     
    2929                                       
    3030                                        <g:each in="${item.value.data}" var="data">
    31                                                 <td>
    32                                                         <g:if test="${item.value.numSequences > 0}">
     31                                                <td><g:if test="${item.value.numSequences > 0}">
    3332                                                                <g:formatNumber number="${data.value.percentageClassified * 100}" format="#" />%
    34                                                         </g:if>
    35                                                 </td>
     33                                                        </g:if></td>
    3634                                        </g:each>
    3735                                </tr>
     
    3937                        </tbody>
    4038                </table>
     39                <form id="sampleForm">
     40                        <input type="hidden" name="entityType" value="${entityType}" />
     41                        <input type="hidden" name="entityId" value="${entityId}" />
     42                        <g:each in="${assaySamples}" var="assaySample"><input type="hidden" name="ids" value="${assaySample.id}"></g:each>
     43                </form>
     44                <p class="options">
     45                        <a class="fasta" href="#" onClick="submitFormAbsoluteUrl( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportAsFasta" />' ); return false;">Export as fasta</a>
     46                        <a class="classification" href="#" onClick="submitFormAbsoluteUrl( $( '#sampleForm' ), '<g:createLink controller="classification" action="show" />' ); return false;">Show classification</a>
     47                        <a class="classification_export" href="#" onClick="submitFormAbsoluteUrl( $( '#sampleForm' ), '<g:createLink controller="classification" action="export" />' ); return false;">Export classification</a>
     48                        <a class="back" href="${returnUrl}">Return to ${entityType}</a>
     49                </p>                   
    4150        </body>
    4251</html>
  • trunk/grails-app/views/layouts/main.gsp

    r59 r62  
    1717                <script type="text/javascript" src="${resource(dir: 'js', file: 'topnav.js')}"></script>
    1818                <script type="text/javascript" src="${resource(dir: 'js', file: 'jquery.dataTables.min.js')}"></script>
     19                <script type="text/javascript" src="${resource(dir: 'js', file: 'dataTables.formatted-num.js')}"></script>
    1920
    2021                <!-- javascript charts using flot -->
  • trunk/grails-app/views/run/show.gsp

    r61 r62  
    100100        </g:if>
    101101        <g:else>
    102                 <form id="sampleForm"><input type="hidden" name="runId" value="${run.id}" /></form>
     102                <form id="sampleForm"><input type="hidden" name="runId" value="${run.id}" /><input type="hidden" name="entityType" value="run" /><input type="hidden" name="entityId" value="${run.id}" /></form>
    103103                <table class="paginate serverside" rel="<g:createLink controller="run" action="showSampleData" id="${run.id}" />" id="samples">
    104104                        <thead>
     
    165165                        <g:if test="${numReadableAssaySamples > 0}">
    166166                                <a class="fasta" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportAsFasta" />', '#samples', 'Please select one or more samples to export' ); return false;">Export as fasta</a><br />
     167                                <a class="excel" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="assaySample" action="exportMetaData" />', '#samples', 'Please select one or more samples to export' ); return false;">Export metadata</a><br />
     168                                <a class="classification_export" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="export" />', '#samples', 'Please select one or more samples to export' ); return false;">Export classification</a><br />
    167169                        </g:if>
    168170                        <g:else>
    169171                                <a class="fasta disabled" href="#" onClick="return false;">Export as fasta</a><br />
    170                         </g:else>
    171                        
     172                                <a class="excel disabled" href="#" onClick="return false;">Export metadata</a><br />
     173                                <a class="classification_export disabled" href="#" onClick="return false;">Export classification</a><br />
     174                        </g:else>
     175                </p>
     176                <p class="options multiple last">
    172177                        <g:if test="${numReadableAssaySamples > 0}">
    173                                 <a class="classification" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="percentageClassified" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Percentage classified</a><br />
    174                         </g:if>
    175                         <g:else>
    176                                 <a class="classification disabled" href="#" onClick="return false;">Percentage classified</a><br />
    177                         </g:else>
    178                        
     178                                <a class="classification" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="show" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Show classification</a><br />
     179                                <a class="classification_percentage" href="#" onClick="submitPaginatedForm( $( '#sampleForm' ), '<g:createLink controller="classification" action="percentageClassified" />', '#samples', 'Please select one or more samples to view classification' ); return false;">Percentage classified</a><br />
     180                        </g:if>
     181                        <g:else>
     182                                <a class="classification disabled" href="#" onClick="return false;">Show classification</a><br />
     183                                <a class="classification_percentage disabled" href="#" onClick="return false;">Percentage classified</a><br />
     184                        </g:else>
    179185                </p>
    180186               
  • trunk/web-app/css/buttons.css

    r50 r62  
    1313}
    1414
    15 .options.multiple { float: left; width: 300px; }
     15.options.multiple { float: left; width: 250px; }
     16.options.last { float: left; width: 180px; }
    1617
    1718.options .separator { margin-left: 20px; }
     
    1920#content .options a.disabled { color: #aaa; cursor: default; }
    2021
     22.options a.back {
     23        background-image: url(../plugins/famfamfam-1.0.1/images/icons/arrow_left.png);
     24}
    2125.options a.fasta {
    2226        background-image: url(../plugins/famfamfam-1.0.1/images/icons/brick_go.png);
     
    5256        background-image: url(../plugins/famfamfam-1.0.1/images/icons/delete.png);
    5357}
     58
     59.options a.classification {
     60        background-image: url(../plugins/famfamfam-1.0.1/images/icons/tag_blue.png);
     61}
     62
     63.options a.classification_percentage {
     64        background-image: url(../plugins/famfamfam-1.0.1/images/icons/tag_red.png);
     65}
     66
     67.options a.classification_export {
     68        background-image: url(../plugins/famfamfam-1.0.1/images/icons/tag_green.png);
     69}
     70
  • trunk/web-app/css/metagenomics.css

    r59 r62  
    511511
    512512.importProcessedFiles td { vertical-align: middle; }
     513
     514/* Classification table */
     515.filter { margin-bottom: 10px; line-height: 3em; text-align: right; float: right; margin-top: -3em; }
     516.filter label { vertical-align: inherit; text-align: right; line-height: 26px; margin-right: 5px;}
     517.classification .total td { font-weight: bold; }
     518.classification th.sample, .classification td.value { text-align: right; }
     519.classification td.level .levelnumber { display: inline-block; width: 20px; *display: inline; zoom: 1; }
  • trunk/web-app/js/forms.js

    r60 r62  
    11function submitForm( form, url ) {
     2        submitFormAbsoluteUrl( form, baseUrl + url );
     3}
     4
     5function submitFormAbsoluteUrl( form, url ) {
    26        if( form == undefined || !form )
    37                return;
    48
    5         form.attr( 'action', baseUrl + url );
     9        form.attr( 'action', url );
    610        form.submit();
    711}
  • trunk/web-app/js/paginate.js

    r60 r62  
    2424                        iDisplayLength: 10,                                     // Number of items shown on one page.
    2525                        aoColumnDefs: [
    26                                 { "bSortable": false, "aTargets": ["nonsortable"] }     // Disable sorting on all columns with th.nonsortable
     26                                { "bSortable": false, "aTargets": ["nonsortable"] },                            // Disable sorting on all columns with th.nonsortable
     27                                { "sSortDataType": "formatted-num", "aTargets": ["formatted-num"] }     // Make sorting possible on formatted numbers
    2728                        ]                                               
    2829                });
     
    5455                        iDisplayLength: 10,                                     // Number of items shown on one page.
    5556                        aoColumnDefs: [
    56                                 { "bSortable": false, "aTargets": ["nonsortable"] }     // Disable sorting on all columns with th.nonsortable
     57                                { "bSortable": false, "aTargets": ["nonsortable"] },                            // Disable sorting on all columns with th.nonsortable
     58                                { "sSortDataType": "formatted-num", "aTargets": ["formatted-num"] }     // Make sorting possible on formatted numbers
    5759                        ],
    5860                       
     
    8183        });
    8284       
     85        // Initialize tables that should be sortable, but not paginated
     86        $( selector + ' .sortable').each(function(idx, el) {
     87                var $el = $(el);
     88               
     89                $el.dataTable({
     90                        bJQueryUI: true,
     91                        bAutoWidth: false,
     92                        bFilter: false,
     93                        bLengthChange: false,
     94                        bPaginate: false,
     95                        iCookieDuration: 86400,                         // Save cookie one day
     96                        sScrollY: '350px',
     97                        sScrollX: '100%',
     98                        bScrollCollapse: true,
     99                        aoColumnDefs: [
     100                                { "bSortable": false, "aTargets": ["nonsortable"] },                    // Disable sorting on all columns with th.nonsortable
     101                                { "sType": "formatted-num", "aTargets": ["formatted_num"] }             // Make sorting possible on formatted numbers
     102                        ]                                               
     103                });
     104        });     
     105       
    83106        // Show hide paginated buttons
    84107        showHidePaginatedButtons( selector );
Note: See TracChangeset for help on using the changeset viewer.