Changeset 66

Show
Ignore:
Timestamp:
14-06-11 15:27:11 (3 years ago)
Author:
robert@…
Message:

Improved searches

Location:
trunk
Files:
7 modified

Legend:

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

    r63 r66  
    401401                                                 
    402402                                                criterion.value = Double.valueOf( percentage ) / 100.0; 
    403                                         } else if( formCriterion.value =~ /^taxon:[0-9]+$/ ) { 
    404                                                 println "TAXON FOUND!!!"; 
     403                                        } else if( formCriterion.othertaxon =~ /^taxon:[0-9]+$/ ) { 
    405404                                                // Taxon: parse the taxon ID and set taxon 
    406                                                 def otherTaxonId = ( formCriterion.value =~ /[^0-9]/ ).replaceAll( "" ); 
     405                                                def otherTaxonId = ( formCriterion.othertaxon =~ /[^0-9]/ ).replaceAll( "" ); 
    407406                                                def otherTaxon = Taxon.get( Long.valueOf( otherTaxonId ) ); 
    408407                                                 
    409408                                                if( !otherTaxon ) { 
    410                                                         log.debug "Criterion value looks like a taxon, but taxon can't be found for ID: " + otherTaxonId + " (value: " + formCriterion.value + ")"; 
    411                                                         flash.error += "Criterion could not be used: value " + formCriterion.value.encodeAsHtml() + " could not be parsed as a taxon.<br />\n"; 
     409                                                        log.debug "Criterion value looks like a taxon, but taxon can't be found for ID: " + otherTaxonId + " (value: " + formCriterion.othertaxon + ")"; 
     410                                                        flash.error += "Criterion could not be used: value " + formCriterion.othertaxon.encodeAsHtml() + " could not be parsed as a taxon.<br />\n"; 
    412411                                                        continue; 
    413412                                                } 
  • trunk/grails-app/views/query/index.gsp

    r63 r66  
    7777                                                        Factor 
    7878                                                </span>                          
    79                                                 <span class="value"> 
    80                                                         Value 
     79                                                <span class="combinedValue"> 
     80                                                        <span class="item">Value</span> 
     81                                                        <span class="combinator">or</span> 
     82                                                        <span class="item">Other taxon</span> 
    8183                                                </span> 
    8284                                        </li> 
     
    104106                                                        <input class='text' type="text" id="factor" name="criteria.0.factor" /> 
    105107                                                </span> 
    106                                                 <span class="value"> 
    107                                                         <input class='text' type="text" id="value" name="criteria.0.value" /> 
     108                                                <span class="combinedValue"> 
     109                                                        <input class='text' type="text" id="value" onChange="toggleValueAndTaxonInput();" name="criteria.0.value" /> 
     110                                                        <span class="combinator">or</span> 
     111                                                        <input class='text' type="text" id="otherTaxonText" onChange="toggleValueAndTaxonInput();" name="criteriataxon" />  
     112                                                        <input type="hidden" name="criteria.0.othertaxon" id="otherTaxonValue"/>  
    108113                                                </span> 
    109114                                                <span class="addButton"> 
  • trunk/src/groovy/nl/tno/massSequencing/query/AssaySampleSearch.groovy

    r63 r66  
    3939        @Override 
    4040        protected Map defaultHQL() { 
    41                 return [ "select": [ "a", "a.sample.name", "a.assay.name", "a.assay.study.name", "a.numSequences" ], "from": " AssaySample a ", "join": "", "joinConditions": [], "where": [], "groupBy": [], "having": [], "parameters": [:], "fieldNames": [ "Sample name", "Assay name", "Study name", "# sequences" ], "fieldIds": [ "samplename", "assayname", "studyname", "numSequences" ] ] 
     41                return [ "select": [ "a", "a.sample.name", "a.assay.name", "a.assay.study.name", "a.numSequences" ], "from": " AssaySample a ", "join": "", "joinConditions": [], "where": [], "groupBy": [], "having": [], "parameters": [:], "fieldNames": [ "Sample name", "Assay name", "Study name", "# sequences" ], "fieldIds": [ "samplename", "assayname", "studyname", "numSequences" ], "showFieldFuncs": [ null, null, null, null ] ] 
    4242        } 
    4343 
  • trunk/src/groovy/nl/tno/massSequencing/query/Criterion.groovy

    r63 r66  
    4141                List fieldNames = []; 
    4242                List fieldIds = []; 
     43                List fieldShowFuncs = []; 
    4344                List whereClause = [] 
    4445                List havingClause = []; 
     
    9596                        fieldNames << "# " + taxon.name 
    9697                        fieldIds << "absolute-" + taxon.id 
     98                        fieldShowFuncs << null; 
    9799                        fieldNames << "# " + value.name 
    98100                        fieldIds << "absolute-" + value.id 
     101                        fieldShowFuncs << null; 
    99102                         
    100103                        joinClause = ", Classification " + prefix + "1Classification, Classification " + prefix + "2Classification"; 
     
    121124                        fieldNames << "% " + taxon.name 
    122125                        fieldIds <<  "relative-" + taxon.id 
     126                        fieldShowFuncs << { percentage -> return sprintf( "%.1f%%", percentage * 100 ); } 
    123127                         
    124128                        joinClause = ", Classification " + prefix + "Classification"; 
     
    142146                        fieldNames << "# " + taxon.name 
    143147                        fieldIds << "absolute-" + taxon.id 
     148                        fieldShowFuncs << null; 
    144149 
    145150                        joinClause = ", Classification " + prefix + "Classification"; 
     
    159164                def having = havingClause ? "( " + havingClause.join( " AND " ) + " )" : "" 
    160165         
    161                 return [ "select": selectClause, "join": joinClause, "joinConditions": onClause, "where": where, "having": having, "parameters": parameters, "fieldNames": fieldNames, "fieldIds": fieldIds ] 
     166                return [ "select": selectClause, "join": joinClause, "joinConditions": onClause, "where": where, "having": having, "parameters": parameters, "fieldNames": fieldNames, "fieldIds": fieldIds, "showFieldFuncs": fieldShowFuncs ] 
    162167        } 
    163168 
  • trunk/src/groovy/nl/tno/massSequencing/query/Search.groovy

    r63 r66  
    137137                         
    138138                        criteriaHQL.each { 
    139                                 println "  " + it.key + " = " + hql[ it.key ] + " + "+ it.value 
    140                                   
    141139                                if( it.value ) 
    142140                                        hql[ it.key ] += it.value 
     
    202200                                i++; 
    203201                        } 
    204                         println "SAVING DATA"; 
    205                          
    206                         println data.names; 
    207                         println indicesUsed; 
    208                         println hql.select[ indicesUsed ]; 
    209                         data.data = entities.collect { it[ indicesUsed ] } 
     202                         
     203                        // Pick the selected fields from the data and processe the values 
     204                        // according to the functions given (e.g. format percentages) 
     205                        entities.each { entityData -> 
     206                                def dataLine = [];  
     207                                for( def j in indicesUsed ) { 
     208                                        dataLine << ( hql.showFieldFuncs[ j - 1 ] ? hql.showFieldFuncs[ j - 1 ]( entityData[ j ] ) : entityData[ j ] ); 
     209                                } 
     210                                data.data << dataLine; 
     211                        } 
     212                         
    210213                        resultData = data; 
    211214                } 
     
    224227         */ 
    225228        protected Map defaultHQL() { 
    226                 return [ "select": [ "a" ], "from": " AssaySample a ", "join": "", "joinConditions": [], "where": [], "groupBy": [ ], "having": [], "parameters": [:], "fieldNames": [], "fieldIds": [] ] 
     229                return [ "select": [ "a" ], "from": " AssaySample a ", "join": "", "joinConditions": [], "where": [], "groupBy": [ ], "having": [], "parameters": [:], "fieldNames": [], "fieldIds": [], "showFieldFuncs": [] ] 
    227230        } 
    228231    
  • trunk/web-app/css/query.css

    r63 r66  
    2121#searchForm ul#criteria li .factor input { width: 60px; } 
    2222 
    23 #searchForm ul#criteria li .value { width: 240px; } 
    24 #searchForm ul#criteria li .value input { width: 220px; } 
     23#searchForm ul#criteria li .combinedValue { width: 340px; font-weight: normal; } 
     24#searchForm ul#criteria li .combinedValue span.item { vertical-align: bottom; width: 140px; font-weight: bold; } 
     25#searchForm ul#criteria li .combinedValue input { width: 140px; } 
     26 
     27#searchForm ul#criteria li span.combinator { vertical-align: bottom; width: 16px; } 
     28 
     29#searchForm ul#criteria li .value { width: 140px; } 
     30#searchForm ul#criteria li .othertaxon { width: 165px; } 
     31 
    2532 
    2633#searchForm ul#criteria li .addButton { margin: 4px 0; } 
  • trunk/web-app/js/query.js

    r63 r66  
    1111        $( '#queryFieldSelect' ).remove(); 
    1212 
    13         $( "#queryFieldText" ).autocomplete({ 
     13        createAutoComplete( $( '#queryFieldText' ), $( '#queryField' ), true ); 
     14        createAutoComplete( $( '#otherTaxonText' ), $( '#otherTaxonValue' ), false ); 
     15}); 
     16 
     17function createAutoComplete( textField, valueField, disableIfWrong ) { 
     18        textField.autocomplete({ 
    1419                minLength: 2, 
    1520                source: queryableFields, 
    1621                focus: function( event, ui ) { 
    17                         $( "#queryFieldText" ).val( ui.item.show ); 
     22                        textField.val( ui.item.show ); 
    1823                        return false; 
    1924                }, 
    2025                select: function( event, ui ) { 
    21                         selectQueryableFieldItem( ui.item ); 
     26                        selectQueryableFieldItem( ui.item, textField, valueField, disableIfWrong ); 
    2227                        //$( "#queryFieldEntity" ).html( ui.item.entity ); 
    2328                        return false; 
     
    2530                change: function( event, ui ) { 
    2631                        // If the user has left the field blank, remove the field that has been selected 
    27                         if( $( '#queryFieldText' ).val().trim() == "" ) { 
    28                                 selectQueryableFieldItem( null ); 
     32                        if( textField.val().trim() == "" ) { 
     33                                selectQueryableFieldItem( null, textField, valueField, disableIfWrong ); 
    2934                        } 
    3035                        // If no item is selected and the user has entered some text, select the first one 
    3136                        // See https://github.com/scottgonzalez/jquery-ui-extensions/blob/master/autocomplete/jquery.ui.autocomplete.selectFirst.js 
    3237                        else if( ui.item == null ) { 
    33                                 var el = $( '#queryFieldText' ).autocomplete().data( "autocomplete" ); 
     38                                var el = textField.autocomplete().data( "autocomplete" ); 
    3439                                 
    3540                                // Check how many fields are in the list. However, if the user first enters 
     
    3843                                // For that reason we perform an extra check to see whether the value of the 
    3944                                // first item matches the entered text 
    40                                 var searchResults = $.ui.autocomplete.filter( queryableFields, $( '#queryFieldText' ).val() ); 
     45                                var searchResults = $.ui.autocomplete.filter( queryableFields, textField.val() ); 
    4146                                if( searchResults && searchResults.length > 0 ) { 
    42                                         selectQueryableFieldItem( searchResults[ 0 ] ); 
     47                                        selectQueryableFieldItem( searchResults[ 0 ], textField, valueField, disableIfWrong ); 
    4348                                } else { 
    4449                                        // Clear the input field if nothing is in the list 
    45                                         selectQueryableFieldItem( null ); 
     50                                        selectQueryableFieldItem( null, textField, valueField, disableIfWrong ); 
    4651                                } 
    4752                        } 
     
    5459                        .appendTo( ul ); 
    5560        }; 
    56 }); 
     61         
     62} 
    5763 
    5864/** 
     
    6066 * @param item  THe selected item or null if nothing is selected 
    6167 */ 
    62 function selectQueryableFieldItem( item ) { 
     68function selectQueryableFieldItem( item, textField, valueField, disableIfWrong ) { 
    6369        var show = ""; 
    6470        var value = ""; 
     
    6672        if( item != null ) { 
    6773                show = item.show; 
    68                 value = item.value; 
     74                 
     75                if( disableIfWrong ) 
     76                        value = item.value; 
     77                else 
     78                        value = "taxon:" + item.value; 
    6979 
    7080                // Only hide the text if something is chosen. Otherwise, the entered 
    7181                // text remains 
    72                 $( "#queryFieldText" ).val( show ); 
    73         } 
    74          
    75         $( "#queryField" ).val( value ); 
    76          
    77         if( value == "" ) { 
    78                 $( "#queryFieldText" ).css( "background-color", "#FDD" ); 
    79                 $( ".newCriterion .addButton a" ).addClass( "disabled" ); 
    80         } else { 
    81                 $( "#queryFieldText" ).css( "background-color", "white" ); 
    82                 $( ".newCriterion .addButton a" ).removeClass( "disabled" ); 
     82                textField.val( show ); 
     83        } 
     84         
     85        valueField.val( value ); 
     86         
     87        if( disableIfWrong ) { 
     88                if( value == "" ) { 
     89                        textField.css( "background-color", "#FDD" ); 
     90                        $( ".newCriterion .addButton a" ).addClass( "disabled" ); 
     91                } else { 
     92                        textField.css( "background-color", "white" ); 
     93                        $( ".newCriterion .addButton a" ).removeClass( "disabled" ); 
     94                } 
    8395        } 
    8496         
     
    100112} 
    101113 
     114function toggleValueAndTaxonInput() { 
     115        if( $( '#value' ).val() != "" ) { 
     116                // Disable taxon input 
     117                $( '#otherTaxonText' ).val( '' ); 
     118                $( '#otherTaxonValue' ).val( '' ); 
     119                $( '#otherTaxonText' ).attr( 'disabled', true ); 
     120        } else if( $( '#otherTaxonText' ).val() != "" ) { 
     121                // Disable value input 
     122                $( '#value' ).val( '' ); 
     123                $( '#value' ).attr( 'disabled', true ); 
     124        } else { 
     125                // Enable both 
     126                $( '#value' ).attr( 'disabled', false ); 
     127                $( '#otherTaxonText' ).attr( 'disabled', false ); 
     128        } 
     129} 
    102130/******************************************************** 
    103131 *  
     
    120148        var factor = $( '#searchForm input#factor' ).val(); 
    121149        var value = $( '#searchForm input#value' ).val(); 
     150        var otherTaxonName = $( '#searchForm input#otherTaxonText' ).val(); 
     151        var otherTaxonValue = $( '#searchForm input#otherTaxonValue' ).val(); 
    122152         
    123153        if( field_descriptor == "" ) { 
     
    127157         
    128158        // Show the title and a remove button 
    129         showCriterion(field_descriptor, taxonName, value, operator, factor); 
     159        showCriterion(field_descriptor, taxonName, value, otherTaxonValue, otherTaxonName, operator, factor); 
    130160        toggleSearchMode(); 
    131161         
     
    136166        $( '#searchForm input#value' ).val( '' ); 
    137167        $( '#searchForm input#factor' ).val( '' ); 
     168        $( '#searchForm input#otherTaxonText' ).val( '' ); 
     169        $( '#searchForm input#otherTaxonValue' ).val( '' ); 
    138170        $( "#searchForm .newCriterion .addButton a" ).addClass( "disabled" ); 
    139          
     171 
     172        toggleValueAndTaxonInput(); 
    140173} 
    141174 
     
    191224 * Shows a criterium on the screen 
    192225 */ 
    193 function showCriterion( taxon, taxonName, value, operator, factor ) { 
     226function showCriterion( taxon, taxonName, value, otherTaxonValue, otherTaxonName, operator, factor ) { 
    194227        // Create data elements 
    195228        var fieldSpan = createCriterionElement( 'taxon', taxon, taxonName ); 
     
    197230        var factorSpan = createCriterionElement( 'factor', factor, ( factor == "" || factor == undefined ? "" : factor + "x" ) ); 
    198231        var valueSpan = createCriterionElement( 'value', value ); 
     232        var orSpan = $( '<span class="combinator"> </span>' ); 
     233        var otherTaxonSpan = createCriterionElement( 'othertaxon', otherTaxonValue, otherTaxonName ); 
    199234         
    200235        var input = $( '<a href="#" onClick="return false;"><img src="' + baseUrl + '/plugins/famfamfam-1.0.1/images/icons/delete.png" border="0"></a>' ); 
     
    213248        // Append them to a list item 
    214249        var li = $( '<li></li>' ); 
    215         li.append( fieldSpan ).append( "\n" ).append( operatorSpan ).append( "\n" ).append( factorSpan ).append( "\n" ).append( valueSpan ).append( "\n" ).append( span ); 
     250        li.append( fieldSpan ).append( "\n" ).append( operatorSpan ).append( "\n" ).append( factorSpan ).append( "\n" ).append( valueSpan ).append( "\n" ).append( orSpan ).append( "\n" ).append( otherTaxonSpan ).append( "\n" ).append( span ); 
    216251         
    217252        $('#criteria .newCriterion').before(li);