source: trunk/www/common/annotations/annotate.jsp @ 6945

Last change on this file since 6945 was 6945, checked in by Nicklas Nordborg, 6 years ago

References #1941: Store experimental factor values as part experiments

Implemented support for syncing/cloning/deleting annotations in batch by selecting multiple annotations in one go.

New icons for inherited annotations depending on inherited/cloned/sync status.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 25.2 KB
Line 
1<%-- $Id: annotate.jsp 6945 2015-09-04 09:19:58Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Jari Häkkinen, Nicklas Nordborg
5  Copyright (C) 2007 Nicklas Nordborg
6
7  This file is part of BASE - BioArray Software Environment.
8  Available at http://base.thep.lu.se/
9
10  BASE is free software; you can redistribute it and/or
11  modify it under the terms of the GNU General Public License
12  as published by the Free Software Foundation; either version 3
13  of the License, or (at your option) any later version.
14
15  BASE is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License
21  along with BASE. If not, see <http://www.gnu.org/licenses/>.
22  ------------------------------------------------------------------
23 
24  @author Nicklas
25  @version 2.0
26--%>
27<%@ page pageEncoding="UTF-8" session="false"
28  import="net.sf.basedb.core.SessionControl"
29  import="net.sf.basedb.core.DbControl"
30  import="net.sf.basedb.core.Item"
31  import="net.sf.basedb.core.Type"
32  import="net.sf.basedb.core.BasicItem"
33  import="net.sf.basedb.core.Permission"
34  import="net.sf.basedb.core.Annotatable"
35  import="net.sf.basedb.core.Nameable"
36  import="net.sf.basedb.core.Protocol"
37  import="net.sf.basedb.core.Subtypable"
38  import="net.sf.basedb.core.ItemSubtype"
39  import="net.sf.basedb.core.BioPlateType"
40  import="net.sf.basedb.core.BioPlate"
41  import="net.sf.basedb.core.AnnotationSet"
42  import="net.sf.basedb.core.Annotation"
43  import="net.sf.basedb.core.Unit"
44  import="net.sf.basedb.core.Quantity"
45  import="net.sf.basedb.core.AnnotatableProxy"
46  import="net.sf.basedb.core.ItemQuery"
47  import="net.sf.basedb.core.Include"
48  import="net.sf.basedb.core.ItemResultList"
49  import="net.sf.basedb.core.AnnotationType"
50  import="net.sf.basedb.core.AnnotationTypeCategory"
51  import="net.sf.basedb.core.PermissionDeniedException"
52  import="net.sf.basedb.core.query.Expressions"
53  import="net.sf.basedb.core.query.Restrictions"
54  import="net.sf.basedb.core.query.Hql"
55  import="net.sf.basedb.core.query.Orders"
56  import="net.sf.basedb.util.NameableComparator"
57  import="net.sf.basedb.clients.web.Base"
58  import="net.sf.basedb.clients.web.util.HTML"
59  import="net.sf.basedb.util.formatter.Formatter"
60  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
61  import="net.sf.basedb.clients.web.formatter.FormatterSettings"
62  import="net.sf.basedb.util.Values"
63  import="org.json.simple.JSONObject"
64  import="org.json.simple.JSONArray"
65  import="java.util.ArrayList"
66  import="java.util.List"
67  import="java.util.Date"
68  import="java.util.Set"
69  import="java.util.HashSet"
70  import="java.util.TreeSet"
71  import="java.util.Map"
72  import="java.util.HashMap"
73%>
74<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
75<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
76<%!
77private JSONObject makeJSON(DbControl dc, AnnotationType at, Annotation a, boolean isProtocolParameter, Set<AnnotationTypeCategory> allCategories)
78{
79  // Create the JSON objects for holding all info
80  // The base object has 'id', 'source', 'annotationType' and 'annotation'
81  JSONObject json = new JSONObject();
82  json.put("id", ""+at.getId() + (a!=null ? "-" + a.getId() : ""));
83  // If 'a' is null this is a primary annotation that has no current values
84  json.put("source", a == null ? "PRIMARY" : a.getSource().name());
85
86  JSONObject jsonAt = new JSONObject();
87  json.put("annotationType", jsonAt);
88  JSONObject jsonA = new JSONObject();
89  json.put("annotation", jsonA);
90  JSONArray jsonValues = new JSONArray();
91  jsonA.put("values", jsonValues);
92
93  // Load annotation type information
94  Type valueType = at.getValueType();
95  Formatter formatter = FormatterFactory.getTypeFormatter(dc.getSessionControl(), valueType);
96 
97  jsonAt.put("id", at.getId());
98  jsonAt.put("name", at.getName());
99  jsonAt.put("valueType", valueType.name());
100  jsonAt.put("multiplicity", at.getMultiplicity());
101  jsonAt.put("description", HTML.encodeTags(at.getDescription()));
102  jsonAt.put("removed", at.isRemoved());
103  jsonAt.put("protocolParameter", isProtocolParameter);
104
105  if (valueType == Type.STRING)
106  {
107    jsonAt.put("maxLength", at.getMaxLength());
108  }
109  else if (valueType == Type.INT || valueType == Type.LONG)
110  {
111    jsonAt.put("minValue", at.getMinValueLong());
112    jsonAt.put("maxValue", at.getMaxValueLong());
113  }
114  else if (valueType == Type.FLOAT || valueType == Type.DOUBLE)
115  {
116    jsonAt.put("minValue", at.getMinValueDouble());
117    jsonAt.put("maxValue", at.getMaxValueDouble());
118  }
119 
120  // Enumeration
121  if (at.isEnumeration())
122  {
123    List<?> values = at.getValues();
124    JSONArray jsonEnum = new JSONArray();
125    for (Object val : values)
126    {
127      jsonEnum.add(formatter.format(val));
128    }
129    jsonAt.put("enumeration", jsonEnum);
130    jsonAt.put("displayAsList", at.getDisplayAsList());
131  }
132 
133  // Units
134  if (at.supportUnits())
135  {
136    Unit defaultUnit = at.getDefaultUnit();
137    jsonAt.put("defaultUnit", defaultUnit.getId());
138    jsonAt.put("defaultSymbol", defaultUnit.getDisplaySymbol());
139   
140    if (!at.isEnumeration())
141    {
142      ItemQuery<Unit> unitQuery = at.getUsableUnits();
143      if (unitQuery.count(dc) == 0)
144      {
145        unitQuery = at.getQuantity().getUnits();
146      }
147      else
148      {
149        unitQuery.reset();
150      }
151      unitQuery.order(Orders.desc(Hql.property("referenceFactor")));
152      unitQuery.order(Orders.asc(Hql.property("displaySymbol")));
153      List<Unit> units = new ArrayList<Unit>(unitQuery.list(dc));
154      if (!units.contains(defaultUnit)) units.add(defaultUnit);
155     
156      Unit currentUnit = a != null ? a.getUnit() : null;
157      if (currentUnit != null && !units.contains(currentUnit)) units.add(currentUnit);
158     
159      JSONArray jsonUnits = new JSONArray();
160      for (Unit unit : units)
161      {
162        JSONObject jsonUnit = new JSONObject();
163        jsonUnit.put("id", unit.getId());
164        jsonUnit.put("description", HTML.encodeTags(unit.getName() + " - " + unit.getDescription()));
165        jsonUnit.put("symbol", HTML.encodeTags(unit.getDisplaySymbol()));
166        jsonUnits.add(jsonUnit);
167      }
168      jsonAt.put("units", jsonUnits);
169    }
170  }
171 
172  // Categories
173  JSONArray jsonCategories = new JSONArray();
174  ItemQuery<AnnotationTypeCategory> categoryQuery = at.getCategories();
175  categoryQuery.include(Include.MINE, Include.OTHERS, Include.SHARED, Include.IN_PROJECT);
176  categoryQuery.join(Hql.innerJoin("annotationTypes", "atp"));
177  categoryQuery.restrict(Restrictions.eq(Hql.alias("atp"), Hql.entity(at)));
178  for (AnnotationTypeCategory category : categoryQuery.list(dc))
179  {
180    allCategories.add(category);
181    jsonCategories.add(category.getId());
182  }
183  jsonAt.put("categories", jsonCategories);
184
185 
186  if (a != null)
187  {
188    createJSON(jsonA, dc, a, formatter, false);
189   
190    if (a.getSource() != Annotation.Source.PRIMARY)
191    {
192      Annotation inherited = a.getInheritedFrom();
193      if (inherited != null)
194      {
195        JSONObject jsonInherited = new JSONObject();
196        createJSON(jsonInherited, dc, inherited, formatter, true);
197        Annotatable inheritedFrom = inherited.getAnnotationSet().getItem(dc);
198        JSONObject jsonFrom = new JSONObject();
199        jsonFrom.put("id", inheritedFrom.getId());
200        jsonFrom.put("name", ((Nameable)inheritedFrom).getName());
201        jsonFrom.put("type", inheritedFrom.getType().name());
202        jsonInherited.put("from", jsonFrom);
203        json.put("inherited", jsonInherited);
204      }
205    }
206
207  }
208
209  return json;
210}
211
212private void createJSON(JSONObject json, DbControl dc, Annotation a, Formatter formatter, boolean formatAll)
213{
214  json.put("id", a.getId());
215  Date lastUpdate = a.getLastUpdate();
216  if (lastUpdate != null) json.put("lastUpdate",  lastUpdate.getTime());
217 
218  Unit currentUnit = a.getUnit();
219  if (currentUnit != null) 
220  {
221    json.put("unit", currentUnit.getId());
222    json.put("unitSymbol", currentUnit.getDisplaySymbol());
223  }
224 
225  // Populate the values array
226  List values = a.getValues(null);
227  if (values != null)
228  {
229    JSONArray jsonValues = new JSONArray();
230    json.put("values", jsonValues);
231   
232    for (Object value : values)
233    {
234      // Dates should be formatted to strings using the current date(time) format
235      if (formatAll || value instanceof Date) 
236      {
237        value = formatter.format(value);
238      }
239      jsonValues.add(value.toString());
240    }
241  }
242 
243}
244
245%>
246<%
247final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
248final String ID = sc.getId();
249final float scale = Base.getScale(sc);
250final Item itemType = Item.valueOf(request.getParameter("item_type"));
251final int itemId = Values.getInt(request.getParameter("item_id"));
252final int protocolId = Values.getInt(request.getParameter("protocol_id"), -1);
253final int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1);
254final int annotationId = Values.getInt(request.getParameter("annotation_id"));
255int annotationTypeId = Values.getInt(request.getParameter("annotationtype_id"));
256final boolean standalone = Values.getBoolean(request.getParameter("standalone"));
257
258final DbControl dc = sc.newDbControl();
259try
260{
261  // Date and time formats
262  String dateFormat = FormatterSettings.getDateFormat(sc);
263  String htmlDateFormat = HTML.encodeTags(dateFormat);
264  String dateTimeFormat = FormatterSettings.getDateTimeFormat(sc);
265  String htmlDateTimeFormat = HTML.encodeTags(dateTimeFormat);
266 
267  Annotatable item = null;
268 
269  if (annotationId != 0)
270  {
271    Annotation a = Annotation.getById(dc, annotationId);
272    item = a.getAnnotationSet().getItem();
273    annotationTypeId = a.getAnnotationType().getId();
274  }
275  else if (itemId != 0)
276  {
277    item = (Annotatable)itemType.getById(dc, itemId);
278  }
279  final boolean writePermission = item == null ? true : item.hasPermission(Permission.WRITE);
280 
281  // Load the current item and it's protocol
282  // NOTE! User may have selected a different protocol in the form than what is
283  // currently saved so if a protocol_id is sent in the request we use that
284  Protocol protocol = null;
285  boolean readProtocol = true;
286  try
287  {
288    if (protocolId == - 1 && item != null)
289    {
290      protocol = item.getProtocol();
291    }
292    else if (protocolId > 0)
293    {
294      protocol = Protocol.getById(dc, protocolId);
295    }
296  }
297  catch (PermissionDeniedException ex)
298  {
299    readProtocol = false;
300  }
301 
302  // Load the current subtype
303  // NOTE! User may have selected a different subtype in the form than what is
304  // currently saved so if a subtype_id is sent in the request we use that
305  String selectedCategoryName = null;
306  try
307  {
308    ItemSubtype subtype = null;
309    if (subtypeId > 0)
310    {
311      subtype = ItemSubtype.getById(dc, subtypeId);
312    }
313    else if (item instanceof Subtypable)
314    {
315      subtype = ((Subtypable)item).getItemSubtype();
316    }
317    else if (item instanceof BioPlate)
318    {
319      BioPlateType bpt = ((BioPlate)item).getBioPlateType();
320      subtype = bpt.getItemSubtype();
321      if (subtype == null) selectedCategoryName = bpt.getName();
322    }
323    if (subtype != null) selectedCategoryName = subtype.getName();
324  }
325  catch (PermissionDeniedException ex)
326  {}
327 
328  //selectedCategoryName = "Test"; // DEBUG!!
329 
330  if (standalone)
331  {
332    sc.getCurrentContext(itemType).setObject("item", item); 
333  }
334
335  String title = "Annotate " + 
336    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() : 
337      (item == null ? " new item" : item.toString())));
338
339  // Queries to retrieve annotation types and protocol parameters
340  ItemQuery<AnnotationType> annotationTypeQuery = null;
341  String message = null;
342  if (item instanceof AnnotatableProxy)
343  {
344    AnnotatableProxy proxy = (AnnotatableProxy)item;
345    annotationTypeQuery = Base.getAnnotationTypesQuery(proxy);
346    message = proxy.getAnnotationMessage();
347  }
348  else
349  {
350    annotationTypeQuery = Base.getAnnotationTypesQuery(itemType, false);
351  }
352  final ItemQuery<AnnotationType> parameterQuery = Base.getProtocolParametersQuery(protocol);
353
354  // Holds all categories that we have found
355  final Set<AnnotationTypeCategory> allCategories = 
356    new TreeSet<AnnotationTypeCategory>(new NameableComparator(false));
357 
358  // Load existing annotations
359  AnnotationSet as = null;
360  Map<AnnotationType, Annotation> primary = new HashMap<AnnotationType, Annotation>();
361  List<Annotation> inherited = new ArrayList<Annotation>();
362  if (item != null && item.isAnnotated())
363  {
364    // Load the existing annotations
365    as = item.getAnnotationSet();
366    ItemQuery<Annotation> aQuery = as.getAnnotations(null);
367    aQuery.order(Orders.asc(Hql.property("annotationType.name")));
368    List<Annotation> annotations = aQuery.list(dc);
369    for (Annotation a : annotations)
370    {
371      try
372      {
373        if (a.getSource() == Annotation.Source.PRIMARY)
374        {
375          primary.put(a.getAnnotationType(), a);
376        }
377        else
378        {
379          inherited.add(a);
380        }
381      }
382      catch (PermissionDeniedException ex)
383      {}
384    }
385  }
386 
387  // Load all annotation types that available from multiple sources:
388  // * As defined by the server admin for the current item type
389  // * Existing on the current item
390  // * Defined as protocol parameters for the current protocol
391  Set<AnnotationType> annotationTypes = new TreeSet<AnnotationType>(new NameableComparator(false));
392  Set<AnnotationType> protocolParameters = new HashSet<AnnotationType>();
393  annotationTypes.addAll(annotationTypeQuery.list(dc));
394  annotationTypes.addAll(primary.keySet());
395  if (parameterQuery != null) 
396  {
397    protocolParameters.addAll(parameterQuery.list(dc));
398    annotationTypes.addAll(protocolParameters);
399  }
400
401  // Build JSON objects for all annotation types, the current values and annotation type categories
402  JSONArray jsonAnnotations = new JSONArray();
403  for (AnnotationType at : annotationTypes)
404  {
405    Annotation a = primary.get(at);
406    if (at.isRemoved() && a == null) continue;
407    JSONObject json = makeJSON(dc, at, a, protocolParameters.contains(at), allCategories);
408    jsonAnnotations.add(json);
409  }
410  for (Annotation a : inherited)
411  {
412    AnnotationType at = a.getAnnotationType();
413    JSONObject json = makeJSON(dc, at, a, false, allCategories);
414    jsonAnnotations.add(json);
415  }
416  %>
417  <base:page type="<%=standalone ? "popup" : "iframe"%>" title="<%=title%>">
418  <base:head scripts="~annotate.js" styles="parameters.css,toolbar.css">
419  <style>
420  .first-primary:before
421  {
422    content: '― Primary Annotations ―';
423    font-variant: small-caps;
424    font-size: 80%;
425    font-weight: bold;
426    color: #999999;
427  }
428 
429  .first-inherited:before
430  {
431    content: '― Inherited & Cloned ―';
432    font-variant: small-caps;
433    font-size: 80%;
434    font-weight: bold;
435    color: #999999;
436  }
437 
438 
439  .parameterlist .param
440  {
441    padding-right: 20px;
442  }
443  .parameterlist .param.selected
444  {
445    padding-right: 20px;
446  }
447  .parameterlist .param:hover
448  {
449    padding-right: 18px;
450  }
451 
452  .parameterlist .param input
453  {
454    position: absolute;
455    right: 1px;
456    margin-top: 1px;
457  }
458 
459  #selected-name
460  {
461    font-weight: bold;
462  }
463 
464  #selected-description
465  {
466    margin-left: 0px;
467    margin-right: 0px;
468    display: none;
469  }
470 
471  #none-selected
472  {
473    display: none;
474    margin-top: 2em;
475  }
476 
477  #selected-container > div
478  {
479    display: none;
480  }
481 
482  #selected-container.none-selected #none-selected
483  {
484    display: block;
485  }
486  #selected-container.none-selected.no-annotations #none-selected
487  {
488    display: none;
489  }
490 
491  #selected-container.has-selected #info-container
492  {
493    display: block;
494  }
495 
496  #selected-container.has-description #selected-description
497  {
498    display: block;
499  }
500
501  #selected-container.INHERITED #inherited-container,
502  #selected-container.CLONED #inherited-container
503  {
504    display: block;
505    border-left-width: 2px;
506    padding: 2px 5px;
507    margin: 0.5em 0;
508  }
509
510  #selected-container.inherited-missing #inherited-missing
511  {
512    display: block;
513    border-left-width: 2px;
514    padding: 2px 5px;
515    margin: 0.5em 0;
516  }
517  #selected-container.inherited-missing #inherited-container
518  {
519    display: none;
520  }
521 
522  #inherited-item
523  {
524    font-style: italic;
525  }
526 
527  #inherited-modified, #inherited-clone
528  {
529    display: none;
530  }
531
532  #selected-container.modified #inherited-modified
533  {
534    display: inline;
535  }
536 
537  #selected-container.INHERITED #inherited-clone
538  {
539    display: inline;
540  }
541 
542  #selected-container.PRIMARY #input-container,
543  #selected-container.CLONED #input-container
544  {
545    display: block;
546  }
547 
548  #input-container > div
549  {
550    display: none;
551  }
552 
553  #selected-container.ENUM-SINGLE #ENUM-SINGLE
554  {
555    display: block;
556  }
557  #selected-container.ENUM-MULTIPLE #ENUM-MULTIPLE
558  {
559    display: block;
560  }
561  #selected-container.ENUM-RADIO-CHECKBOX #ENUM-RADIO-CHECKBOX
562  {
563    display: block;
564  }
565  #selected-container.STRING #STRING-container
566  {
567    display: block;
568  }
569  #selected-container.TEXT #TEXT-container
570  {
571    display: block;
572  }
573  #selected-container.INT #INT-container
574  {
575    display: block;
576  }
577  #selected-container.LONG #LONG-container
578  {
579    display: block;
580  }
581  #selected-container.FLOAT #FLOAT-container
582  {
583    display: block;
584  }
585  #selected-container.DOUBLE #DOUBLE-container
586  {
587    display: block;
588  }
589  #selected-container.BOOLEAN #BOOLEAN-container
590  {
591    display: block;
592  }
593  #selected-container.DATE #DATE-container
594  {
595    display: block;
596  }
597  #selected-container.TIMESTAMP #TIMESTAMP-container
598  {
599    display: block;
600  }
601  #selected-container.has-unit .numeric
602  {
603    float: left;
604    margin-right: 0.25em;
605  }
606  #selected-container.has-unit #unit-container
607  {
608    display: block;
609  }
610  .not-specified
611  {
612    font-style: italic;
613  }
614  </style>
615  </base:head>
616  <base:body>
617    <%
618    if (standalone)
619    {
620      %>
621      <h1><%=title%> <base:help helpid="annotations.edit" /></h1>
622      <div class="content">
623      <%
624    }
625    %>
626    <div id="page-data" class="datacontainer"
627      data-annotations="<%=HTML.encodeTags(jsonAnnotations.toJSONString()) %>"
628      data-annotation-type-id="<%=annotationTypeId%>"
629      data-annotation-id="<%=annotationId %>"
630      data-date-format="<%=htmlDateFormat%>"
631      data-datetime-format="<%=htmlDateTimeFormat%>"
632      ></div>
633    <form name="annotations">
634   
635    <div class="absolutefull">
636      <div class="absolutefull bg-filled-100 rightborder" style="width: 18em;">
637        <div class="absolutefull" style="height: 2em;">
638          <table style="margin: auto; height: 100%;"><tr><td>
639          <select name="categories" id="categories" style="width: 17em;">
640          <option value="-1">- all -
641          <%
642          if (protocol != null)
643          {
644            %>
645            <option value="-2">- protocol parameters -
646            <%
647          }
648          %>
649          <option value="0">- uncategorized -
650          <%
651          for (AnnotationTypeCategory category : allCategories)
652          {
653            boolean selected = category.getName().equals(selectedCategoryName);
654            %>
655            <option value="<%=category.getId()%>"
656              title="<%=HTML.encodeTags(category.getDescription())%>"
657              <%=selected ? "selected" : "" %>
658            ><%=HTML.encodeTags(category.getName())%>
659            <%
660          }
661          %>
662          </select>
663          </td></tr></table>
664        </div>
665       
666        <div id="annotation-list" class="absolutefull parameterlist topborder" 
667          style="top: 2em; bottom: 6em;">
668          <div class="first-primary"></div>
669          <%
670          if (annotationTypes.size() == 0 && inherited.size() == 0)
671          {
672            %>
673            <div class="messagecontainer error">
674              There are no annotation types defined for this kind of item.
675            </div>
676            <%
677          }
678          %>
679        </div>
680        <div class="absolutefull topborder" style="top: auto; bottom: 0em; height: 7em;">
681          <tbl:toolbar subclass="bottomborder">
682            <tbl:button id="btnDelete" title="Delete" image="remove.png" />
683            <tbl:button id="btnAdd" title="Add" image="add.png" />
684          </tbl:toolbar>
685          <tbl:toolbar subclass="bottomborder">
686            <tbl:button id="btnSync" title="Sync" image="refresh.png" />
687            <tbl:button id="btnClone" title="Clone" image="copy.png" />
688            <tbl:button id="btnDeclone" title="De-clone" />
689          </tbl:toolbar>
690          <table style="height: 3em; margin:auto;"><tr><td>
691          <base:icon image="hasvalues.png" /> = has value(s)<br>
692          <base:icon image="parameter.png" /> = protocol parameter
693          </td></tr></table>
694        </div>
695      </div>
696     
697      <div class="absolutefull input100" style="left: 18em; padding: 8px;">
698        <%
699        if (message != null)
700        {
701          %>
702          <div class="messagecontainer help" style="margin-top: 0.2em;"><%=message%></div>
703          <%
704        }
705        if (!writePermission)
706        {
707          %>
708          <div class="messagecontainer error">You do not have permission to change this information</div>
709          <%
710        }
711        %>
712        <div id="valuecontainer" style="display: none;">
713          <b>Values</b> <span id="multiplicity"></span><br>
714          <select name="multi-values" id="multi-values" size="5" style="width: 100%;">
715          </select>
716          <table>
717          <tr>
718            <td><base:button id="btnMultiAdd" title="Add" tooltip="Add a new value" /></td>
719            <td><base:button id="btnMultiRemove" title="Remove" tooltip="Remove the selected values"/></td>
720          </tr>
721          </table>
722        <br>
723        </div>
724       
725        <div id="selected-container">
726          <div id="none-selected" class="messagecontainer note">
727            <base:icon image="goback.png" /> Select an annotation.
728          </div>
729
730          <div id="info-container">
731            <span id="selected-name">Name</span>
732            (<span id="selected-type">type</span>)
733          </div>
734         
735          <div id="inherited-container" class="bg-filled-100">
736            <span id="inherited-item"></span><br>
737            <span id="inherited-values"></span>
738            <span id="inherited-modified">(modified; <span id="sync-modified" class="link" title="Synchronize the annotation values with the parent item">sync</span>)</span>
739            <span id="inherited-clone">(<span id="convert-to-cloned" class="link" title="Clone the annotation values from the parent">clone</span>)</span>
740          </div>
741                   
742          <div id="inherited-missing" class="bg-filled-100">
743            Cloned from an unknown item.
744          </div>
745       
746          <div id="input-container">
747         
748            <div id="ENUM-SINGLE">
749              <select name="ENUM-SINGLE-input" id="ENUM-SINGLE-input" 
750                style="min-width: 5em;">
751              </select>
752            </div>
753             
754            <div id="ENUM-MULTIPLE">
755              <select name="ENUM-MULTIPLE-input" id="ENUM-MULTIPLE-input" 
756                multiple size="10" style="min-width: 5em;">
757              </select>
758            </div>
759             
760            <div id="ENUM-RADIO-CHECKBOX">
761              radios/checkboxes
762            </div>
763       
764            <div id="STRING-container">
765              <input name="STRING-input" id="STRING-input" 
766                type="text" class="text"
767                maxlength="255" value="">
768            </div>
769           
770            <div id="TEXT-container">
771              <table style="width: 100%;">
772              <tr>
773                <td>
774                <textarea name="TEXT-input" id="TEXT-input" 
775                  class="text" rows="5"></textarea>
776                </td>
777                <td style="width: 20px;">
778                  <base:icon
779                    id="TEXT-zoom"
780                    image="zoom.png"
781                    tooltip="Edit in larger window" 
782                  />
783                </td>
784              </tr>
785              </table>
786            </div>
787           
788            <div id="INT-container" class="numeric">
789              <input 
790                name="INT-input" id="INT-input"
791                class="text" type="text" 
792                value="" style="width: 12em;" maxlength="20">
793            </div>
794
795            <div id="LONG-container" class="numeric">
796              <input 
797                name="LONG-input" id="LONG-input"
798                class="text" type="text" 
799                value="" style="width: 12em;" maxlength="20">
800            </div>
801           
802            <div id="FLOAT-container" class="numeric">
803              <input 
804                name="FLOAT-input" id="FLOAT-input"
805                class="text" type="text"
806                value="" style="width: 12em;" maxlength="20">
807            </div>
808
809            <div id="DOUBLE-container" class="numeric">
810              <input 
811                name="DOUBLE-input" id="DOUBLE-input"
812                class="text" type="text" 
813                value="" style="width: 12em;" maxlength="20">
814            </div>
815         
816            <div id="unit-container">
817              <select name="unit" id="unit" style="min-width: 5em;"></select>
818            </div>
819           
820            <div id="DATE-container">
821              <table>
822              <tr>
823              <td>
824                <input 
825                  name="DATE-input" id="DATE-input"
826                  class="text" type="text" 
827                  value="" style="width: 15em;" maxlength="20" 
828                  title="Enter date in format: <%=htmlDateFormat%>">
829              </td>
830              <td>
831                <base:button 
832                  id="DATE-calendar"
833                  image="calendar.png"
834                  title="Calendar&hellip;" 
835                  tooltip="Select a date from a calendar"
836                />
837              </td>
838              </tr>
839              </table>
840            </div>
841           
842            <div id="TIMESTAMP-container">
843              <table>
844              <tr>
845              <td>
846                <input 
847                  name="TIMESTAMP-input" id="TIMESTAMP-input"
848                  class="text" type="text" 
849                  value="" style="width: 15em;" maxlength="20" 
850                  title="Enter date + time in format: <%=htmlDateTimeFormat%>">
851              </td>
852              <td>
853                <base:button 
854                  id="TIMESTAMP-calendar"
855                  image="calendar.png"
856                  title="Calendar&hellip;" 
857                  tooltip="Select date and time from a calendar"
858                />
859              </td>
860              </tr>
861              </table>
862            </div>
863         
864            <div id="BOOLEAN-container">
865              <label class="not-specified"><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-NULL" 
866                value="" checked>- not specified -</label><br>
867              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-TRUE" 
868                value="true">true</label><br>
869              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-FALSE"
870                value="false">false</label>
871            </div>
872          </div>
873         
874          <div id="selected-description" class="messagecontainer help">
875          </div>
876        </div>
877 
878      </div>
879    </div>
880    </form>
881    <%
882    if (standalone)
883    {
884      %>
885      </div>
886      <base:buttongroup subclass="dialogbuttons topborder">
887        <base:button id="btnSave" title="Save" visible="<%=writePermission%>" />
888        <base:button id="close" title="Cancel"  visible="<%=writePermission%>" />
889        <base:button id="close" title="Close" visible="<%=!writePermission%>" />
890      </base:buttongroup>
891      <form name="modified" method="post" action="index.jsp?ID=<%=ID%>">
892        <input type="hidden" name="cmd" value="SaveAnnotations">
893        <input type="hidden" name="item_type" value="<%=itemType.name()%>">
894        <input type="hidden" name="item_id" value="<%=itemId%>">
895      </form>
896      <%
897    }
898    %>
899  </base:body>
900  </base:page>
901  <%
902}
903finally
904{
905  if (dc != null) dc.close();
906}
907%>
Note: See TracBrowser for help on using the repository browser.