Changeset 1526
- Timestamp:
- Feb 16, 2011, 11:12:14 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/query/AdvancedQueryController.groovy
r1524 r1526 15 15 def authenticationService 16 16 17 def entitiesToSearchFor = [ 'Study': 'Studies', 'Sample': 'Samples' ]17 def entitiesToSearchFor = [ 'Study': 'Studies', 'Sample': 'Samples', 'Assay': 'Assays'] 18 18 19 19 /** … … 198 198 199 199 if( queryIds.size() == 0 ) { 200 flash.error = "Incorrect search ID given to s how"201 redirect( action: " index" );200 flash.error = "Incorrect search ID given to search in" 201 redirect( action: "list" ); 202 202 return 203 203 } … … 287 287 case "Study": return "studyresults"; break; 288 288 case "Sample": return "sampleresults"; break; 289 case "Assay": return "assayresults"; break; 289 290 default: return "results"; break; 290 291 } … … 298 299 case "Study": return new StudySearch(); 299 300 case "Sample": return new SampleSearch(); 300 301 case "Assay": return new AssaySearch(); 302 301 303 // This exception will only be thrown if the entitiesToSearchFor contains more entities than 302 304 // mentioned in this switch structure. … … 375 377 // Loop through all keys of c and remove the non-numeric ones 376 378 for( c in formCriteria ) { 377 if( c.key ==~ /[0-9]+/ ) {379 if( c.key ==~ /[0-9]+/ && c.value.entityfield ) { 378 380 def formCriterion = c.value; 379 381 … … 478 480 479 481 // First check whether a search with the same criteria is already present 480 def previousSearch = retrieveSearch ByCriteria( s.getCriteria(), s.searchMode);482 def previousSearch = retrieveSearch( s ); 481 483 482 484 def id … … 496 498 /** 497 499 * Retrieves a search from session with the same criteria as given 498 * @param criteria List of criteriato search for500 * @param s Search that is used as an example to search for 499 501 * @return Search that has this criteria, or null if no such search is found. 500 502 */ 501 protected Search retrieveSearch ByCriteria( List criteria, SearchMode searchMode = SearchMode.and) {503 protected Search retrieveSearch( Search s ) { 502 504 if( !session.queries ) 503 505 return null 504 506 505 if( !criteria )506 return null507 508 507 for( query in session.queries ) { 509 def key = query.key;510 508 def value = query.value; 511 509 512 if( value.searchMode == searchMode && value.criteria && value.criteria.containsAll( criteria ) && criteria.containsAll( value.criteria ) ) { 513 return value; 514 } 510 if( s.equals( value ) ) 511 return value 515 512 } 516 513 -
trunk/grails-app/domain/dbnp/studycapturing/Assay.groovy
r1457 r1526 74 74 75 75 /** 76 * Basic equals method to check whether objects are equals, by comparing the ids 77 * @param o Object to compare with 78 * @return True iff the id of the given Study is equal to the id of this Study 79 */ 80 public boolean equals( Object o ) { 81 if( o == null ) 82 return false; 83 84 if( !( o instanceof Assay ) ) 85 return false 86 87 Assay s = (Assay) o; 88 89 return this.id == s.id 90 } 91 92 /** 76 93 * Returns the UUID of this sample and generates one if needed 77 94 */ -
trunk/grails-app/views/advancedQuery/_criteria.gsp
r1512 r1526 1 1 <%@ page import="dbnp.query.*" %> 2 <ul id="criteria"> 3 <g:each in="${criteria}" var="criterion" status="j"> 4 <li> 5 <span class="entityfield">${criterion.entityField().toLowerCase()}</span> 6 <span class="operator">${criterion.operator}</span> 7 <span class="value"> 8 <g:if test="${criterion.value != null && criterion.value instanceof Search}"> 9 <g:link action="show" id="${criterion.value.id}">${criterion.value}</g:link> 2 <g:if test="${criteria}"> 3 with 4 <ul id="criteria"> 5 <g:each in="${criteria}" var="criterion" status="j"> 6 <li> 7 <span class="entityfield">${criterion.entityField().toLowerCase()}</span> 8 <span class="operator">${criterion.operator}</span> 9 <span class="value"> 10 <g:if test="${criterion.value != null && criterion.value instanceof Search}"> 11 <g:link action="show" id="${criterion.value.id}">${criterion.value}</g:link> 12 </g:if> 13 <g:else> 14 ${criterion.value} 15 </g:else> 16 </span> 17 <g:if test="${j < criteria.size() -1}"> 18 <g:if test="${search.searchMode == SearchMode.and}">and</g:if> 19 <g:if test="${search.searchMode == SearchMode.or}">or</g:if> 10 20 </g:if> 11 <g:else> 12 ${criterion.value} 13 </g:else> 14 </span> 15 <g:if test="${j < criteria.size() -1}"> 16 <g:if test="${search.searchMode == SearchMode.and}">and</g:if> 17 <g:if test="${search.searchMode == SearchMode.or}">or</g:if> 18 </g:if> 19 </li> 20 </g:each> 21 </ul> 21 </li> 22 </g:each> 23 </ul> 24 </g:if> 25 <g:else> 26 without criteria. 27 </g:else> -
trunk/grails-app/views/advancedQuery/index.gsp
r1512 r1526 30 30 showCriterium("${criterion.entityField().encodeAsJavaScript()}", "${criterion.value.toString().encodeAsJavaScript()}", "${criterion.operator.toString().encodeAsJavaScript()}"); 31 31 </g:each> 32 showHideNoCriteriaItem();33 32 }); 34 33 </g:if> … … 51 50 52 51 <div id="searchForm"> 53 <form id="input_criteria">54 <h2>Add criterium</h2>55 <p class="explanation">56 N.B. Comparing numerical values is done without taking into57 account the units. E.g. a weight of 1 kg equals 1 grams.58 </p>59 <label for="field">Field</label>60 <select name="field" id="queryFieldSelect">61 <option value=""></option>62 <g:each in="${searchableFields}" var="entity">63 <optgroup label="${entity.key}">64 <g:each in="${entity.value}" var="field">65 <option value="${entity.key}.${field}">66 ${field[0].toUpperCase() + field[1..-1]}67 </option>68 </g:each>69 </optgroup>70 </g:each>71 </select>72 73 <label for="value">Comparison</label>74 <select name="operator">75 <option value="equals">Equals</option>76 <option value="contains">Contains</option>77 <option value=">=">Greater than or equals</option>78 <option value=">">Greater than</option>79 <option value="<">Lower than</option>80 <option value="<=">Lower than or equals</option>81 </select>82 83 <label for="value">Value</label>84 <input class='text' type="text" name="value" />85 86 <input class="button" type="button" onClick="addCriterium();" value="Add" />87 </form>88 52 <g:form action="search" method="get"> 89 <label for="entity">Search for</label><g:select from="${entitiesToSearchFor}" optionKey="key" optionValue="value" name="entity" /><br /> 90 <label for="entity">Searchtype</label><g:select from="${searchModes}" name="operator" /><br /> 91 <label for="criteria">Criteria</label> 53 54 <h3><span class="nummer">1</span>Select criteria</h3> 55 <p class="explanation"> 56 N.B. Comparing numerical values is done without taking into 57 account the units. E.g. a weight of 1 kg equals 1 grams. 58 </p> 92 59 <ul id="criteria"> 93 <li class="emptyList">No criteria added. Use the form on the right to specify criteria to search on.</li> 60 <li class="titlerow"> 61 <span class="entityfield"> 62 Field 63 </span> 64 <span class="operator"> 65 Operator 66 </span> 67 <span class="value"> 68 Value 69 </span> 70 </li> 71 <li class="newCriterion"> 72 <span class="entityfield"> 73 <select name="criteria.0.entityfield" id="queryFieldSelect"> 74 <option value=""></option> 75 <g:each in="${searchableFields}" var="entity"> 76 <optgroup label="${entity.key}"> 77 <g:each in="${entity.value}" var="field"> 78 <option value="${entity.key}.${field}"> 79 ${field[0].toUpperCase() + field[1..-1]} 80 </option> 81 </g:each> 82 </optgroup> 83 </g:each> 84 </select> 85 </span> 86 <span class="operator"> 87 <select id="operator" name="criteria.0.operator"> 88 <option value="equals">Equals</option> 89 <option value="contains">Contains</option> 90 <option value=">=">>=</option> 91 <option value=">">></option> 92 <option value="<"><</option> 93 <option value="<="><=</option> 94 </select> 95 </span> 96 <span class="value"> 97 <input class='text' type="text" id="value" name="criteria.0.value" /> 98 </span> 99 <span class="addButton"> 100 <a href="#" onClick="addCriterion(); return false;"> 101 <img src="${fam.icon( name: 'add' )}" border="0"> 102 </a> 103 </span> 104 </li> 94 105 </ul> 95 106 96 <input type="submit" value="Run query" class="submitcriteria" disabled="disabled" /> 107 <div id="searchMode"> 108 <h3><span class="nummer">1b</span>Search mode</h3> 109 <p> 110 Choose how to combine the given criteria:<br /> 111 <g:select from="${searchModes}" name="operator" /> 112 </p> 113 </div> 114 115 <h3><span class="nummer">2</span>Output type</h3> 116 <p> 117 Choose the type of output:<br /> 118 <g:select from="${entitiesToSearchFor}" optionKey="key" optionValue="value" name="entity" /> 119 </p> 120 121 <h3><span class="nummer">3</span>Run query</h3> 122 <p> 123 <input type="submit" value="Run query" class="submitcriteria" /> 124 </p> 97 125 </g:form> 98 126 -
trunk/grails-app/views/advancedQuery/list.gsp
r1524 r1526 56 56 <td>${search.entity}</td> 57 57 <td> 58 <g: each in="${search.getCriteria()}" var="criterion" status="j">59 <g:if test="${j > 0}">, </g:if>58 <g:set var="criteria" value="${search.getCriteria()}" /> 59 <g:each in="${criteria}" var="criterion" status="j"> 60 60 <span class="entityfield">${criterion.entityField()}</span> 61 61 <span class="operator">${criterion.operator}</span> … … 68 68 </g:else> 69 69 </span> 70 <g:if test="${j < criteria.size() -1}"> 71 <g:if test="${search.searchMode == SearchMode.and}">and</g:if> 72 <g:if test="${search.searchMode == SearchMode.or}">or</g:if> 73 </g:if> 70 74 </g:each> 71 75 </td> -
trunk/grails-app/views/advancedQuery/results.gsp
r1524 r1526 12 12 13 13 <div class="searchoptions"> 14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">result</g:if><g:else>results</g:else> found with14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">result</g:if><g:else>results</g:else> found 15 15 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 16 16 </div> … … 49 49 if( fieldValue ) { 50 50 if( fieldValue instanceof Collection ) { 51 fieldValue = fieldValue.collect { it.toString() }.findAll { it }. join( ', ' );51 fieldValue = fieldValue.collect { it.toString() }.findAll { it }.unique().join( ', ' ); 52 52 } else { 53 53 fieldValue = fieldValue.toString(); -
trunk/grails-app/views/advancedQuery/sampleresults.gsp
r1524 r1526 12 12 13 13 <div class="searchoptions"> 14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">sample</g:if><g:else>samples</g:else> found with14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">sample</g:if><g:else>samples</g:else> found 15 15 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 16 16 </div> … … 50 50 if( fieldValue ) { 51 51 if( fieldValue instanceof Collection ) { 52 fieldValue = fieldValue.collect { it.toString() }.findAll { it }. join( ', ' );52 fieldValue = fieldValue.collect { it.toString() }.findAll { it }.unique().join( ', ' ); 53 53 } else { 54 54 fieldValue = fieldValue.toString(); -
trunk/grails-app/views/advancedQuery/studyresults.gsp
r1524 r1526 12 12 13 13 <div class="searchoptions"> 14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">study</g:if><g:else>studies</g:else> found with14 ${search.getNumResults()} <g:if test="${search.getNumResults() == 1}">study</g:if><g:else>studies</g:else> found 15 15 <g:render template="criteria" model="[criteria: search.getCriteria()]" /> 16 16 </div> … … 86 86 if( fieldValue ) { 87 87 if( fieldValue instanceof Collection ) { 88 fieldValue = fieldValue.collect { it.toString() }.findAll { it }. join( ', ' );88 fieldValue = fieldValue.collect { it.toString() }.findAll { it }.unique().join( ', ' ); 89 89 } else { 90 90 fieldValue = fieldValue.toString(); -
trunk/grails-app/views/study/show_assays.gsp
r1490 r1526 33 33 <td> 34 34 <g:if test="${assay.module.openInFrame == null || assay.module.openInFrame == Boolean.TRUE}"> 35 <jumpbar:link frameSource="${assay.module.url}/assay/showByToken/${assay.giveUUID()}" pageTitle=" Metabolomics Module">35 <jumpbar:link frameSource="${assay.module.url}/assay/showByToken/${assay.giveUUID()}" pageTitle="${assay.module.name}"> 36 36 view 37 37 </jumpbar:link> -
trunk/src/groovy/dbnp/query/SampleSearch.groovy
r1524 r1526 71 71 } 72 72 73 // We expect the s amplecriteria to be the most discriminative, and discard74 // the most samples. (e.g. by searching on s ample title of sampletype). For73 // We expect the study criteria to be the most discriminative, and discard 74 // the most samples. (e.g. by searching on study title or study type). For 75 75 // that reason we first look through the list of studies. However, when the 76 // user didn't enter any s amplecriteria, this will be an extra step, but doesn't76 // user didn't enter any study criteria, this will be an extra step, but doesn't 77 77 // cost much time to process. 78 78 def samples = [] … … 152 152 @Override 153 153 void executeOr() { 154 // We expect the sample criteria to be the most discriminative, and discard155 // the most samples. (e.g. by searching on sample title of sample type). For156 // that reason we first look through the list of studies. However, when the157 // user didn't enter any sample criteria, this will be an extra step, but doesn't158 // cost much time to process.159 def samples = []160 154 def allSamples = Sample.list().findAll { it.parent?.canRead( this.user ) }.toList(); 161 162 // If no criteria are found, return all samples 163 if( !criteria || criteria.size() == 0 ) { 164 results = allSamples 165 return; 166 } 167 168 samples = ( samples + filterOnStudyCriteria( allSamples - samples ) ).unique(); 169 samples = ( samples + filterOnSubjectCriteria( allSamples - samples ) ).unique(); 170 samples = ( samples + filterOnSampleCriteria( allSamples - samples ) ).unique(); 171 samples = ( samples + filterOnEventCriteria( allSamples - samples ) ).unique(); 172 samples = ( samples + filterOnSamplingEventCriteria( allSamples - samples ) ).unique(); 173 samples = ( samples + filterOnAssayCriteria( allSamples - samples ) ).unique(); 174 175 samples = ( samples + filterOnModuleCriteria( allSamples - samples ) ).unique(); 176 177 // Save matches 178 results = samples; 155 executeOr( allSamples ); 179 156 } 180 157 … … 203 180 return null 204 181 205 return criterion.getFieldValue( sample.parentEventGroup.events.toList() );182 return sample.parentEventGroup.events?.collect { criterion.getFieldValue( it ) }; 206 183 } 207 184 case "SamplingEvent": … … 258 235 }); 259 236 237 println "Matching assays: " + assays 238 260 239 // If no assays match these criteria, then no samples will match either 261 240 if( assays.size() == 0 ) … … 268 247 269 248 def studyAssays = assays.findAll { it.parent.equals( sample.parent ); } 270 249 250 println "Assays for " + sample + " (based on study): " + studyAssays 251 271 252 // See if this sample is present in any of the matching assays. If so, 272 253 // this sample matches the criteria … … 274 255 if( assay.samples?.contains( sample ) ) 275 256 return true; 257 258 println "Assay " + assay + " with samples " + assay.samples + " doesn't contain " + sample; 276 259 } 277 260 -
trunk/src/groovy/dbnp/query/Search.groovy
r1524 r1526 71 71 72 72 /** 73 * Returns a list of Criteria74 */75 public List getCriteria() { return criteria; }76 77 /**78 * Sets a new list of criteria79 * @param c List with criteria objects80 */81 public void setCriteria( List c ) { criteria = c; }82 83 /**84 * Adds a criterion to this query85 * @param c Criterion86 */87 public void addCriterion( Criterion c ) {88 if( criteria )89 criteria << c;90 else91 criteria = [c];92 }93 94 /**95 * Retrieves the results found using this query. The result is empty is96 * the query has not been executed yet.97 */98 public List getResults() { return results; }99 100 /**101 * Returns the results found using this query, filtered by a list of ids.102 * @param selectedIds List with ids of the entities you want to return.103 * @return A list with only those results for which the id is in the selectedIds104 */105 public List filterResults( List selectedIds ) {106 if( !selectedIds || !results )107 return results108 109 return results.findAll {110 selectedIds.contains( it.id )111 }112 }113 114 /**115 * Returns a list of fields for the results of this query. The fields returned are those116 * fields that the query searched for.117 */118 public Map getResultFields() { return resultFields; }119 120 /**121 73 * Constructor of this search object. Sets the user field to the 122 74 * currently logged in user … … 179 131 * subclasses searching for a specific entity 180 132 */ 181 p ublicvoid executeAnd() {133 protected void executeAnd() { 182 134 183 135 } … … 187 139 * subclasses searching for a specific entity 188 140 */ 189 public void executeOr() { 190 191 } 192 141 protected void executeOr() { 142 143 } 144 145 /** 146 * Default implementation of an inclusive (AND) search. Can be called by subclasses in order 147 * to simplify searches. 148 * 149 * Filters the list of objects on study, subject, sample, event, samplingevent and assaycriteria, 150 * based on the closures defined in valueCallback. Afterwards, the objects are filtered on module 151 * criteria 152 * 153 * @param objects List of objects to search in 154 */ 155 protected void executeAnd( List objects ) { 156 // If no criteria are found, return all studies 157 if( !criteria || criteria.size() == 0 ) { 158 results = objects; 159 return; 160 } 161 162 // Perform filters 163 objects = filterOnStudyCriteria( objects ); 164 objects = filterOnSubjectCriteria( objects ); 165 objects = filterOnSampleCriteria( objects ); 166 objects = filterOnEventCriteria( objects ); 167 objects = filterOnSamplingEventCriteria( objects ); 168 objects = filterOnAssayCriteria( objects ); 169 170 objects = filterOnModuleCriteria( objects ); 171 172 // Save matches 173 results = objects; 174 } 175 176 /** 177 * Default implementation of an exclusive (OR) search. Can be called by subclasses in order 178 * to simplify searches. 179 * 180 * Filters the list of objects on study, subject, sample, event, samplingevent and assaycriteria, 181 * based on the closures defined in valueCallback. Afterwards, the objects are filtered on module 182 * criteria 183 * 184 * @param allObjects List of objects to search in 185 */ 186 protected void executeOr( List allObjects ) { 187 // If no criteria are found, return all studies 188 if( !criteria || criteria.size() == 0 ) { 189 results = allObjects; 190 return; 191 } 192 193 // Perform filters on those objects not yet found by other criteria 194 def objects = [] 195 objects = ( objects + filterOnStudyCriteria( allObjects - objects ) ).unique(); 196 objects = ( objects + filterOnSubjectCriteria( allObjects - objects ) ).unique(); 197 objects = ( objects + filterOnSampleCriteria( allObjects - objects ) ).unique(); 198 objects = ( objects + filterOnEventCriteria( allObjects - objects ) ).unique(); 199 objects = ( objects + filterOnSamplingEventCriteria( allObjects - objects ) ).unique(); 200 objects = ( objects + filterOnAssayCriteria( allObjects - objects ) ).unique(); 201 202 // All objects (including the ones already found by another criterion) are sent to 203 // be filtered on module criteria, in order to have the module give data about all 204 // objects (for showing purposes later on) 205 objects = ( objects + filterOnModuleCriteria( allObjects ) ).unique(); 206 207 // Save matches 208 results = objects; 209 } 210 211 193 212 /************************************************************************ 194 213 * 195 * These methods are used in querying and shouldbe overridden by subclasses214 * These methods are used in querying and can be overridden by subclasses 196 215 * in order to provide custom searching 197 216 * 198 * /217 ************************************************************************/ 199 218 200 219 /** … … 270 289 return criteria?.findAll { it.entity == entity } 271 290 } 272 273 /** 274 * Filters a list with entities, based on the given criteria and a closure to check whether a criterion is matched 275 * 276 * @param entities Original list with entities to check for these criteria 277 * @param criteria List with criteria to match on 278 * @param check Closure to see whether a specific entity matches a criterion. Gets two arguments: 279 * element The element to check 280 * criterion The criterion to check on. 281 * Returns true if the criterion holds, false otherwise 282 * @return The filtered list of entities 283 */ 284 protected List filterEntityList( List entities, List<Criterion> criteria, Closure check ) { 285 if( !entities || !criteria || criteria.size() == 0 ) { 286 if( searchMode == SearchMode.and ) 287 return entities; 288 else if( searchMode == SearchMode.or ) 289 return [] 290 } 291 292 return entities.findAll { entity -> 293 if( searchMode == SearchMode.and ) { 294 for( criterion in criteria ) { 295 if( !check( entity, criterion ) ) { 296 return false; 297 } 298 } 299 return true; 300 } else if( searchMode == SearchMode.or ) { 301 for( criterion in criteria ) { 302 if( check( entity, criterion ) ) { 303 return true; 304 } 305 } 306 return false; 307 } 308 } 309 } 310 291 292 311 293 /** 312 294 * Prepares a value from a template entity for comparison, by giving it a correct type 313 295 * 314 * @param value Value of the field 296 * @param value Value of the field 315 297 * @param type TemplateFieldType Type of the specific field 316 298 * @return The value of the field in the correct entity … … 374 356 } 375 357 358 /***************************************************** 359 * 360 * Methods for filtering lists based on specific (GSCF) criteria 361 * 362 *****************************************************/ 363 364 365 /** 366 * Filters a list with entities, based on the given criteria and a closure to check whether a criterion is matched 367 * 368 * @param entities Original list with entities to check for these criteria 369 * @param criteria List with criteria to match on 370 * @param check Closure to see whether a specific entity matches a criterion. Gets two arguments: 371 * element The element to check 372 * criterion The criterion to check on. 373 * Returns true if the criterion holds, false otherwise 374 * @return The filtered list of entities 375 */ 376 protected List filterEntityList( List entities, List<Criterion> criteria, Closure check ) { 377 if( !entities || !criteria || criteria.size() == 0 ) { 378 if( searchMode == SearchMode.and ) 379 return entities; 380 else if( searchMode == SearchMode.or ) 381 return [] 382 } 383 384 return entities.findAll { entity -> 385 if( searchMode == SearchMode.and ) { 386 for( criterion in criteria ) { 387 if( !check( entity, criterion ) ) { 388 return false; 389 } 390 } 391 return true; 392 } else if( searchMode == SearchMode.or ) { 393 for( criterion in criteria ) { 394 if( check( entity, criterion ) ) { 395 return true; 396 } 397 } 398 return false; 399 } 400 } 401 } 402 376 403 /** 377 404 * Filters the given list of studies on the study criteria … … 460 487 return filterOnTemplateEntityCriteria(studies, entity, valueCallback( entity ) ) 461 488 } 489 490 /******************************************************************** 491 * 492 * Methods for filtering object lists on module criteria 493 * 494 ********************************************************************/ 462 495 463 496 /** … … 690 723 } 691 724 725 726 /************************************************************************ 727 * 728 * Getters and setters 729 * 730 ************************************************************************/ 731 732 /** 733 * Returns a list of Criteria 734 */ 735 public List getCriteria() { return criteria; } 736 737 /** 738 * Sets a new list of criteria 739 * @param c List with criteria objects 740 */ 741 public void setCriteria( List c ) { criteria = c; } 742 743 /** 744 * Adds a criterion to this query 745 * @param c Criterion 746 */ 747 public void addCriterion( Criterion c ) { 748 if( criteria ) 749 criteria << c; 750 else 751 criteria = [c]; 752 } 753 754 /** 755 * Retrieves the results found using this query. The result is empty is 756 * the query has not been executed yet. 757 */ 758 public List getResults() { return results; } 759 760 /** 761 * Returns the results found using this query, filtered by a list of ids. 762 * @param selectedIds List with ids of the entities you want to return. 763 * @return A list with only those results for which the id is in the selectedIds 764 */ 765 public List filterResults( List selectedIds ) { 766 if( !selectedIds || !results ) 767 return results 768 769 return results.findAll { 770 selectedIds.contains( it.id ) 771 } 772 } 773 774 /** 775 * Returns a list of fields for the results of this query. The fields returned are those 776 * fields that the query searched for. 777 */ 778 public Map getResultFields() { return resultFields; } 779 692 780 public String toString() { 693 781 return ( this.entity ? this.entity + " search" : "Search" ) + " " + this.id 694 782 } 783 784 public boolean equals( Object o ) { 785 if( o == null ) 786 return false 787 788 if( !( o instanceof Search ) ) 789 return false 790 791 Search s = (Search) o; 792 793 return ( searchMode == s.searchMode && 794 entity == s.entity && 795 criteria.size() == s.criteria.size() && 796 s.criteria.containsAll( criteria ) && 797 criteria.containsAll( s.criteria ) ); 798 } 695 799 } -
trunk/src/groovy/dbnp/query/StudySearch.groovy
r1524 r1526 65 65 */ 66 66 @Override 67 void executeAnd() {67 protected void executeAnd() { 68 68 def studies = Study.list().findAll { it.canRead( this.user ) }; 69 69 70 // If no criteria are found, return all studies 71 if( !criteria || criteria.size() == 0 ) { 72 results = studies; 73 return; 74 } 75 76 // Perform filters 77 studies = filterOnStudyCriteria( studies ); 78 studies = filterOnSubjectCriteria( studies ); 79 studies = filterOnSampleCriteria( studies ); 80 studies = filterOnEventCriteria( studies ); 81 studies = filterOnSamplingEventCriteria( studies ); 82 studies = filterOnAssayCriteria( studies ); 83 84 studies = filterOnModuleCriteria( studies ); 85 86 // Save matches 87 results = studies; 70 executeAnd( studies ); 88 71 } 89 72 … … 121 104 */ 122 105 @Override 123 void executeOr() {106 protected void executeOr() { 124 107 def allStudies = Study.list().findAll { it.canRead( this.user ) }; 125 126 // If no criteria are found, return all studies 127 if( !criteria || criteria.size() == 0 ) { 128 results = allStudies; 129 return; 130 } 131 132 // Perform filters 133 def studies = [] 134 studies = ( studies + filterOnStudyCriteria( allStudies - studies ) ).unique(); 135 studies = ( studies + filterOnSubjectCriteria( allStudies - studies ) ).unique(); 136 studies = ( studies + filterOnSampleCriteria( allStudies - studies ) ).unique(); 137 studies = ( studies + filterOnEventCriteria( allStudies - studies ) ).unique(); 138 studies = ( studies + filterOnSamplingEventCriteria( allStudies - studies ) ).unique(); 139 studies = ( studies + filterOnAssayCriteria( allStudies - studies ) ).unique(); 140 141 studies = ( studies + filterOnModuleCriteria( allStudies - studies ) ).unique(); 142 143 // Save matches 144 results = studies; 108 executeOr( allStudies ); 145 109 } 146 110 -
trunk/web-app/css/advancedQuery.css
r1524 r1526 1 1 label { display: inline-block; zoom: 1; *display: inline; width: 110px; margin-top: 10px; } 2 2 3 #searchForm { position: relative; border: 1px solid #666666; padding: 5px 10px; margin: 10px 0; } 3 #searchForm { position: relative; margin: 10px 0; font-size: 11px; } 4 #searchForm h3 { font-size: 13px; } 5 #searchForm h3 .nummer { display: inline-block; zoom: 1; *display: inline; width: 25px; } 4 6 5 #searchForm ul#criteria { margin-left: 110px; padding-left: 0px; margin-top: -19px; list-style-type: none; } 6 #searchForm ul#criteria li { margin: 2px 0; padding-left: 0; } 7 #searchForm p { margin-left: 25px; } 8 9 #searchForm ul#criteria { margin-left: 25px; padding-left: 0px; list-style-type: none; } 10 #searchForm ul#criteria li { margin: 2px 0; padding: 2px 0; } 7 11 #searchForm ul#criteria li span, 8 12 #searchForm ul#criteria li a { display: inline-block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-right: 5px; } 9 #searchForm ul#criteria li .entityfield { width: 180px; }13 #searchForm ul#criteria li .entityfield { width: 200px; } 10 14 #searchForm ul#criteria li .operator { width: 100px; } 11 15 #searchForm ul#criteria li .value { width: 240px; } 16 #searchForm ul#criteria li .addButton { margin: 4px 0; } 17 #searchForm ul#criteria li input, #searchForm ul#criteria li select { font-size: 11px; } 12 18 13 #searchForm ul#criteria li.emptyList { color: #666; } 14 #searchForm ul#criteria li.emptyList:hover { cursor: default; } 19 #searchForm ul#criteria li.titlerow { font-weight: bold; border-bottom: 1px solid #aaa; } 15 20 16 #searchForm ul#criteria li:hover { cursor: pointer; } 17 #searchForm ul#criteria li:hover span { text-decoration: line-through; } 18 19 #input_criteria { display: block; float: right; width: 260px; border-left: 1px solid #666; padding: 10px; position: relative; height: 100%; } 20 #input_criteria h2 { margin-top: 2px; margin-bottom: 8px; font-weight: bold; } 21 #input_criteria label { width: 80px; margin-top: 8px; } 22 #input_criteria input.text, #input_criteria select { width: 165px; } 23 #input_criteria input.button { margin-top: 8px; } 24 #input_criteria .explanation { font-size: 10px; } 21 #searchMode { display: none; } 25 22 26 23 .ui-menu-item .entity { color: #666; font-style: italic; } -
trunk/web-app/js/advancedQuery.js
r1482 r1526 8 8 // By replacing it with javascript, users without javascript will still be able to use the select 9 9 $( '#queryFieldSelect' ).after( $( '<input type="text" class="text" id="queryFieldText">' )); 10 $( '#queryFieldText' ).after( $( '<input type="hidden" name=" field" id="queryField"></span>' ));10 $( '#queryFieldText' ).after( $( '<input type="hidden" name="criteria.0.entityfield" id="queryField"></span>' )); 11 11 $( '#queryFieldSelect' ).remove(); 12 12 … … 40 40 41 41 // Is used to keep track of a unique ID for all criteria. 42 var criteriumId = 0; 42 // ID = 0 is used for the input fields, in order to have them sent as well 43 // when the user clicks 'run query' 44 var criteriumId = 1; 43 45 44 46 /** 45 47 * Adds a criteria to the list of search criteria 46 48 */ 47 function addCriteri um() {48 var field_descriptor = $( '# input_criteria [name=field]' ).val();49 var value = $( '# input_criteria input[name=value]' ).val();50 var operator = $( '# input_criteria select[name=operator]' ).val();49 function addCriterion() { 50 var field_descriptor = $( '#searchForm #queryField' ).val(); 51 var value = $( '#searchForm input#value' ).val(); 52 var operator = $( '#searchForm select#operator' ).val(); 51 53 52 54 // Show the title and a remove button 53 55 showCriterium(field_descriptor, value, operator); 54 showHideNoCriteriaItem();56 toggleSearchMode(); 55 57 56 58 // Clear the input form 57 $( '#input_criteria #queryFieldText' ).val( '' ); 58 $( '#input_criteria [name=field]' ).val( '' ); 59 $( '#input_criteria select[name=operator]' ).val( 'equals' ); 60 $( '#input_criteria input[name=value]' ).val( '' ); 61 } 62 63 function showHideNoCriteriaItem() { 64 remainingCriteria = $( '#criteria' ).children().length - 1; // -1 because one element is the 'empty' item 65 66 if( remainingCriteria == 0 ) { 67 // Show the 'none box' 68 $('#criteria .emptyList').show(); 69 $('.submitcriteria' ).attr( 'disabled', 'disabled' ); 70 } else { 71 // Hide the 'none box' 72 $('#criteria .emptyList').hide(); 73 $('.submitcriteria' ).attr( 'disabled', '' ); 74 } 59 $( '#searchForm #queryFieldText' ).val( '' ); 60 $( '#searchForm #queryField' ).val( '' ); 61 $( '#searchForm select#operator' ).val( 'equals' ); 62 $( '#searchForm input#value' ).val( '' ); 75 63 } 76 64 … … 80 68 function removeCriterium(element) { 81 69 element.remove(); 82 showHideNoCriteriaItem();70 toggleSearchMode(); 83 71 } 72 73 function toggleSearchMode() { 74 if( $('#criteria' ).children( 'li' ) - 2 == 0 ) { 75 $( '#searchMode' ).hide(); 76 } else { 77 $( '#searchMode' ).show(); 78 } 79 } 80 84 81 85 82 /** … … 98 95 valueSpan = createCriteriumElement( 'value', value ); 99 96 97 var input = $( '<a href="#" onClick="return false;"><img src="../plugins/famfamfam-1.0.1/images/icons/delete.png" border="0"></a>' ); 98 input.bind( 'click', function() { 99 if( confirm( "Are you sure you want to remove this criterium?" ) ) { 100 removeCriterium( $(this).closest( 'li' ) ); 101 return false; 102 } 103 }); 104 var span = $( '<span></span>' ); 105 span.append( "\n" ).append( input ); 106 100 107 // Increase the criteriumID to ensure a unique number every time 101 108 criteriumId++; … … 103 110 // Append them to a list item 104 111 var li = $( '<li></li>' ); 105 li.append( fieldSpan ).append( operatorSpan ).append( valueSpan );112 li.append( fieldSpan ).append( "\n" ).append( operatorSpan ).append( "\n" ).append( valueSpan ).append( "\n" ).append( span ); 106 113 107 li.bind( 'click', function() {108 if( confirm( "Are you sure you want to remove this criterium?" ) ) {109 removeCriterium( $(this) );110 return false;111 }112 });113 114 114 $('#criteria ').append(li);115 $('#criteria .newCriterion').before(li); 115 116 } 116 117
Note: See TracChangeset
for help on using the changeset viewer.