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

Last change on this file since 1008 was 1008, checked in by s.h.sikkema@…, 12 years ago

Upped jumpbar version and fixed backlink for jumpbar link

  • Property svn:keywords set to Author Date Rev
File size: 34.8 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>Public</td>
277              <g:each in="${studyList}" var="studyInstance">
278                <td>
279                   ${studyInstance.publicstudy}
280                </td>
281              </g:each>
282            </tr>
283            <tr>
284              <td>Owner</td>
285              <g:each in="${studyList}" var="studyInstance">
286                <td>
287                   ${studyInstance.owner.username}
288                </td>
289              </g:each>
290            </tr>
291            <tr>
292              <td>Readers</td>
293              <g:each in="${studyList}" var="studyInstance">
294                <td>
295                  <g:if test="${studyInstance.readers.size() == 0}">
296                    -
297                  </g:if>
298                  <g:else>
299                    ${studyInstance.readers.username.join( ", " )}
300                  </g:else>
301                </td>
302              </g:each>
303            </tr>
304            <tr>
305              <td>Writers</td>
306              <g:each in="${studyList}" var="studyInstance">
307                <td>
308                  <g:if test="${studyInstance.writers.size()==0}">
309                    -
310                  </g:if>
311                  <g:else>
312                    ${studyInstance.writers.username.join( ", " )}
313                  </g:else>
314                </td>
315              </g:each>
316            </tr>
317          </table>
318        </div>
319
320        <div id="subjects">
321
322          <g:if test="${studyList*.subjects?.flatten()?.size()==0}">
323            No subjects in the selected studies
324          </g:if>
325          <g:else>
326            <table>
327              <thead>
328                <tr>
329                  <g:if test="${multipleStudies}">
330                    <th></th>
331                  </g:if>
332                  <g:each in="${new dbnp.studycapturing.Subject().giveDomainFields()}" var="field">
333                    <th>${field}</th>
334                  </g:each>
335
336                  <%
337                    // Determine a union of the fields for all different
338                    // subjects in all studies. In order to show a proper list.
339                    // We want every field to appear just once,
340                    // so the list is filtered for unique values
341                    subjectTemplates = studyList*.giveSubjectTemplates()?.flatten().unique()
342                    if( !subjectTemplates ) {
343                      subjectTemplates = [];
344                      subjectFields = [];
345                    } else {
346                      subjectFields = subjectTemplates*.fields?.flatten().unique()
347                      if( !subjectFields ) {
348                        subjectFields = [];
349                      }
350                    }
351
352                    /*
353                     * These lines are rewritten because
354                     * performance sucked
355                     *
356                     *   // These took about 9 seconds (for 31 subjects and
357                     *   allSubjects = studyList*.subjects?.flatten()
358                     *
359                     *   subjectFields = subjectFields.findAll { subjectField ->
360                     *     ( true in allSubjects.collect { subject -> subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) != null }.flatten() )
361                     *   }
362                     */
363
364                    // Filter out all fields that are left blank for all subjects
365                    allSubjects = studyList*.subjects?.flatten()
366
367                    showSubjectFields = []
368                    subjectFields.each { subjectField ->
369                      for( subject in allSubjects )
370                      {
371                        // If the field is filled for this subject, we have to
372                        // show the field and should not check any other
373                        // subjects (hence the break)
374                        if( subject.fieldExists( subjectField.name ) && subject.getFieldValue( subjectField.name ) ) {
375                          showSubjectFields << subjectField;
376                          break;
377                        }
378                      }
379                    }
380                  %>
381
382                  <g:each in="${showSubjectFields}" var="field">
383                    <th>${field}</th>
384                  </g:each>
385
386                </tr>
387              </thead>
388
389              <g:set var="i" value="${1}" />
390
391              <g:each in="${studyList}" var="studyInstance">
392                <%
393                  // Sort subjects by name
394                  subjects = studyInstance.subjects;
395                  sortedSubjects = subjects.sort( { a, b -> a.name <=> b.name } as Comparator )
396                %>
397
398                <g:each in="${sortedSubjects}" var="subject" status="j">
399                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
400                    <g:if test="${multipleStudies && j==0}">
401                      <td class="studytitle" rowspan="${sortedSubjects?.size()}">
402                        ${studyInstance.title}
403                      </td>
404                    </g:if>
405                    <g:each in="${subject.giveDomainFields()}" var="field">
406                      <td>${subject.getFieldValue(field.name)}</td>
407                    </g:each>
408                 
409                    <g:each in="${showSubjectFields}" var="field">
410                      <td>
411                        <g:if test="${subject.fieldExists(field.name)}">
412                          ${subject.getFieldValue(field.name)}
413                        </g:if>
414                        <g:else>
415                          N/A
416                        </g:else>
417                      </td>
418                    </g:each>
419
420                  </tr>
421                  <g:set var="i" value="${i + 1}" />
422                </g:each>
423              </g:each>
424            </table>
425          </g:else>
426        </div>
427
428        <div id="events-timeline">
429          <g:if test="${studyList*.events?.flatten()?.size()==0 && studyInstance*.samplingEvents?.flatten()?.size()==0 }">
430            No events in these studies
431          </g:if>
432          <g:else>
433            <g:each in="${studyList}" var="study" status="i">
434              <div style="margin: 10px; ">
435                <div class="eventtitles" id="eventtitles-${i}"></div>
436                <div class="eventstimeline" id="eventstimeline-${i}"></div>
437              </div>
438            </g:each>
439            <noscript>
440              <table>
441                <thead>
442                  <tr>
443                    <g:if test="${multipleStudies}">
444                      <th></th>
445                    </g:if>
446                    <th>Start time</th>
447                    <th>Duration</th>
448                    <th>Type</th>
449                    <th>Sampling event</th>
450                    <th>Parameters</th>
451                  </tr>
452                </thead>
453
454                <g:set var="i" value="${1}" />
455
456                <g:each in="${studyList}" var="studyInstance">
457                  <%
458                    // Sort events by starttime and duration
459                    events = studyInstance.events + studyInstance.samplingEvents;
460                    sortedEvents = events.sort( { a, b ->
461                          //a.startTime == b.startTime ?
462                            //a.getDuration().getValue() <=> b.getDuration().getValue() :
463                          a.startTime <=> b.startTime
464                      } as Comparator )
465                  %>
466
467                  <g:each in="${sortedEvents}" var="event" status="j">
468                    <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
469                      <g:if test="${multipleStudies && j==0}">
470                        <td class="studytitle" rowspan="${sortedEvents?.size()}">
471                          ${studyInstance.title}
472                        </td>
473                      </g:if>
474                      <td>${event.getStartTimeString()}</td>
475                      <td>${((event.getClass() == 'Event') ? event.getDurationString() : '')}</td>
476                      <td>${event.template.name}</td>
477                      <td>
478                        <g:if test="${event instanceof dbnp.studycapturing.SamplingEvent}">
479                          <g:checkBox name="samplingEvent" disabled="${true}" value="${true}"/>
480                        </g:if>
481                        <g:else>
482                          <g:checkBox name="event" disabled="${true}" value="${false}" />
483                        </g:else>
484                      </td>
485                      <td>
486                        <g:set var="fieldCounter" value="${1}" />
487                        <g:each in="${event.giveTemplateFields()}" var="field">
488                          <g:if test="${event.getFieldValue(field.name)}">
489                            <g:if test="${fieldCounter > 1}">, </g:if>
490                              ${field.name} = ${event.getFieldValue( field.name )}
491                            <g:set var="fieldCounter" value="${fieldCounter + 1}" />
492                          </g:if>
493                        </g:each>
494                      </td>
495                    </tr>
496
497                    <g:set var="i" value="${i + 1}" />
498                  </g:each>
499                </g:each>
500              </table>
501
502            </noscript>
503
504          </g:else>
505        </div>
506
507        <div id="events-table">
508          <g:if test="${studyList*.eventGroups?.flatten()?.size()==0}">
509            No event groups in this study
510          </g:if>
511          <g:else>
512            <%
513              // Determine a union of the event templates for all different
514              // eventgroups in all studies, in order to show a proper list.
515              // We want every field to appear just once,
516              // so the list is filtered for unique values
517              groupTemplates = studyList*.giveAllEventTemplates()?.flatten().unique()
518            %>
519            <table>
520              <thead>
521                <tr>
522                  <g:if test="${multipleStudies}">
523                    <th></th>
524                  </g:if>
525                  <th>Name</th>
526                  <th colspan="${groupTemplates?.size()}">Events</th>
527                  <th>Subjects</th>
528                </tr>
529                <tr>
530                  <g:if test="${multipleStudies}">
531                    <th></th>
532                  </g:if>
533                  <th></th>
534                  <g:each in="${groupTemplates}" var="eventTemplate">
535                    <th>${eventTemplate.name}</th>
536                  </g:each>
537                  <th></th>
538                </tr>
539              </thead>
540
541              <g:set var="i" value="${1}" />
542
543              <g:each in="${studyList}" var="studyInstance">
544                <%
545                  def sortedEventGroups = studyInstance.eventGroups.sort( { a, b ->
546                      return a.name <=> b.name;
547                  }  as Comparator );
548
549                  def orphans = studyInstance.getOrphanEvents();
550                  if( orphans?.size() > 0 ) {
551                    sortedEventGroups.add( new EventGroup(
552                      id: -1,
553                      name: 'No group',
554                      events: orphans,
555                      subjects: []
556                    ));
557                  }
558
559                %>
560                <g:each in="${sortedEventGroups}" var="eventGroup" status="j">
561                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
562                    <g:if test="${multipleStudies && j==0}">
563                      <td class="studytitle" rowspan="${sortedEventGroups?.size()}">
564                        ${studyInstance.title}
565                      </td>
566                    </g:if>
567                    <td>${eventGroup.name}</td>
568
569                    <g:each in="${groupTemplates}" var="currentEventTemplate">
570                      <td>
571                        <g:each in="${eventGroup.events}" var="event">
572                          <g:if test="${event.template.name==currentEventTemplate.name}">
573
574                            <g:set var="fieldCounter" value="${1}" />
575                            <g:each in="${event.giveTemplateFields()}" var="field">
576                              <g:if test="${event.getFieldValue(field.name)}">
577                                <g:if test="${fieldCounter > 1}">, </g:if>
578                                  ${field.name} = ${event.getFieldValue( field.name )}
579                                <g:set var="fieldCounter" value="${fieldCounter + 1}" />
580                              </g:if>
581                            </g:each>
582                          </g:if>
583                        </g:each>
584                      </td>
585                    </g:each>
586                    <td>
587                      <% sortedGroupSubjects = eventGroup.subjects.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
588                      ${sortedGroupSubjects.name.join( ', ' )}
589                    </td>
590                  </tr>
591
592                  <g:set var="i" value="${i + 1}" />
593                </g:each>
594
595              </g:each>
596
597            </table>
598          </g:else>
599        </div>
600
601        <div id="assays">
602          <g:if test="${studyList*.assays?.flatten()?.size()==0}">
603            No assays in these studies
604          </g:if>
605          <g:else>
606            <table>
607              <thead>
608                <tr>
609                  <g:if test="${multipleStudies}">
610                    <th></th>
611                  </g:if>
612                        <th width="100">Assay Code</th>
613                  <th width="100">Assay Name</th>
614                  <th width="100">Module</th>
615                  <th width="150">Platform</th>
616                  <th>Link</th>
617                  <th>Samples</th>
618                </tr>
619              </thead>
620              <g:set var="i" value="${1}" />
621
622              <g:each in="${studyList}" var="studyInstance">
623                <g:each in="${studyInstance.assays}" var="assay" status="j">
624                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
625                    <g:if test="${multipleStudies && j==0}">
626                      <td class="studytitle" rowspan="${studyInstance.assays?.size()}">
627                        ${studyInstance.title}
628                      </td>
629                    </g:if>
630                          <td>${assay.token}</td>
631                    <td>${assay.name}</td>
632                    <td>${assay.module.name}</td>
633                    <td>${assay.module.platform}</td>
634                    %{--<td><a href="${assay.module.url}/assay/${assay.externalAssayID}">view</a></td>--}%
635                    <td><jumpbar:link
636                      linkDest="${createLink(action:'show', id:study.id)}"
637                      linkText='Go back to GSCF'
638                      frameSource="${assay.module.url}/assay/showByToken/${assay.externalAssayID}"
639                      pageTitle="Assay View in Module">
640                      view
641                    </jumpbar:link></td>
642                    <td>
643                      <% sortedAssaySamples = assay.samples.sort( { a, b -> a.name <=> b.name } as Comparator )  %>
644                      ${sortedAssaySamples.name.join( ', ' )}
645                    </td>
646                  </tr>
647                  <g:set var="i" value="${i + 1}" />
648
649                </g:each>
650              </g:each>
651            </table>
652          </g:else>
653        </div>
654
655        <div id="samples">
656
657          <g:if test="${studyList*.samples.flatten()?.size()==0}">
658            No samples in the selected studies
659          </g:if>
660          <g:else>
661            <table>
662              <thead>
663                <tr>
664                  <g:if test="${multipleStudies}">
665                    <th></th>
666                  </g:if>
667
668                        <th>Parent Subject</th>
669                        <th>Parent Sampling Event</th>
670
671
672                  <g:each in="${new dbnp.studycapturing.Sample().giveDomainFields()}" var="field">
673                    <th>${field}</th>
674                  </g:each>
675
676                  <%
677                    // Determine a union of the fields for all different
678                    // samples in all studies. In order to show a proper list.
679                    // We want every field to appear just once,
680                    // so the list is filtered for unique values
681                    sampleTemplates = studyList*.giveSampleTemplates().flatten().unique()
682
683                    if( !sampleTemplates ) {
684                      sampleTemplates = [];
685                      sampleFields = [];
686                      showSampleFields = [];
687                    } else {
688                      sampleFields = sampleTemplates*.fields.flatten().unique()
689                      if( !sampleFields ) {
690                        sampleFields = [];
691                        showSampleFields = [];
692                      } else {
693                        // Filter out all fields that are left blank for all samples
694                        allSamples = studyList*.samples.flatten()
695
696                        showSampleFields = [];
697                        sampleFields.each { sampleField ->
698                          for( sample in allSamples )
699                          {
700                            // If the field is filled for this subject, we have to
701                            // show the field and should not check any other
702                            // samples (hence the break)
703                            if( sample.fieldExists( sampleField.name ) && sample.getFieldValue( sampleField.name ) ) {
704                              showSampleFields << sampleField;
705                              break;
706                            }
707                          }
708                        }
709                      }
710                    }
711                  %>
712
713                  <g:each in="${showSampleFields}" var="field">
714                    <th>${field}</th>
715                  </g:each>
716
717                </tr>
718              </thead>
719
720              <g:set var="i" value="${1}" />
721
722              <g:each in="${studyList}" var="studyInstance">
723                <%
724                  // Sort samples by name
725                  samples = studyInstance.samples;
726                  sortedSamples = samples.sort( { a, b -> a.name <=> b.name } as Comparator )
727                %>
728
729                <g:each in="${sortedSamples}" var="sample" status="j">
730                  <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
731                    <g:if test="${multipleStudies && j==0}">
732                      <td class="studytitle" rowspan="${sortedSamples?.size()}">
733                        ${studyInstance.title}
734                      </td>
735                    </g:if>
736                          <td>${sample.parentSubject?.name}</td>
737                          <td>${sample.parentEvent?.template?.name} at ${sample.parentEvent?.getStartTimeString()}</td>
738                    <g:each in="${sample.giveDomainFields()}" var="field">
739                      <td>${sample.getFieldValue(field.name)}</td>
740                    </g:each>
741
742                    <g:each in="${showSampleFields}" var="field">
743                      <td>
744                        <g:if test="${sample.fieldExists(field.name)}">
745                          ${sample.getFieldValue(field.name)}
746                        </g:if>
747                        <g:else>
748                          N/A
749                        </g:else>
750                      </td>
751                    </g:each>
752
753                  </tr>
754                  <g:set var="i" value="${i + 1}" />
755                </g:each>
756              </g:each>
757
758            </table>
759          </g:else>
760        </div>
761
762        <div id="persons">
763          <%
764            // Determine a list of all persons
765            allPersons = studyList*.persons*.person.flatten().unique()
766          %>
767          <g:if test="${allPersons?.size()==0}">
768            No persons involved in these studies
769          </g:if>
770          <g:else>
771            <table>
772              <tr>
773                <thead>
774                  <th>Name</th>
775                  <th>Affiliations</th>
776                  <th>Phone</th>
777                  <th>Email</th>
778                  <g:if test="${multipleStudies}">
779                    <g:each in="${studyList}" var="studyInstance">
780                      <th>${studyInstance.title}</th>
781                    </g:each>
782                  </g:if>
783                  <g:else>
784                    <th>Role</th>
785                  </g:else>
786                </thead>
787              </tr>
788              <g:each in="${allPersons}" var="person" status="i">
789                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
790                  <td>${person.firstName} ${person.prefix} ${person.lastName}</td>
791                  <td>
792                    ${person.affiliations.join(', ')}
793                  </td>
794                  <td>${person.phone}</td>
795                  <td>${person.email}</td>
796                  <g:each in="${studyList}" var="studyInstance">
797                    <%
798                      studyperson = studyInstance.persons.find { it.person == person }
799                    %>
800                    <td>
801                      <g:if test="${studyperson}">
802                        ${studyperson.role.name}
803                      </g:if>
804                     </td>
805                  </g:each>
806
807                </tr>
808              </g:each>
809            </table>
810          </g:else>
811        </div>
812
813        <div id="publications">
814          <%
815            // Determine a list of all persons
816            allPublications = studyList*.publications.flatten().unique()
817          %>
818          <g:if test="${allPublications?.size()==0}">
819            No publications attached to these studies
820          </g:if>
821          <g:else>
822            <table>
823              <tr>
824                <thead>
825                  <th>Title</th>
826                  <th>Authors</th>
827                  <th>Comments</th>
828
829                  <g:if test="${multipleStudies}">
830                    <g:each in="${studyList}" var="studyInstance">
831                      <th>${studyInstance.title}</th>
832                    </g:each>
833                  </g:if>
834                </thead>
835              </tr>
836              <g:each in="${allPublications}" var="publication" status="i">
837                <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
838                  <td>${publication.title}</td>
839                  <td>
840                    ${publication.authorsList}
841                  </td>
842                  <td>${publication.comments}</td>
843                  <g:if test="${multipleStudies}">
844                    <g:each in="${studyList}" var="studyInstance">
845                      <td>
846                        <g:if test="${publication in studyInstance.publications}">
847                          x
848                        </g:if>
849                      </td>
850                    </g:each>
851                  </g:if>
852                </tr>
853              </g:each>
854            </table>
855          </g:else>
856        </div>
857
858      </div>
859    </div>
860    <br>
861    <div class="buttons">
862      <g:form>
863        <g:if test="${studyList?.size() == 1}">
864          <g:set var="studyInstance" value="${studyList[0]}" />
865          <g:hiddenField name="id" value="${studyInstance?.id}" />
866          <g:if test="${studyInstance.canWrite(loggedInUser)}">
867            <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>
868          </g:if>
869          <g:if test="${studyInstance.isOwner(loggedInUser)}">
870            <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>
871          </g:if>
872          </g:if>
873        <span class="button"><g:link class="backToList" action="list">Back to list</g:link></span>
874      </g:form>
875    </div>
876
877  </div>
878</body>
879</html>
Note: See TracBrowser for help on using the repository browser.