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

Last change on this file since 536 was 536, checked in by roberth, 12 years ago

Samples are now shown in the study overview page. Also some tests are added and the bootstrap is updated to show some sample fields with a template

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