Changeset 1962 for trunk


Ignore:
Timestamp:
Jul 12, 2011, 5:20:34 PM (8 years ago)
Author:
robert@…
Message:
  • Added debug statements and a bugfix to login and logout methods
  • Added an autocomplete method that shows the possible values when searching for an exact match in a field
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/authentication/LoginController.groovy

    r1773 r1962  
    7373                }
    7474
     75                log.info( "Remote authentication with " + consumer + " and " + token )
     76               
    7577                def returnUrl;
    7678               
  • trunk/grails-app/controllers/dbnp/authentication/LogoutController.groovy

    r1932 r1962  
    11package dbnp.authentication
    22
     3import org.codehaus.groovy.grails.commons.ConfigurationHolder
    34import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
    45
     
    3738                        returnUrl = params.returnUrl;
    3839                } else {
    39                         returnUrl = g.createLink(controller: 'home', absolute: true)
     40                        // Return to baseURL
     41                        returnUrl = ConfigurationHolder.config.grails.serverURL
    4042                }
    4143               
  • trunk/grails-app/controllers/dbnp/query/AdvancedQueryController.groovy

    r1919 r1962  
    44import org.dbnp.gdt.*
    55import dbnp.studycapturing.*;
     6import grails.converters.JSON
    67
    78/**
     
    113114                        return;
    114115                }
    115                
     116
    116117                // Attach all objects to the current hibernate thread, because the
    117118                // object might be attached to an old thread, since the results are
     
    125126                render( view: view, model: [search: s, queryId: queryId, actions: determineActions(s)] );
    126127        }
    127        
     128
    128129        /**
    129130         * Shows a list of searches that have been saved in session
     
    234235                redirect( action: "show", id: queryId );
    235236        }
    236        
     237
    237238        /**
    238239         * Registers a search from a module with GSCF, in order to be able to refine the searches
     
    245246                def tokens = params.list( 'tokens' );
    246247                def results
    247                
     248
    248249                switch( entity ) {
    249250                        case "Study":
     
    261262                                return;
    262263                }
    263                
     264
    264265                // Register and save search
    265266                Search s = Search.register( name, url, entity, results );
    266267                int searchId = saveSearch( s );
    267                
     268
    268269                // Redirect to the search screen
    269270                def params = [
    270                         "criteria.0.entityfield": s.entity,
    271                         "criteria.0.operator": "in",
    272                         "criteria.0.value": searchId
    273                 ];
     271                                        "criteria.0.entityfield": s.entity,
     272                                        "criteria.0.operator": "in",
     273                                        "criteria.0.value": searchId
     274                                ];
    274275
    275276                redirect( action: "index", params: params)
     277        }
     278
     279        /**
     280         * Retrieves a list of distinct values that have been entered for the given field.
     281         */
     282        def getFieldValues = {
     283                def entityField = params.entityfield;
     284                entityField = entityField.split( /\./ );
     285                def entity = entityField[ 0 ];
     286                def field = entityField[ 1 ];
     287               
     288                def term = params.term
     289                def termLike = "%" + term + "%"
     290               
     291                // Skip searching all fields
     292                if( entity == "*" || field == "*" ) {
     293                        render [] as JSON
     294                        return;
     295                }
     296               
     297                def entityClass = TemplateEntity.parseEntity( 'dbnp.studycapturing.' + entity)
     298               
     299                // Domain fields can be easily found
     300                if( field == "Template" ) {
     301                        render Template.executeQuery( "select distinct t.name FROM Template t where t.entity = :entity AND t.name LIKE :term", [ "entity": entityClass, "term": termLike ] ) as JSON
     302                        return;
     303                }
     304               
     305                // Determine domain fields of the entity
     306                def domainFields = entityClass.giveDomainFields();
     307                def domainField = domainFields.find { it.name == field };
     308               
     309                // The values of a domainfield can be determined easily
     310                if( domainField ) {
     311                        render entityClass.executeQuery( "select distinct e." + field + " FROM " + entity + " e WHERE e." + field + " LIKE :term", [ "term": termLike ] ) as JSON
     312                        return;
     313                }
     314               
     315                // Find all fields with this name and entity, in order to determine the type of the field
     316                def fields = TemplateField.findAll( "FROM TemplateField t WHERE t.name = :name AND t.entity = :entity", [ "name": field, "entity": entityClass ] );
     317
     318                // If the field is not found, return an empty list
     319                def listValues = [];
     320                if( !fields ) {
     321                        render listValues as JSON
     322                }
     323
     324                // Determine the type (or types) of the field
     325                def fieldTypes = fields*.type.unique()*.casedName;
     326               
     327                // Now create a list of possible values, based on the fieldType(s)
     328               
     329                // Several types of fields are handled differently.
     330                // The 'simple' types (string, double) are handled by searching in the associated 'templateXXXXFields' table
     331                // The 'complex' types (stringlist, template etc., referencing another database table) can't be
     332                // handled correctly (the same way), since the HQL INDEX() function doesn't work on those relations.
     333                // We do a search for these types to see whether any field with that type fits this criterion, in order to
     334                // filter out false positives later on.
     335                fieldTypes.each { type ->
     336                        // Determine field name
     337                        def fieldName = "template" + type + 'Fields'
     338
     339                        switch( type ) {
     340                                case 'String':
     341                                case 'Text':
     342                                case 'File':
     343                                        // 'Simple' field types (string values)
     344                                        listValues += entityClass.executeQuery( "SELECT DISTINCT f FROM " + entity + " s left join s." + fieldName + " f WHERE index(f) = :field AND f LIKE :term", [ "field": field, "term": termLike ] );
     345                                        break;
     346                                       
     347                                case 'Date':
     348                                case 'Double':
     349                                case 'Long':
     350                                        // 'Simple' field types that can be converted to string and compared
     351                                        listValues += entityClass.executeQuery( "SELECT DISTINCT f FROM " + entity + " s left join s." + fieldName + " f WHERE index(f) = :field AND str(f) LIKE :term", [ "field": field, "term": termLike ] );
     352                                        break;
     353                                case 'Boolean':
     354                                        // Simple field types that don't support like
     355                                        listValues += entityClass.executeQuery( "SELECT DISTINCT f FROM " + entity + " s left join s." + fieldName + " f WHERE index(f) = :field", [ "field": field ] );
     356                                        break;
     357                               
     358                                case 'RelTime':
     359                                        // RelTime values should be formatted before returning
     360                                        def reltimes = entityClass.executeQuery( "SELECT DISTINCT f FROM " + entity + " s left join s." + fieldName + " f WHERE index(f) = :field", [ "field": field ] );
     361                                        listValues += reltimes.collect { def rt = new RelTime( it ); return rt.toString(); }
     362                                        break;
     363
     364                                case 'StringList':
     365                                case 'ExtendableStringList':
     366                                case 'Term':
     367                                case 'Template':
     368                                case 'Module':
     369                                        // 'Complex' field types: select all possible names for the given field, that have ever been used
     370                                        // (i.e. all ontologies that have ever been used in any field). We have to do it this way, because the HQL
     371                                        // index() function (see simple fields) doesn't work on many-to-many relations
     372                                        listValues += entityClass.executeQuery( "SELECT DISTINCT f.name FROM " + entity + " s left join s." + fieldName + " f WHERE f.name LIKE :term", [ "term": termLike ] );
     373                                default:
     374                                        break;
     375                        }
     376                }
     377               
     378                render listValues as JSON
    276379        }
    277380
     
    293396                        case "Sample":  return new SampleSearch();
    294397                        case "Assay":   return new AssaySearch();
    295                        
     398
    296399                        // This exception will only be thrown if the entitiesToSearchFor contains more entities than
    297400                        // mentioned in this switch structure.
     
    320423                                        def aUC = a.size() > 1 ? a[0].toUpperCase() + a[1..-1] : a;
    321424                                        def bUC = b.size() > 1 ? b[0].toUpperCase() + b[1..-1] : b;
    322                                         aUC <=> bUC 
     425                                        aUC <=> bUC
    323426                                };
    324427                        }
     
    348451                        }
    349452                }
    350                
     453
    351454                return fields;
    352455        }
     
    372475                ArrayList list = [];
    373476                flash.error = "";
    374                
     477
    375478                // Loop through all keys of c and remove the non-numeric ones
    376479                for( c in formCriteria ) {
     
    489592
    490593                s.id = id;
    491                
     594
    492595                if( !s.url )
    493596                        s.url = g.createLink( controller: "advancedQuery", action: "show", id: id, absolute: true );
    494                
     597
    495598                session.queries[ id ] = s;
    496599
     
    587690
    588691                                def paramString = ids.collect { return 'ids=' + it }.join( '&' );
    589                                
     692
    590693                                return [[
    591694                                                module: "gscf",
     
    612715
    613716                                def paramString = ids.collect { return 'ids=' + it }.join( '&' );
    614                                
     717
    615718                                return [[
    616719                                                module: "gscf",
     
    652755                                                def baseUrl = action.url ?: module.url + "/action/" + action.name
    653756                                                def paramString = s.filterResults(selectedTokens).collect { "tokens=" + it.giveUUID() }.join( "&" )
    654                                                
     757
    655758                                                def url = baseUrl;
    656759
     
    659762                                                else
    660763                                                        url += "?"
    661                                                
     764
    662765                                                paramString += "&entity=" + s.entity
    663                                                
     766
    664767                                                actions << [
    665768                                                                        module: moduleName,
  • trunk/grails-app/views/advancedQuery/index.gsp

    r1908 r1962  
    110110                        <li class="newCriterion">
    111111                                <span class="entityfield">
    112                                         <select name="criteria.0.entityfield" id="queryFieldSelect">
     112                                        <select name="criteria.0.entityfield" id="queryFieldSelect" onChange="updateAutocomplete()">
    113113                                                <option value=""></option>
    114114                                                <g:each in="${searchableFields}" var="entity">
     
    129129                                </span>
    130130                                <span class="operator">
    131                                         <select id="operator" name="criteria.0.operator">
     131                                        <select id="operator" name="criteria.0.operator" onChange="updateAutocomplete();">
    132132                                                <option value="equals">Equals</option>
    133133                                                <option value="contains">Contains</option>
  • trunk/web-app/js/advancedQuery.js

    r1908 r1962  
    4646                                }
    4747                        }
     48                       
     49                        updateAutocomplete();
    4850                }
    4951        })
     
    135137        $( "#searchForm .newCriterion .addButton a" ).addClass( "disabled" );
    136138       
     139        // Update value autocomplete
     140        updateAutocomplete();
    137141}
    138142
     
    219223        return a;
    220224}
     225
     226/**
     227 * Update the autocomplete on the value field
     228 */
     229var autoCompleteExists = false;
     230function updateAutocomplete() {
     231        if( $( '#operator' ).val() == "equals" && $( "#queryFieldText" ).val() != "" ) {
     232                // Add an autocomplete to the value textfield. If one exists, remove the old one
     233                if( autoCompleteExists ) {
     234                        $( '#searchForm input#value' ).autocomplete( 'destroy' );
     235                        autoCompleteExists = false;
     236                }
     237               
     238                $( '#searchForm input#value' ).autocomplete({
     239                        source: baseUrl + "/advancedQuery/getFieldValues?entityfield=" + $( '#queryField' ).val()
     240                });
     241               
     242                autoCompleteExists = true;
     243        } else {
     244                // Remove autocomplete from the value textfield
     245                $( '#searchForm input#value' ).autocomplete( 'destroy' );
     246                autoCompleteExists = false;
     247        }
     248}
Note: See TracChangeset for help on using the changeset viewer.