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

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

References #2034: New permission for annotating items

The "Edit annotation" icon in the "Annotations & parameters" tab should be enabled when the logged in user has RESTRICTED_WRITE permission.

The "Save" button in the "Edit annotations" dialog should be enabled if the logged in user has RESTRICTED_WRITE permission.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 22.5 KB
Line 
1<%-- $Id: annotate.jsp 7213 2016-10-19 12:18:53Z 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 annotatePermission = item == null ? true : item.hasPermission(Permission.RESTRICTED_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="<%=annotatePermission%>" />
795        <base:button id="close" title="Cancel"  visible="<%=annotatePermission%>" />
796        <base:button id="close" title="Close" visible="<%=!annotatePermission%>" />
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.