source: trunk/grails-app/views/study/show.gsp @ 899

Last change on this file since 899 was 899, checked in by keesvb, 10 years ago

temporarily insert /assay/assayToken convention in study assays view, as long as REST services are not properly implemented on SAM and NMCDSP side (and as long as the IFRAME solution to have the GSCF navigation layer over the view is not yet implemented)

  • Property svn:keywords set to Date Author Rev
File size: 34.2 KB
Line 
1
2<%@ page import="dbnp.studycapturing.Study" %>
3<%@ page import="dbnp.studycapturing.EventGroup" %>
4<%@ page import="dbnp.studycapturing.RelTime" %>
5<html>
6  <head>
7    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
8    <meta name="layout" content="main" />
9    <g:set var="entityName" value="${message(code: 'study.label', default: 'Study')}" />
10    <title><g:message code="default.show.label" args="[entityName]" /></title>
11    <script type="text/javascript">
12      // Flag whether the timelines have been loaded
13      var timelineloaded = false;
14     
15      // Number of timelines that should be loaded
16      var numTimelines = ${studyList?.size()};
17     
18      // This method is called on the event body.onLoad
19      $(function() {
20              $("#tabs").tabs({
21                show: function(event, ui) {
22                  // If the events tab is shown, the timeline should be redrawn
23                  if( ui.tab.hash == '#events-timeline' && !timelineloaded ) {
24                    loadTimeline( 'eventstimeline', 'eventtitles', 0 );
25                    timelineloaded = true;
26                  }
27                }
28              });
29      });
30    </script>
31    <link rel="stylesheet" type="text/css" href="${resource(dir: 'css', file: 'studies.css')}"/>
32
33    <!-- Include scripts for the SIMILE timeline. See http://simile-widgets.org/wiki/ -->
34    <script type="text/javascript">
35      Timeline_ajax_url="${resource(dir: 'js', file: 'timeline-simile/timeline_ajax/simile-ajax-api.js')}";
36      Timeline_urlPrefix='${resource(dir: 'js', file: 'timeline-simile/')}';
37      Timeline_parameters='bundle=true';
38    </script>
39    <script src="${resource(dir: 'js', file: 'timeline-simile/timeline-api.js')}" type="text/javascript"></script>
40    <script src="${resource(dir: 'js', file: 'timeline-simile/custom-timeline.js')}" type="text/javascript"></script>
41    <script src="${resource(dir: 'js', file: 'jquery-callback-1.2.js')}" type="text/javascript"></script>
42
43    <!-- Create the JSON objects for the timeline with events -->
44    <script type="text/javascript">
45         /*
46          * Creates timeline bands for displaying different timelines
47          *
48          * @returns array with BandInfo objects, as described on http://simile-widgets.org/wiki/Timeline_GettingStarted
49          */
50        function createTimelineBands( timelineNr ) {
51          var bandInfos = [];
52          var eventSources = [];
53          var overviewEventSource = new Timeline.DefaultEventSource();
54
55          // The way the timeline should look. See http://www.linuxjournal.com/article/9301
56          var theme = Timeline.ClassicTheme.create();
57          var emptyEtherPainter = new Timeline.EmptyEtherPainter( { theme: theme } )
58
59          // Now create the bands for all studies, and add them to one timeline
60          // Multiple timeline on one page do not seem to work
61          <g:set var="bandNr" value="${0}" />
62          <g:each in="${studyList}" var="study" status="timelineNr">
63              // The date that the timeline should start on
64              var dateStr = "<g:formatDate format="yyyy/MM/dd HH:mm:ss" date="${study.startDate}"/>";
65              firstDate = new Date ( dateStr );
66
67              //------------- Eventgroup overview ---------------
68
69              <g:set var="datesBandNr" value="${bandNr}" />
70              // Add an empty band to show the dates
71              bandInfos[${bandNr}] =
72                     Timeline.createBandInfo({
73                        width:          40,
74                        intervalUnit:   Timeline.DateTime.DAY,
75                        intervalPixels: 40,
76                        showEventText:  false,
77                        date:           firstDate,
78                        timeZone:       +1,
79                        layout:         'original',
80                        theme:          theme
81                     });
82              bandTitleInfo[ timelineNr ][ ${bandNr} ] = {
83                title: "${study.title}",
84                subjects: "",
85                className: "studytitle"
86              };
87
88              <g:set var="bandNr" value="${bandNr+1}" />
89              <%
90                def sortedEventGroups = study.eventGroups.sort( { a, b ->
91                    return a.name <=> b.name;
92                }  as Comparator );
93
94                def orphans = study.getOrphanEvents();
95                if( orphans?.size() > 0 ) {
96                  sortedEventGroups.add( new EventGroup(
97                    id: -1,
98                    name: 'No group',
99                    events: orphans,
100                    subjects: []
101                  ));
102                }
103
104              %>
105              <g:each in="${sortedEventGroups}" var="eventGroup" status="i">
106
107                //------------- Eventgroup ${bandNr} ---------------
108
109                // Create an eventsource for all events
110                eventSources[${bandNr}] = new Timeline.DefaultEventSource();
111
112                // Load events for this eventsource (using jquery)
113                var event_url = '${createLink(controller:'study', action:'events', id:( eventGroup.id ? eventGroup.id : -1 ), params: [ startDate: study.startDate.getTime(), study: study.id ])}';
114                $.getJSON(event_url, $.callback( _loadJSONEvents, [0, ${bandNr}, eventSources[${bandNr}], overviewEventSource, event_url] ) );
115
116                // Create a new timeline band
117                bandInfos[${bandNr}] =
118                       Timeline.createBandInfo({
119                           eventSource:    eventSources[${bandNr}],
120                           width:          30,
121                           intervalUnit:   Timeline.DateTime.DAY,
122                           intervalPixels: 40,
123                           date:           firstDate,
124                           timeZone:       +1,
125                           syncWith:       1,
126                           layout:         'original',
127                           theme:          theme
128                       });
129
130                // Make sure the date isn't printed by using the empty ether painter
131                bandInfos[${bandNr}].etherPainter = emptyEtherPainter;
132
133                // Add a title to the bandinfo
134                <%
135                  sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator );
136                  def simpleSubjects = sortedGroupSubjects.name.join( ', ' );
137
138                  // We can only show appr. 30 characters per line and as many lines as there are events
139                  def charsPerLine = 30;
140                  def numEvents = eventGroup.events?.size();
141                  def maxChars = numEvents * charsPerLine;
142
143                  // If the subjects will fit, show them all
144                  if( simpleSubjects?.size() < maxChars ) {
145                    showSubjects = simpleSubjects;
146                  } else {
147                    // Always add the first name
148                    def subjectNames = sortedGroupSubjects[0]?.name;
149
150                    // Continue adding names until the length is to long
151                    id = 0;
152                    sortedGroupSubjects.each { subject ->
153                      if( id > 0 ) {
154                        println( "ID: " + id + " - " + subjectNames?.size() + " - " + subject.name?.size() + " - " + maxChars );
155                        if( subjectNames?.size() + subject.name?.size() < maxChars - 15 ) {
156                          subjectNames += ", " + subject.name;
157                        } else {
158                          return;
159                        }
160                      }
161                      id++;
162                    }
163
164                    // Add a postfix
165                    subjectNames += " and " + ( sortedGroupSubjects?.size() - id ) + " more";
166
167                    showSubjects = subjectNames;
168                  }
169
170
171                %>
172                bandTitleInfo[ timelineNr ][ ${bandNr} ] = {
173                  title: "${eventGroup.name}",
174                  className: "<g:if test="${ eventGroup.id == -1 || !eventGroup.id  }">no_group</g:if>",
175                  subjects: "${showSubjects}"
176                };
177
178                <g:set var="bandNr" value="${bandNr+1}" />
179              </g:each>
180
181              // Synchronize all bands
182              <g:each in="${sortedEventGroups}" var="eventGroup" status="i">
183                bandInfos[${i + datesBandNr +1}].syncWith = ${datesBandNr};
184              </g:each>
185
186          </g:each>
187
188          return bandInfos;
189        }
190     </script>
191</head>
192<body>
193
194  <div class="body" id="studies">
195    <h1><g:message code="default.show.label" args="[entityName]" /></h1>
196    <g:if test="${flash.message}">
197      <div class="message">${flash.message}</div>
198    </g:if>
199    <div class="dialog">
200      <div id="tabs">
201        <ul>
202          <li><a href="#study">Study Information</a></li>
203          <li><a href="#subjects">Subjects</a></li>
204          <li><a href="#events-timeline">Events timeline</a></li>
205          <li><a href="#events-table">Events table</a></li>
206          <li><a href="#assays">Assays</a></li>
207          <li><a href="#samples">Samples</a></li>
208          <li><a href="#persons">Persons</a></li>
209          <li><a href="#publications">Publications</a></li>
210        </ul>
211
212        <div id="study">
213          <table>
214            <!-- only show the head section if there are multiple studies -->
215            <g:if test="${multipleStudies}">
216              <thead>
217                <tr>
218                  <th></th>
219                  <g:each in="${studyList}" var="studyInstance">
220                    <th>${studyInstance.title}</th>
221                  </g:each>
222                </tr>
223              </thead>
224            </g:if>
225            <%
226              // Determine a union of the fields from all studies, in order
227              // to show a proper list. We want every field to appear just once,
228              // so the list is filtered for unique values
229              studyFields = studyList[0].giveDomainFields() + studyList*.giveTemplateFields()?.flatten().unique()
230            %>
231            <!-- Show all template and domain fields, if filled -->
232            <g:each in="${studyFields}" var="field">
233              <%
234                // If a value is not set for any of the selected studies, the
235                // field should not appear in the list
236                showField = true in studyList.collect { it.fieldExists( field.name ) && it.getFieldValue( field.name ) != null }?.flatten()
237              %>
238              <g:if test="${showField}">
239                <tr>
240                  <td>${field}</td>
241                  <g:each in="${studyList}" var="studyInstance">
242                    <td>${studyInstance.getFieldValue(field.name)}</td>
243                  </g:each>
244                </tr>
245              </g:if>
246            </g:each>
247
248            <!-- Add some extra fields -->
249            <tr>
250              <td>Events</td>
251              <g:each in="${studyList}" var="studyInstance">
252                <td>
253                  <g:if test="${studyInstance.giveEventTemplates()?.size()==0}">
254                    -
255                  </g:if>
256                  <g:else>
257                   ${studyInstance.giveEventTemplates().name.join(", ")}
258                  </g:else>
259                </td>
260              </g:each>
261            </tr>
262            <tr>
263              <td>Sampling events</td>
264              <g:each in="${studyList}" var="studyInstance">
265                <td>
266                  <g:if test="${studyInstance.giveSamplingEventTemplates()?.size()==0}">
267                    -
268                  </g:if>
269                  <g:else>
270                   ${studyInstance.giveSamplingEventTemplates().name.join(", ")}
271                  </g:else>
272                </td>
273              </g:each>
274            </tr>
275                          <tr>
276                                <td>Owner</td>
277                                <g:each in="${studyList}" var="studyInstance">
278                                  <td>
279                                        <g:if test="${studyInstance.owner}">
280                                                <g:link controller="user" action="show" id="${studyInstance.owner.id}">${studyInstance.owner?.encodeAsHTML()}</g:link>
281                                        </g:if>
282                                        <g:else>
283                                         -
284                                        </g:else>
285                                  </td>
286                                </g:each>
287                          </tr>
288            <tr>
289              <td>Readers</td>
290              <g:each in="${studyList}" var="studyInstance">
291                <td>
292                  <g:if test="${studyInstance.readers?.size()==0}">
293                    -
294                  </g:if>
295                  <g:else>
296                    <g:each in="${studyInstance.readers}" var="r" status="i">
297                      <g:if test="${i > 0}">, </g:if>
298                      <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
299                    </g:each>
300                  </g:else>
301                </td>
302              </g:each>
303            </tr>
304            <tr>
305              <td>Editors</td>
306              <g:each in="${studyList}" var="studyInstance">
307                <td>
308                  <g:if test="${studyInstance.editors?.size()==0}">
309                    -
310                  </g:if>
311                  <g:else>
312                    <g:each in="${studyInstance.editors}" var="r" status="i">
313                      <g:if test="${i > 0}">, </g:if>
314                      <g:link controller="user" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link>
315                    </g:each>
316                  </g:else>
317                </td>
318              </g:each>
319            </tr>
320
321          </table>
322        </div>
323
324        <div id="subjects">
325
326          <g:if test="${studyList*.subjects?.flatten()?.size()==0}">
327            No subjects in the selected studies
328          </g:if>
329          <g:else>
330            <table>
331              <thead>
332                <tr>
333                  <g:if test="${multipleStudies}">
334                    <th></th>
335                  </g:if>
336                  <g:each in="${new dbnp.studycapturing.Subject().giveDomainFields()}" var="field">
337                    <th>${field}</th>
338                  </g:each>
339
340                  <%
341                    // Determine a union of the fields for all different
342                    // subjects in all studies. In order to show a proper list.
343                    // We want every field to appear just once,
344                    // so the list is filtered for unique values
345                    subjectTemplates = studyList*.giveSubjectTemplates()?.flatten().unique()
346                    if( !subjectTemplates ) {
347                      subjectTemplates = [];
348                      subjectFields = [];
349                    } else {
350                      subjectFields = subjectTemplates*.fields?.flatten().unique()
351                      if( !subjectFields ) {
352                        subjectFields = [];
353                      }
354                    }
355
356                    /*
357                     * These lines are rewritten because
358                     * performance sucked
359                     *
360                     *   // These took about 9 seconds (for 31 subjects and
361                     *   allSubjects = studyList*.subjects?.flatten()
362                     *
363                     *   subjectFields = subjectFields.findAll { subjectField ->
364                     *     ( true in allSubjects.collect { subject -> subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) != null }.flatten() )
365                     *   }
366                     */
367
368                    // Filter out all fields that are left blank for all subjects
369                    allSubjects = studyList*.subjects?.flatten()
370
371                    showSubjectFields = []
372                    subjectFields.each { subjectField ->
373                      for( subject in allSubjects )
374                      {
375                        // If the field is filled for this subject, we have to
376                        // show the field and should not check any other
377                        // subjects (hence the break)
378                        if( subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) ) {
379                          showSubjectFields << subjectField;
380                          break;
381                        }
382                      }
383                    }
384                  %>
385
386                  <g:each in="${showSubjectFields}" var="field">
387                    <th>${field}</th>
388                  </g:each>
389
390                </tr>
391              </thead>
392
393              <g:set var="i" value="${1}" />
394
395              <g:each in="${studyList}" var="studyInstance">
396                <%
397                  // Sort subjects by name
398                  subjects = studyInstance.subjects;
399                  sortedSubjects = subjects.sort( { a, b -> a.name <=> b.name } as Comparator )
400                %>
401
402                <g:each in="${sortedSubjects}" var="subject" status="j">
403                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
404                    <g:if test="${multipleStudies && j==0}">
405                      <td class="studytitle" rowspan="${sortedSubjects?.size()}">
406                        ${studyInstance.title}
407                      </td>
408                    </g:if>
409                    <g:each in="${subject.giveDomainFields()}" var="field">
410                      <td>${subject.getFieldValue(field.name)}</td>
411                    </g:each>
412                 
413                    <g:each in="${showSubjectFields}" var="field">
414                      <td>
415                        <g:if test="${subject.fieldExists(field.name)}">
416                          ${subject.getFieldValue(field.name)}
417                        </g:if>
418                        <g:else>
419                          N/A
420                        </g:else>
421                      </td>
422                    </g:each>
423
424                  </tr>
425                  <g:set var="i" value="${i + 1}" />
426                </g:each>
427              </g:each>
428            </table>
429          </g:else>
430        </div>
431
432        <div id="events-timeline">
433          <g:if test="${studyList*.events?.flatten()?.size()==0 && studyInstance*.samplingEvents?.flatten()?.size()==0 }">
434            No events in these studies
435          </g:if>
436          <g:else>
437            <g:each in="${studyList}" var="study" status="i">
438              <div style="margin: 10px; ">
439                <div class="eventtitles" id="eventtitles-${i}"></div>
440                <div class="eventstimeline" id="eventstimeline-${i}"></div>
441              </div>
442            </g:each>
443            <noscript>
444              <table>
445                <thead>
446                  <tr>
447                    <g:if test="${multipleStudies}">
448                      <th></th>
449                    </g:if>
450                    <th>Start time</th>
451                    <th>Duration</th>
452                    <th>Type</th>
453                    <th>Sampling event</th>
454                    <th>Parameters</th>
455                  </tr>
456                </thead>
457
458                <g:set var="i" value="${1}" />
459
460                <g:each in="${studyList}" var="studyInstance">
461                  <%
462                    // Sort events by starttime and duration
463                    events = studyInstance.events + studyInstance.samplingEvents;
464                    sortedEvents = events.sort( { a, b ->
465                          //a.startTime == b.startTime ?
466                            //a.getDuration().getValue() <=> b.getDuration().getValue() :
467                          a.startTime <=> b.startTime
468                      } as Comparator )
469                  %>
470
471                  <g:each in="${sortedEvents}" var="event" status="j">
472                    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
473                      <g:if test="${multipleStudies && j==0}">
474                        <td class="studytitle" rowspan="${sortedEvents?.size()}">
475                          ${studyInstance.title}
476                        </td>
477                      </g:if>
478                      <td>${event.getStartTimeString()}</td>
479                      <td>${((event.getClass() == 'Event') ? event.getDurationString() : '')}</td>
480                      <td>${event.template.name}</td>
481                      <td>
482                        <g:if test="${event instanceof dbnp.studycapturing.SamplingEvent}">
483                          <g:checkBox name="samplingEvent" disabled="${true}" value="${true}"/>
484                        </g:if>
485                        <g:else>
486                          <g:checkBox name="event" disabled="${true}" value="${false}" />
487                        </g:else>
488                      </td>
489                      <td>
490                        <g:set var="fieldCounter" value="${1}" />
491                        <g:each in="${event.giveTemplateFields()}" var="field">
492                          <g:if test="${event.getFieldValue(field.name)}">
493                            <g:if test="${fieldCounter > 1}">, </g:if>
494                              ${field.name} = ${event.getFieldValue( field.name )}
495                            <g:set var="fieldCounter" value="${fieldCounter + 1}" />
496                          </g:if>
497                        </g:each>
498                      </td>
499                    </tr>
500
501                    <g:set var="i" value="${i + 1}" />
502                  </g:each>
503                </g:each>
504              </table>
505
506            </noscript>
507
508          </g:else>
509        </div>
510
511        <div id="events-table">
512          <g:if test="${studyList*.eventGroups?.flatten()?.size()==0}">
513            No event groups in this study
514          </g:if>
515          <g:else>
516            <%
517              // Determine a union of the event templates for all different
518              // eventgroups in all studies, in order to show a proper list.
519              // We want every field to appear just once,
520              // so the list is filtered for unique values
521              groupTemplates = studyList*.giveAllEventTemplates()?.flatten().unique()
522            %>
523            <table>
524              <thead>
525                <tr>
526                  <g:if test="${multipleStudies}">
527                    <th></th>
528                  </g:if>
529                  <th>Name</th>
530                  <th colspan="${groupTemplates?.size()}">Events</th>
531                  <th>Subjects</th>
532                </tr>
533                <tr>
534                  <g:if test="${multipleStudies}">
535                    <th></th>
536                  </g:if>
537                  <th></th>
538                  <g:each in="${groupTemplates}" var="eventTemplate">
539                    <th>${eventTemplate.name}</th>
540                  </g:each>
541                  <th></th>
542                </tr>
543              </thead>
544
545              <g:set var="i" value="${1}" />
546
547              <g:each in="${studyList}" var="studyInstance">
548                <%
549                  def sortedEventGroups = studyInstance.eventGroups.sort( { a, b ->
550                      return a.name <=> b.name;
551                  }  as Comparator );
552
553                  def orphans = studyInstance.getOrphanEvents();
554                  if( orphans?.size() > 0 ) {
555                    sortedEventGroups.add( new EventGroup(
556                      id: -1,
557                      name: 'No group',
558                      events: orphans,
559                      subjects: []
560                    ));
561                  }
562
563                %>
564                <g:each in="${sortedEventGroups}" var="eventGroup" status="j">
565                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
566                    <g:if test="${multipleStudies && j==0}">
567                      <td class="studytitle" rowspan="${sortedEventGroups?.size()}">
568                        ${studyInstance.title}
569                      </td>
570                    </g:if>
571                    <td>${eventGroup.name}</td>
572
573                    <g:each in="${groupTemplates}" var="currentEventTemplate">
574                      <td>
575                        <g:each in="${eventGroup.events}" var="event">
576                          <g:if test="${event.template.name==currentEventTemplate.name}">
577
578                            <g:set var="fieldCounter" value="${1}" />
579                            <g:each in="${event.giveTemplateFields()}" var="field">
580                              <g:if test="${event.getFieldValue(field.name)}">
581                                <g:if test="${fieldCounter > 1}">, </g:if>
582                                  ${field.name} = ${event.getFieldValue( field.name )}
583                                <g:set var="fieldCounter" value="${fieldCounter + 1}" />
584                              </g:if>
585                            </g:each>
586                          </g:if>
587                        </g:each>
588                      </td>
589                    </g:each>
590                    <td>
591                      <% sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
592                      ${sortedGroupSubjects.name.join( ', ' )}
593                    </td>
594                  </tr>
595
596                  <g:set var="i" value="${i + 1}" />
597                </g:each>
598
599              </g:each>
600
601            </table>
602          </g:else>
603        </div>
604
605        <div id="assays">
606          <g:if test="${studyList*.assays?.flatten()?.size()==0}">
607            No assays in these studies
608          </g:if>
609          <g:else>
610            <table>
611              <thead>
612                <tr>
613                  <g:if test="${multipleStudies}">
614                    <th></th>
615                  </g:if>
616                  <th width="100">Assay Name</th>
617                  <th width="100">Module</th>
618                  <th width="150">Platform</th>
619                  <th>Link</th>
620                  <th>Samples</th>
621                </tr>
622              </thead>
623              <g:set var="i" value="${1}" />
624
625              <g:each in="${studyList}" var="studyInstance">
626                <g:each in="${studyInstance.assays}" var="assay" status="j">
627                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
628                    <g:if test="${multipleStudies && j==0}">
629                      <td class="studytitle" rowspan="${studyInstance.assays?.size()}">
630                        ${studyInstance.title}
631                      </td>
632                    </g:if>
633                    <td>${assay.name}</td>
634                    <td>${assay.module.name}</td>
635                    <td>${assay.module.platform}</td>
636                    <td><a href="${assay.module.url}/assay/${assay.externalAssayID}">view</a></td>
637                    <td>
638                      <% sortedAssaySamples = assay.samples.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
639                      ${sortedAssaySamples.name.join( ', ' )}
640                    </td>
641                  </tr>
642                  <g:set var="i" value="${i + 1}" />
643
644                </g:each>
645              </g:each>
646            </table>
647          </g:else>
648        </div>
649
650        <div id="samples">
651
652          <g:if test="${studyList*.samples.flatten()?.size()==0}">
653            No samples in the selected studies
654          </g:if>
655          <g:else>
656            <table>
657              <thead>
658                <tr>
659                  <g:if test="${multipleStudies}">
660                    <th></th>
661                  </g:if>
662                  <g:each in="${new dbnp.studycapturing.Sample().giveDomainFields()}" var="field">
663                    <th>${field}</th>
664                  </g:each>
665
666                  <%
667                    // Determine a union of the fields for all different
668                    // samples in all studies. In order to show a proper list.
669                    // We want every field to appear just once,
670                    // so the list is filtered for unique values
671                    sampleTemplates = studyList*.giveSampleTemplates().flatten().unique()
672
673                    if( !sampleTemplates ) {
674                      sampleTemplates = [];
675                      sampleFields = [];
676                      showSampleFields = [];
677                    } else {
678                      sampleFields = sampleTemplates*.fields.flatten().unique()
679                      if( !sampleFields ) {
680                        sampleFields = [];
681                        showSampleFields = [];
682                      } else {
683                        // Filter out all fields that are left blank for all samples
684                        allSamples = studyList*.samples.flatten()
685
686                        showSampleFields = [];
687                        sampleFields.each { sampleField ->
688                          for( sample in allSamples )
689                          {
690                            // If the field is filled for this subject, we have to
691                            // show the field and should not check any other
692                            // samples (hence the break)
693                            if( sample.fieldExists( sampleField.name ) && sample.getFieldValue( sampleField.name ) ) {
694                              showSampleFields << sampleField;
695                              break;
696                            }
697                          }
698                        }
699                      }
700                    }
701                  %>
702
703                  <g:each in="${showSampleFields}" var="field">
704                    <th>${field}</th>
705                  </g:each>
706
707                </tr>
708              </thead>
709
710              <g:set var="i" value="${1}" />
711
712              <g:each in="${studyList}" var="studyInstance">
713                <%
714                  // Sort samples by name
715                  samples = studyInstance.samples;
716                  sortedSamples = samples.sort( { a, b -> a.name <=> b.name } as Comparator )
717                %>
718
719                <g:each in="${sortedSamples}" var="sample" status="j">
720                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
721                    <g:if test="${multipleStudies && j==0}">
722                      <td class="studytitle" rowspan="${sortedSamples?.size()}">
723                        ${studyInstance.title}
724                      </td>
725                    </g:if>
726                    <g:each in="${sample.giveDomainFields()}" var="field">
727                      <td>${sample.getFieldValue(field.name)}</td>
728                    </g:each>
729
730                    <g:each in="${showSampleFields}" var="field">
731                      <td>
732                        <g:if test="${sample.fieldExists(field.name)}">
733                          ${sample.getFieldValue(field.name)}
734                        </g:if>
735                        <g:else>
736                          N/A
737                        </g:else>
738                      </td>
739                    </g:each>
740
741                  </tr>
742                  <g:set var="i" value="${i + 1}" />
743                </g:each>
744              </g:each>
745
746            </table>
747          </g:else>
748        </div>
749
750        <div id="persons">
751          <%
752            // Determine a list of all persons
753            allPersons = studyList*.persons*.person.flatten().unique()
754          %>
755          <g:if test="${allPersons?.size()==0}">
756            No persons involved in these studies
757          </g:if>
758          <g:else>
759            <table>
760              <tr>
761                <thead>
762                  <th>Name</th>
763                  <th>Affiliations</th>
764                  <th>Phone</th>
765                  <th>Email</th>
766                  <g:if test="${multipleStudies}">
767                    <g:each in="${studyList}" var="studyInstance">
768                      <th>${studyInstance.title}</th>
769                    </g:each>
770                  </g:if>
771                  <g:else>
772                    <th>Role</th>
773                  </g:else>
774                </thead>
775              </tr>
776              <g:each in="${allPersons}" var="person" status="i">
777                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
778                  <td>${person.firstName} ${person.prefix} ${person.lastName}</td>
779                  <td>
780                    ${person.affiliations.join(', ')}
781                  </td>
782                  <td>${person.phone}</td>
783                  <td>${person.email}</td>
784                  <g:each in="${studyList}" var="studyInstance">
785                    <%
786                      studyperson = studyInstance.persons.find { it.person == person }
787                    %>
788                    <td>
789                      <g:if test="${studyperson}">
790                        ${studyperson.role.name}
791                      </g:if>
792                     </td>
793                  </g:each>
794
795                </tr>
796              </g:each>
797            </table>
798          </g:else>
799        </div>
800
801        <div id="publications">
802          <%
803            // Determine a list of all persons
804            allPublications = studyList*.publications.flatten().unique()
805          %>
806          <g:if test="${allPublications?.size()==0}">
807            No publications attached to these studies
808          </g:if>
809          <g:else>
810            <table>
811              <tr>
812                <thead>
813                  <th>Title</th>
814                  <th>Authors</th>
815                  <th>Comments</th>
816
817                  <g:if test="${multipleStudies}">
818                    <g:each in="${studyList}" var="studyInstance">
819                      <th>${studyInstance.title}</th>
820                    </g:each>
821                  </g:if>
822                </thead>
823              </tr>
824              <g:each in="${allPublications}" var="publication" status="i">
825                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
826                  <td>${publication.title}</td>
827                  <td>
828                    ${publication.authorsList}
829                  </td>
830                  <td>${publication.comments}</td>
831                  <g:if test="${multipleStudies}">
832                    <g:each in="${studyList}" var="studyInstance">
833                      <td>
834                        <g:if test="${publication in studyInstance.publications}">
835                          x
836                        </g:if>
837                      </td>
838                    </g:each>
839                  </g:if>
840                </tr>
841              </g:each>
842            </table>
843          </g:else>
844        </div>
845
846      </div>
847    </div>
848    <br>
849    <div class="buttons">
850      <g:form>
851        <g:if test="${studyList?.size() == 1}">
852          <g:set var="studyInstance" value="${studyList[0]}" />
853          <g:hiddenField name="id" value="${studyInstance?.id}" />
854          <span class="button"><g:link class="edit" controller="wizard" params="[jump:'edit']" id="${studyInstance?.id}">${message(code: 'default.button.edit.label', default: 'Edit')}</g:link></span>
855          <span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
856        </g:if>
857        <span class="button"><g:link class="backToList" action="list">Back to list</g:link></span>
858      </g:form>
859    </div>
860
861  </div>
862</body>
863</html>
Note: See TracBrowser for help on using the repository browser.