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

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

References #2033: Permissions for annotating items may be incorrectly implemented

Changes in the web interface (Annotations tab) so that the "edit" icon is only visible if the user has permission to modify or create an annotation.

The edit dialog will still list all annotations but editing is disabled for read-only annotations.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 22.5 KB
Line 
1<%-- $Id: annotate.jsp 7206 2016-10-19 08:25:47Z 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.clients.web.AnnotationUtil"
63  import="net.sf.basedb.util.Values"
64  import="org.json.simple.JSONObject"
65  import="org.json.simple.JSONArray"
66  import="java.util.ArrayList"
67  import="java.util.List"
68  import="java.util.Date"
69  import="java.util.Set"
70  import="java.util.HashSet"
71  import="java.util.TreeSet"
72  import="java.util.Map"
73  import="java.util.HashMap"
74%>
75<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
76<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
77<%@ taglib prefix="m" uri="/WEB-INF/menu.tld" %>
78<%
79final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
80final String ID = sc.getId();
81final float scale = Base.getScale(sc);
82final Item itemType = Item.valueOf(request.getParameter("item_type"));
83final int itemId = Values.getInt(request.getParameter("item_id"));
84final int protocolId = Values.getInt(request.getParameter("protocol_id"), -1);
85final int subtypeId = Values.getInt(request.getParameter("subtype_id"), -1);
86final int annotationId = Values.getInt(request.getParameter("annotation_id"));
87int annotationTypeId = Values.getInt(request.getParameter("annotationtype_id"));
88final boolean standalone = Values.getBoolean(request.getParameter("standalone"));
89
90// Parent items may have been submitted by caller
91// Each parameter is ITEMTYPE:ID:ID:...
92String[] parents = request.getParameterValues("parents");
93
94final DbControl dc = sc.newDbControl();
95try
96{
97  // Date and time formats
98  String dateFormat = FormatterSettings.getDateFormat(sc);
99  String htmlDateFormat = HTML.encodeTags(dateFormat);
100  String dateTimeFormat = FormatterSettings.getDateTimeFormat(sc);
101  String htmlDateTimeFormat = HTML.encodeTags(dateTimeFormat);
102 
103  Annotatable item = null;
104 
105  if (annotationId != 0)
106  {
107    Annotation a = Annotation.getById(dc, annotationId);
108    item = a.getAnnotationSet().getItem();
109    annotationTypeId = a.getAnnotationType().getId();
110  }
111  else if (itemId != 0)
112  {
113    item = (Annotatable)itemType.getById(dc, itemId);
114  }
115  final boolean writePermission = item == null ? true : item.hasPermission(Permission.WRITE);
116 
117  // Load the current item and it's protocol
118  // NOTE! User may have selected a different protocol in the form than what is
119  // currently saved so if a protocol_id is sent in the request we use that
120  Protocol protocol = null;
121  boolean readProtocol = true;
122  try
123  {
124    if (protocolId == - 1 && item != null)
125    {
126      protocol = item.getProtocol();
127    }
128    else if (protocolId > 0)
129    {
130      protocol = Protocol.getById(dc, protocolId);
131    }
132  }
133  catch (PermissionDeniedException ex)
134  {
135    readProtocol = false;
136  }
137 
138  // Load the current subtype
139  // NOTE! User may have selected a different subtype in the form than what is
140  // currently saved so if a subtype_id is sent in the request we use that
141  String selectedCategoryName = null;
142  try
143  {
144    ItemSubtype subtype = null;
145    if (subtypeId > 0)
146    {
147      subtype = ItemSubtype.getById(dc, subtypeId);
148    }
149    else if (item instanceof Subtypable)
150    {
151      subtype = ((Subtypable)item).getItemSubtype();
152    }
153    else if (item instanceof BioPlate)
154    {
155      BioPlateType bpt = ((BioPlate)item).getBioPlateType();
156      subtype = bpt.getItemSubtype();
157      if (subtype == null) selectedCategoryName = bpt.getName();
158    }
159    if (subtype != null) selectedCategoryName = subtype.getName();
160  }
161  catch (PermissionDeniedException ex)
162  {}
163 
164  //selectedCategoryName = "Test"; // DEBUG!!
165 
166  if (standalone)
167  {
168    sc.getCurrentContext(itemType).setObject("item", item); 
169  }
170
171  String title = "Annotate " + 
172    HTML.encodeTags((item instanceof Nameable ? ((Nameable)item).getName() : 
173      (item == null ? " new item" : item.toString())));
174
175  // Queries to retrieve annotation types and protocol parameters
176  ItemQuery<AnnotationType> annotationTypeQuery = null;
177  String message = null;
178  if (item instanceof AnnotatableProxy)
179  {
180    AnnotatableProxy proxy = (AnnotatableProxy)item;
181    annotationTypeQuery = Base.getAnnotationTypesQuery(proxy);
182    message = proxy.getAnnotationMessage();
183  }
184  else
185  {
186    annotationTypeQuery = Base.getAnnotationTypesQuery(itemType, false);
187  }
188  final ItemQuery<AnnotationType> parameterQuery = Base.getProtocolParametersQuery(protocol);
189
190  // Holds all categories that we have found
191  final Set<AnnotationTypeCategory> allCategories = 
192    new TreeSet<AnnotationTypeCategory>(new NameableComparator(false));
193 
194  // Load existing annotations
195  AnnotationSet as = null;
196  Map<AnnotationType, Annotation> primary = new HashMap<AnnotationType, Annotation>();
197  List<Annotation> inherited = new ArrayList<Annotation>();
198  if (item != null && item.isAnnotated())
199  {
200    // Load the existing annotations
201    as = item.getAnnotationSet();
202    ItemQuery<Annotation> aQuery = as.getAnnotations(null);
203    aQuery.order(Orders.asc(Hql.property("annotationType.name")));
204    List<Annotation> annotations = aQuery.list(dc);
205    for (Annotation a : annotations)
206    {
207      try
208      {
209        if (a.getSource() == Annotation.Source.PRIMARY)
210        {
211          primary.put(a.getAnnotationType(), a);
212        }
213        else
214        {
215          inherited.add(a);
216        }
217      }
218      catch (PermissionDeniedException ex)
219      {}
220    }
221  }
222 
223  // Load all annotation types that available from multiple sources:
224  // * As defined by the server admin for the current item type
225  // * Existing on the current item
226  // * Defined as protocol parameters for the current protocol
227  Set<AnnotationType> annotationTypes = new TreeSet<AnnotationType>(new NameableComparator(false));
228  Set<AnnotationType> protocolParameters = new HashSet<AnnotationType>();
229  annotationTypes.addAll(annotationTypeQuery.list(dc));
230  annotationTypes.addAll(primary.keySet());
231  if (parameterQuery != null) 
232  {
233    protocolParameters.addAll(parameterQuery.list(dc));
234    annotationTypes.addAll(protocolParameters);
235  }
236
237  // Build JSON objects for all annotation types, the current values and annotation type categories
238  JSONArray jsonAnnotations = new JSONArray();
239  for (AnnotationType at : annotationTypes)
240  {
241    Annotation a = primary.get(at);
242    if (at.isRemoved() && a == null) continue;
243    JSONObject json = AnnotationUtil.createJsonForAnnotationTypeAndAnnotation(dc, at, a, null, protocolParameters.contains(at), allCategories);
244    jsonAnnotations.add(json);
245  }
246  for (Annotation a : inherited)
247  {
248    AnnotationType at = a.getAnnotationType();
249    JSONObject json = AnnotationUtil.createJsonForAnnotationTypeAndAnnotation(dc, at, a, null, false, allCategories);
250    jsonAnnotations.add(json);
251  }
252 
253  // Build JSON for parents submitted via request parameter
254  JSONArray jsonParents = new JSONArray();
255  if (parents != null)
256  {
257    for (String p : parents) jsonParents.add(p);
258  }
259  boolean canInherit = jsonParents.size() > 0;
260  if (!canInherit && item != null)
261  {
262    Set<Annotatable> parentItems = item.getAnnotatableParents();
263    canInherit = parentItems != null && parentItems.size() > 0;
264  }
265  %>
266  <base:page type="<%=standalone ? "popup" : "iframe"%>" title="<%=title%>">
267  <base:head scripts="~annotate.js,menu.js" styles="parameters.css,toolbar.css,menu.css">
268  <style>
269  .first-primary:before
270  {
271    content: '― Primary Annotations ―';
272    font-variant: small-caps;
273    font-size: 80%;
274    font-weight: bold;
275    color: #999999;
276  }
277 
278  .first-inherited:before
279  {
280    content: '― Inherited & Cloned ―';
281    font-variant: small-caps;
282    font-size: 80%;
283    font-weight: bold;
284    color: #999999;
285  }
286 
287 
288  .parameterlist .param
289  {
290    padding-right: 20px;
291  }
292  .parameterlist .param.selected
293  {
294    padding-right: 20px;
295  }
296  .parameterlist .param:hover
297  {
298    padding-right: 18px;
299  }
300 
301  .parameterlist .param input, .parameterlist .check-all
302  {
303    position: absolute;
304    right: 1px;
305    margin-top: 1px;
306  }
307  .parameterlist .check-all
308  {
309    padding-right: 2px;
310  }
311 
312  #selected-name
313  {
314    font-weight: bold;
315  }
316 
317  #selected-description
318  {
319    margin-left: 0px;
320    margin-right: 0px;
321    display: none;
322  }
323 
324  #none-selected
325  {
326    display: none;
327    margin-top: 2em;
328  }
329 
330  #selected-container > div
331  {
332    display: none;
333  }
334 
335  #selected-container.none-selected #none-selected
336  {
337    display: block;
338  }
339  #selected-container.none-selected.no-annotations #none-selected
340  {
341    display: none;
342  }
343 
344  #selected-container.has-selected #info-container
345  {
346    display: block;
347  }
348 
349  #selected-container.has-description #selected-description
350  {
351    display: block;
352  }
353
354  #selected-container.INHERITED #inherited-container,
355  #selected-container.CLONED #inherited-container
356  {
357    display: block;
358    border-left-width: 2px;
359    padding: 2px 5px;
360    margin: 0.5em 0;
361  }
362
363  #selected-container.inherited-missing #inherited-missing
364  {
365    display: block;
366    border-left-width: 2px;
367    padding: 2px 5px;
368    margin: 0.5em 0;
369  }
370  #selected-container.inherited-missing #inherited-container
371  {
372    display: none;
373  }
374 
375  #inherited-item
376  {
377    font-style: italic;
378  }
379 
380  #inherited-modified, #inherited-clone
381  {
382    display: none;
383  }
384
385  #selected-container.modified #inherited-modified
386  {
387    display: inline;
388  }
389 
390  #selected-container.INHERITED #inherited-clone
391  {
392    display: inline;
393  }
394 
395  #selected-container.PRIMARY #input-container,
396  #selected-container.CLONED #input-container
397  {
398    display: block;
399  }
400 
401  #input-container > div
402  {
403    display: none;
404  }
405 
406  #selected-container.ENUM-SINGLE #ENUM-SINGLE
407  {
408    display: block;
409  }
410  #selected-container.ENUM-MULTIPLE #ENUM-MULTIPLE
411  {
412    display: block;
413  }
414  #selected-container.ENUM-RADIO-CHECKBOX #ENUM-RADIO-CHECKBOX
415  {
416    display: block;
417  }
418  #selected-container.STRING #STRING-container
419  {
420    display: block;
421  }
422  #selected-container.TEXT #TEXT-container
423  {
424    display: block;
425  }
426  #selected-container.INT #INT-container
427  {
428    display: block;
429  }
430  #selected-container.LONG #LONG-container
431  {
432    display: block;
433  }
434  #selected-container.FLOAT #FLOAT-container
435  {
436    display: block;
437  }
438  #selected-container.DOUBLE #DOUBLE-container
439  {
440    display: block;
441  }
442  #selected-container.BOOLEAN #BOOLEAN-container
443  {
444    display: block;
445  }
446  #selected-container.DATE #DATE-container
447  {
448    display: block;
449  }
450  #selected-container.TIMESTAMP #TIMESTAMP-container
451  {
452    display: block;
453  }
454  #selected-container.has-unit .numeric
455  {
456    float: left;
457    margin-right: 0.25em;
458  }
459  #selected-container.has-unit #unit-container
460  {
461    display: block;
462  }
463  #selected-container.multiple #multiple-container
464  {
465    display: block;
466  }
467 
468  #selected-container.no-annotate-permission #input-container
469  {
470    pointer-events: none;
471    cursor: default;
472    opacity: 0.5;
473    filter: url(filters.svg#grayscale);
474  }
475  #selected-container.no-annotate-permission #no-annotate-permission
476  {
477    display: block;
478  }
479  .not-specified
480  {
481    font-style: italic;
482  }
483  </style>
484  </base:head>
485  <base:body>
486    <%
487    if (standalone)
488    {
489      %>
490      <h1><%=title%> <base:help helpid="annotations.edit" /></h1>
491      <div class="content">
492      <%
493    }
494    %>
495    <div id="page-data" class="datacontainer"
496      data-item-type="<%=itemType.name() %>"
497      data-item-id="<%=itemId %>"
498      data-annotations="<%=HTML.encodeTags(jsonAnnotations.toJSONString()) %>"
499      data-parents="<%=HTML.encodeTags(jsonParents.toJSONString()) %>"
500      data-annotation-type-id="<%=annotationTypeId%>"
501      data-annotation-id="<%=annotationId %>"
502      data-date-format="<%=htmlDateFormat%>"
503      data-datetime-format="<%=htmlDateTimeFormat%>"
504      ></div>
505    <form name="annotations">
506   
507    <m:menu
508      id="more-actions"
509      style="display: none;"> 
510      <m:menuitem id="btnSync" title="Sync" icon="cloned-outofsync.png" 
511        tooltip="Synchronize the selected annotation"
512      />
513      <m:menuitem id="btnClone" title="Clone" icon="cloned.png" 
514        tooltip="Clone the selected annotations"
515      />
516      <m:menuitem id="btnUnclone" title="Unclone" icon="inherited.png" 
517        tooltip="Revert cloned annotations to inherited"
518      />
519    </m:menu>
520   
521   
522    <div class="absolutefull">
523      <div class="absolutefull bg-filled-100 rightborder" style="width: 18em;">
524        <div class="absolutefull" style="height: 2em;">
525          <table style="margin: auto; height: 100%;"><tr><td>
526          <base:icon image="filter.png" />
527          <select name="categories" id="categories" style="width: 15em;">
528          <option value="-1">- all -
529          <%
530          if (protocol != null)
531          {
532            %>
533            <option value="-2">- protocol parameters -
534            <%
535          }
536          %>
537          <option value="0">- uncategorized -
538          <%
539          for (AnnotationTypeCategory category : allCategories)
540          {
541            boolean selected = category.getName().equals(selectedCategoryName);
542            %>
543            <option value="<%=category.getId()%>"
544              title="<%=HTML.encodeTags(category.getDescription())%>"
545              <%=selected ? "selected" : "" %>
546            ><%=HTML.encodeTags(category.getName())%>
547            <%
548          }
549          %>
550          </select>
551          </td></tr></table>
552        </div>
553       
554        <div id="annotation-list" class="absolutefull parameterlist topborder" 
555          style="top: 2em; bottom: 3em;">
556          <tbl:toolbar subclass="bottomborder" visible="<%=canInherit || annotationTypes.size()>0 || inherited.size()>0 %>">
557            <tbl:button id="btnAdd" title="Inherit&hellip;" image="add.png" 
558              tooltip="Inherit more annotations..."
559              disabled="<%=!canInherit%>"
560            />
561            <tbl:button id="btnDelete" title="Delete" image="remove.png" 
562              tooltip="Delete annotations"
563            />
564            <tbl:button id="btnMore" 
565              subclass="auto-init"
566              data-auto-init="menu-anchor"
567              data-menu-id="more-actions"
568              title="<img src=\"../../images/mini_scroll_down.png\">" image="menu.png"
569              tooltip="More actions..."
570              />
571          </tbl:toolbar>
572            <%
573            if (annotationTypes.size() == 0 && inherited.size() == 0)
574            {
575              %>
576              <div class="messagecontainer error">
577                There are no annotation types defined for this kind of item.
578              </div>
579              <%
580            }
581            %>
582          <div id="primary-list">
583            <div class="first-primary">
584              <base:icon id="check-all-primary" image="check_uncheck.png" subclass="check-all" 
585                tooltip="Toggle all (use CTRL, ALT or SHIFT to check/uncheck)"
586              />
587            </div>
588          </div>
589          <div id="inherited-list">
590            <div class="first-inherited">
591              <base:icon id="check-all-inherited" image="check_uncheck.png" subclass="check-all" 
592                tooltip="Toggle all (use CTRL, ALT or SHIFT to check/uncheck)"
593              />
594            </div>
595          </div>
596        </div>
597       
598        <div class="absolutefull topborder" style="top: auto; bottom: 0em; height: 3em;">
599          <table style="height: 100%; margin:auto;"><tr><td>
600          <base:icon image="hasvalues.png" /> = has value(s)<br>
601          <base:icon image="parameter.png" /> = protocol parameter
602          </td></tr></table>
603        </div>
604      </div>
605     
606      <div class="absolutefull input100" style="left: 18em; padding: 8px;">
607        <%
608        if (message != null)
609        {
610          %>
611          <div class="messagecontainer help" style="margin-top: 0.2em;"><%=message%></div>
612          <%
613        }
614        %>
615        <div id="selected-container">
616          <div id="none-selected" class="messagecontainer note">
617            <base:icon image="goback.png" /> Select an annotation.
618          </div>
619
620          <div id="no-annotate-permission" class="messagecontainer error">
621            You do not have permission to change this annotation.
622          </div>
623
624          <div id="info-container">
625            <span id="selected-name">Name</span>
626            (<span id="selected-type">type</span>)
627          </div>
628         
629          <div id="inherited-container" class="bg-filled-100">
630            <span id="inherited-item"></span><br>
631            <span id="inherited-values"></span>
632            <span id="inherited-modified">(modified; <span id="sync-modified" class="link" title="Synchronize the annotation values with the parent item">sync</span>)</span>
633            <span id="inherited-clone">(<span id="convert-to-cloned" class="link" title="Clone the annotation values from the parent">clone</span>)</span>
634          </div>
635                   
636          <div id="inherited-missing" class="bg-filled-100">
637            Cloned from an unknown item.
638          </div>
639       
640          <div id="input-container">
641            <div id="multiple-container">
642             
643              <select name="multi-values" id="multi-values" size="5" style="width: calc(100% - 8px);">
644              </select>
645              <table>
646              <tr>
647                <td><base:button id="btnMultiAdd" title="Add" tooltip="Add a new value" /></td>
648                <td><base:button id="btnMultiRemove" title="Remove" tooltip="Remove the selected values"/></td>
649              </tr>
650              </table>
651            </div>
652         
653            <div id="ENUM-SINGLE">
654              <select name="ENUM-SINGLE-input" id="ENUM-SINGLE-input" 
655                style="min-width: 15em;">
656              </select>
657            </div>
658             
659            <div id="ENUM-MULTIPLE">
660              <select name="ENUM-MULTIPLE-input" id="ENUM-MULTIPLE-input" 
661                multiple size="10" style="min-width: 15em;">
662              </select>
663            </div>
664             
665            <div id="ENUM-RADIO-CHECKBOX">
666              radios/checkboxes
667            </div>
668       
669            <div id="STRING-container">
670              <input name="STRING-input" id="STRING-input" 
671                type="text" class="text"
672                maxlength="255" value="">
673            </div>
674           
675            <div id="TEXT-container">
676              <table style="width: 100%;">
677              <tr>
678                <td>
679                <textarea name="TEXT-input" id="TEXT-input" 
680                  class="text" rows="5"></textarea>
681                </td>
682                <td style="width: 20px;">
683                  <base:icon
684                    id="TEXT-zoom"
685                    image="zoom.png"
686                    tooltip="Edit in larger window" 
687                  />
688                </td>
689              </tr>
690              </table>
691            </div>
692           
693            <div id="INT-container" class="numeric">
694              <input 
695                name="INT-input" id="INT-input"
696                class="text" type="text" 
697                value="" style="width: 12em;" maxlength="20">
698            </div>
699
700            <div id="LONG-container" class="numeric">
701              <input 
702                name="LONG-input" id="LONG-input"
703                class="text" type="text" 
704                value="" style="width: 12em;" maxlength="20">
705            </div>
706           
707            <div id="FLOAT-container" class="numeric">
708              <input 
709                name="FLOAT-input" id="FLOAT-input"
710                class="text" type="text"
711                value="" style="width: 12em;" maxlength="20">
712            </div>
713
714            <div id="DOUBLE-container" class="numeric">
715              <input 
716                name="DOUBLE-input" id="DOUBLE-input"
717                class="text" type="text" 
718                value="" style="width: 12em;" maxlength="20">
719            </div>
720         
721            <div id="unit-container">
722              <select name="unit" id="unit" style="min-width: 5em;"></select>
723            </div>
724           
725            <div id="DATE-container">
726              <table>
727              <tr>
728              <td>
729                <input 
730                  name="DATE-input" id="DATE-input"
731                  class="text" type="text" 
732                  value="" style="width: 15em;" maxlength="20" 
733                  title="Enter date in format: <%=htmlDateFormat%>">
734              </td>
735              <td>
736                <base:button 
737                  id="DATE-calendar"
738                  image="calendar.png"
739                  title="Calendar&hellip;" 
740                  tooltip="Select a date from a calendar"
741                />
742              </td>
743              </tr>
744              </table>
745            </div>
746           
747            <div id="TIMESTAMP-container">
748              <table>
749              <tr>
750              <td>
751                <input 
752                  name="TIMESTAMP-input" id="TIMESTAMP-input"
753                  class="text" type="text" 
754                  value="" style="width: 15em;" maxlength="20" 
755                  title="Enter date + time in format: <%=htmlDateTimeFormat%>">
756              </td>
757              <td>
758                <base:button 
759                  id="TIMESTAMP-calendar"
760                  image="calendar.png"
761                  title="Calendar&hellip;" 
762                  tooltip="Select date and time from a calendar"
763                />
764              </td>
765              </tr>
766              </table>
767            </div>
768         
769            <div id="BOOLEAN-container">
770              <label class="not-specified"><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-NULL" 
771                value="" checked>- not specified -</label><br>
772              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-TRUE" 
773                value="true">true</label><br>
774              <label><input type="radio" name="BOOLEAN-input" id="BOOLEAN-input-FALSE"
775                value="false">false</label>
776            </div>
777           
778           
779          </div>
780         
781          <div id="selected-description" class="messagecontainer help">
782          </div>
783        </div>
784 
785      </div>
786    </div>
787    </form>
788    <%
789    if (standalone)
790    {
791      %>
792      </div>
793      <base:buttongroup subclass="dialogbuttons topborder">
794        <base:button id="btnSave" title="Save" visible="<%=writePermission%>" />
795        <base:button id="close" title="Cancel"  visible="<%=writePermission%>" />
796        <base:button id="close" title="Close" visible="<%=!writePermission%>" />
797      </base:buttongroup>
798      <form name="modified" method="post" action="index.jsp?ID=<%=ID%>">
799        <input type="hidden" name="cmd" value="SaveAnnotations">
800        <input type="hidden" name="item_type" value="<%=itemType.name()%>">
801        <input type="hidden" name="item_id" value="<%=itemId%>">
802      </form>
803      <%
804    }
805    %>
806  </base:body>
807  </base:page>
808  <%
809}
810finally
811{
812  if (dc != null) dc.close();
813}
814%>
Note: See TracBrowser for help on using the repository browser.