source: trunk/www/biomaterials/samples/edit_sample.jsp @ 5687

Last change on this file since 5687 was 5687, checked in by Nicklas Nordborg, 12 years ago

References #1597: Subtypes of items

Smarter selection of default subtypes and related items (protocols, etc) have now been implemented in the other important edit dialogs.

Added support for also loading and displaying project default items dynamically based on the selected subtype.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 28.7 KB
Line 
1<%-- $Id: edit_sample.jsp 5687 2011-08-09 11:39:40Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) 2005 Nicklas Nordborg
4  Copyright (C) 2006 Johan Enell, Jari Häkkinen, Nicklas Nordborg, Martin Svensson
5
6  This file is part of BASE - BioArray Software Environment.
7  Available at http://base.thep.lu.se/
8
9  BASE is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License
11  as published by the Free Software Foundation; either version 3
12  of the License, or (at your option) any later version.
13
14  BASE is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with BASE. If not, see <http://www.gnu.org/licenses/>.
21  ------------------------------------------------------------------
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.ItemContext"
33  import="net.sf.basedb.core.SystemItems"
34  import="net.sf.basedb.core.Permission"
35  import="net.sf.basedb.core.Sample"
36  import="net.sf.basedb.core.BioSource"
37  import="net.sf.basedb.core.ItemSubtype"
38  import="net.sf.basedb.core.BioMaterialEvent"
39  import="net.sf.basedb.core.BioPlate"
40  import="net.sf.basedb.core.BioWell"
41  import="net.sf.basedb.core.Protocol"
42  import="net.sf.basedb.core.Project"
43  import="net.sf.basedb.core.PermissionDeniedException"
44  import="net.sf.basedb.core.BaseException"
45  import="net.sf.basedb.core.ItemQuery"
46  import="net.sf.basedb.core.ItemResultList"
47  import="net.sf.basedb.core.Include"
48  import="net.sf.basedb.core.query.Orders"
49  import="net.sf.basedb.core.query.Hql"
50  import="net.sf.basedb.core.query.Expressions"
51  import="net.sf.basedb.core.query.Restrictions"
52  import="net.sf.basedb.clients.web.Base"
53  import="net.sf.basedb.clients.web.util.HTML"
54  import="net.sf.basedb.util.Values"
55  import="net.sf.basedb.util.ListUtil"
56  import="net.sf.basedb.util.formatter.WellCoordinateFormatter"
57  import="net.sf.basedb.util.formatter.Formatter"
58  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
59  import="net.sf.basedb.clients.web.formatter.FormatterSettings"
60  import="net.sf.basedb.core.plugin.GuiContext"
61  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
62  import="net.sf.basedb.clients.web.extensions.JspContext"
63  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
64  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
65  import="java.util.List"
66  import="java.util.Set"
67  import="java.util.HashSet"
68  import="java.util.Date"
69  import="java.util.Collections"
70%>
71<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
72<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
73<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
74<%
75final Item itemType = Item.SAMPLE;
76final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
77final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
78final int itemId = cc.getId();
79final String ID = sc.getId();
80final float scale = Base.getScale(sc);
81final DbControl dc = sc.newDbControl();
82try
83{
84  String title = null;
85  Sample sample = null;
86  BioMaterialEvent creationEvent = null;
87  Date eventDate = null;
88  Item parentType = null;
89  String name = null;
90  boolean lockEventProperties = false;
91
92  boolean readCurrentSubtype = true;
93  ItemSubtype currentSubtype = null;
94  boolean readCurrentProtocol = true;
95  Protocol currentProtocol = null;
96  boolean readCurrentBioSource = true;
97  BioSource currentBioSource = null;
98  ItemQuery<Sample> samplesQuery = null; 
99  boolean readCurrentBioWell = true;
100  BioWell currentBioWell = null;
101  boolean lockedWell = false;
102  boolean readCurrentBioPlate = true;
103  BioPlate currentBioPlate = null;
104 
105  WellCoordinateFormatter rowFormatter = new WellCoordinateFormatter(true);
106  WellCoordinateFormatter columnFormatter = new WellCoordinateFormatter(false);
107 
108  if (itemId == 0)
109  {
110    title = "Create sample";
111    cc.removeObject("item");
112    if (cc.getPropertyFilter("creationEvent.protocol.name") != null)
113    {
114      currentProtocol = Base.getFirstMatching(dc, Protocol.getQuery(), "name", cc.getPropertyFilter("creationEvent.protocol.name"));
115    }
116    int bioSourceId = Values.getInt(request.getParameter("biosource_id"));
117    int sampleId = Values.getInt(request.getParameter("sample_id"));
118    int currentSubtypeId = Values.getInt(request.getParameter("subtype_id"));
119    List<ItemSubtype> relatedToParent = Collections.emptyList();
120    if (bioSourceId != 0)
121    {
122      currentBioSource = BioSource.getById(dc, bioSourceId);
123      parentType = Item.BIOSOURCE;
124      name = currentBioSource.getName() + ".s" + (currentBioSource.countSamples() + 1);
125      if (currentSubtypeId == 0)
126      {
127        relatedToParent = ItemSubtype.getParentSubtypes(dc, currentBioSource, Item.SAMPLE);
128      }
129    }
130    else if (sampleId != 0)
131    {
132      parentType = Item.SAMPLE;
133      Sample s = Sample.getById(dc, sampleId);
134      name = s.getName() + ".s" + (s.countSamples()+1);
135      samplesQuery = Sample.getQuery();
136      samplesQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(sampleId)));
137      if (currentSubtypeId == 0)
138      {
139        relatedToParent = ItemSubtype.getParentSubtypes(dc, s, Item.SAMPLE);
140      }
141    }
142    else if (Values.getBoolean(request.getParameter("pooled")))
143    {   
144      parentType = Item.SAMPLE;
145      name = Values.getString(cc.getPropertyValue("name"), "New pooled sample");
146      samplesQuery = Sample.getQuery();
147      samplesQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("selected")));
148      samplesQuery.setParameter("selected", cc.getSelected(), Type.INT);
149    }
150    else
151    {
152      name = Values.getString(cc.getPropertyValue("name"), "New sample");
153    }
154    if (currentSubtypeId == 0) 
155    {
156      if (relatedToParent.size() > 0)
157      {
158        // Find most recently used related subtype
159        List<ItemSubtype> recentSubtypes = (List<ItemSubtype>)cc.getRecent(dc, Item.ITEMSUBTYPE);
160        currentSubtype = ListUtil.findFirstCommon(recentSubtypes, relatedToParent, relatedToParent.get(0));
161      }
162      else
163      {
164        int recentSubtypeId = Values.getInt(cc.getRecent(Item.ITEMSUBTYPE.name(), 0));
165        currentSubtypeId = Values.getInt(cc.getPropertyValue("itemSubtype"), recentSubtypeId);
166        if (currentSubtypeId > 0) currentSubtype = ItemSubtype.getById(dc, currentSubtypeId);
167      }
168    }
169    eventDate = (Date)cc.getPropertyObject("creationEvent.eventDate");
170  }
171  else
172  {
173    sample = Sample.getById(dc, itemId);
174    sample.checkPermission(Permission.WRITE);
175    cc.setObject("item", sample);
176    title = "Edit sample -- " + HTML.encodeTags(sample.getName());
177 
178    creationEvent = sample.getCreationEvent();
179    eventDate = creationEvent.getEventDate();
180    parentType = sample.getParentType();
181    name = sample.getName();
182    lockEventProperties = !creationEvent.hasPermission(Permission.WRITE);
183   
184    try
185    {
186      currentSubtype = sample.getItemSubtype();
187    }
188    catch (PermissionDeniedException ex)
189    {
190      readCurrentSubtype = false;
191    }
192
193    try
194    {
195      currentProtocol = creationEvent.getProtocol();
196    }
197    catch (PermissionDeniedException ex)
198    {
199      readCurrentProtocol = false;
200    }
201 
202    try
203    {
204      if (parentType == Item.BIOSOURCE)
205      {
206        currentBioSource = (BioSource)sample.getParent();
207      }
208    }
209    catch (PermissionDeniedException ex)
210    {
211      readCurrentBioSource = false;
212    }
213   
214    try
215    {
216      currentBioWell = sample.getBioWell();
217      lockedWell = sample.isLockedInWell();
218      if (currentBioWell != null)
219      {
220        currentBioPlate = currentBioWell.getPlate();
221      }
222    }
223    catch (PermissionDeniedException ex)
224    {
225      readCurrentBioWell = false;
226      readCurrentBioPlate = false;
227    }
228 
229    // Query to retrieve parent samples
230    if (parentType == Item.SAMPLE)
231    {
232      samplesQuery = (ItemQuery<Sample>)creationEvent.getSources();
233    }
234  }
235 
236  // Default items
237  int activeProjectId = sc.getActiveProjectId();
238  List<Protocol> defaultProtocols = null;
239  if (activeProjectId > 0)
240  {
241    Project activeProject = Project.getById(dc, activeProjectId);
242    ItemSubtype protocolSubtype = currentSubtype == null ? null : currentSubtype.getRelatedSubtype(Item.PROTOCOL);
243    if (protocolSubtype == null) protocolSubtype = ItemSubtype.getById(dc, SystemItems.getId(Protocol.SAMPLING));
244    defaultProtocols = (List<Protocol>)activeProject.findDefaultItems(dc, protocolSubtype, false);
245  }
246 
247  // Load recently used items
248  List<Protocol> recentProtocols = (List<Protocol>)cc.getRecent(dc, Item.PROTOCOL, currentSubtype);
249  List<BioSource> recentBioSources = (List<BioSource>)cc.getRecent(dc, Item.BIOSOURCE);
250  List<BioPlate> recentBioPlates = (List<BioPlate>)cc.getRecent(dc, Item.BIOPLATE, currentSubtype);
251 
252  // Query to retrieve item types
253  final ItemQuery<ItemSubtype> subtypesQuery = Base.getSubtypesQuery(itemType);
254  subtypesQuery.include(Include.ALL);
255 
256  final String clazz = "class=\"text\"";
257  final String requiredClazz = "class=\"text required\"";
258  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
259  String dateFormat = FormatterSettings.getDateFormat(sc);
260  String jsDateFormat = HTML.javaScriptEncode(dateFormat);
261  String htmlDateFormat = HTML.encodeTags(dateFormat);
262  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), sample);
263  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
264  %>
265  <base:page type="popup" title="<%=title%>">
266  <base:head scripts="tabcontrol.js,annotations.js,linkitems.js,subtypes.js,ajax.js,json2.js" styles="tabcontrol.css">
267    <ext:scripts context="<%=jspContext%>" />
268    <ext:stylesheets context="<%=jspContext%>" />
269    <script language="JavaScript">
270    // Validate the "Sample" tab
271    function validateSample()
272    {
273      var frm = document.forms['sample'];
274      if (Main.trimString(frm.name.value) == '')
275      {
276        alert("You must enter a name");
277        frm.name.focus();
278        return false;
279      }
280      if (Main.trimString(frm.bioplate_id.value) != 0 && Main.trimString(frm.biowell_id.value) == 0)
281      {
282        alert("You must choose a biowell from the bioplate");
283        return false;
284      }
285      return true;
286    }
287
288    // Submit the form
289    function saveSettings()
290    {
291      var frm = document.forms['sample'];
292      if (TabControl.validateActiveTab('settings'))
293      {
294        if (annotationsLoaded)
295        {
296          Annotations.addModifiedAnnotationsToForm(frames.annotations, frm);
297        }
298        if (inheritedAnnotationsLoaded)
299        {
300          Annotations.addInheritedAnnotationsToForm(frames.inheritedAnnotations, frm);
301        }
302        frm.modifiedSamples.value = Link.exportModified(frm, 'S', true).join(',');
303        frm.removedSamples.value = Link.getActionIds(-1, 'S').join(',');
304        frm.submit();
305      }
306    }
307   
308    var annotationsLoaded = false;
309    var inheritedAnnotationsLoaded = false;
310    var parentsChanged = false;
311    var protocolChanged = false;
312    function switchTab(tabControlId, tabId)
313    {
314      if (TabControl.setActiveTab(tabControlId, tabId))
315      {
316        if (tabId == 'annotations' && (protocolChanged || !annotationsLoaded))
317        {
318          Annotations.loadAnnotateFrame(frames.annotations, '<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, getProtocolId(), ItemSubtype.getSubtypeId('sample'));
319          annotationsLoaded = true;
320          protocolChanged = false;
321        }
322        else if (tabId == 'inheritedAnnotations' && 
323          (parentsChanged || !inheritedAnnotationsLoaded))
324        {
325          Annotations.loadInheritFrame(frames.inheritedAnnotations, '<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, getParents());
326          inheritedAnnotationsLoaded = true;
327          parentsChanged = false;
328        }
329      }
330    }
331   
332    function getProtocolId()
333    {
334      var frm = document.forms['sample'];
335      var protocolId = 0;
336      if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
337      {
338        protocolId = Math.abs(parseInt(frm.protocol_id[frm.protocol_id.selectedIndex].value));       
339      }
340      return protocolId;
341    }
342   
343    function getParents()
344    {
345      var frm = document.forms['sample'];
346      var parents = new Array();
347      if (frm.parentType[0].checked)
348      {
349        var bioSourceId = Math.abs(parseInt(frm.biosource_id[frm.biosource_id.selectedIndex].value));
350        if (bioSourceId > 0) parents[parents.length] = 'BIOSOURCE:'+bioSourceId;
351      }
352      else
353      {
354        var ids = Link.getListIds(frm.samples, 'S');
355        if (ids.length > 0)
356        {
357          parents[parents.length] = 'SAMPLE:'+ids.join(':');
358        }
359      }
360      return parents;
361    }
362   
363    function subtypeOnChange()
364    {
365      var frm = document.forms['sample'];
366      var subtypeId = ItemSubtype.getSubtypeId('sample');
367      var recentInfo = ItemSubtype.getRecentAndRelatedInfo(subtypeId, 'SAMPLE', ['PROTOCOL', 'BIOPLATE', 'BIOSOURCE', 'SAMPLE']);
368      protocolChanged = ItemSubtype.updateRecentItemsInList(frm.protocol_id, recentInfo.PROTOCOL['recent']);
369      ItemSubtype.updateDefaultItemsInList(frm.protocol_id, recentInfo.PROTOCOL['default']);
370      ItemSubtype.updateRecentItemsInList(frm.bioplate_id, recentInfo.BIOPLATE['recent']);
371    }
372   
373    function selectProtocolOnClick()
374    {
375      var frm = document.forms['sample'];
376      var url = '../../admin/protocols/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
377      url += '&callback=setProtocolCallback&resetTemporary=1';
378      url += ItemSubtype.createRelatedFilter('sample', 'PROTOCOL', <%=SystemItems.getId(Protocol.SAMPLING)%>);
379      if (frm.protocol_id.length > 1)
380      {
381        var id = Math.abs(parseInt(frm.protocol_id[1].value));       
382        url += '&item_id='+id;
383      }
384      Main.openPopup(url, 'SelectProtocol', 1000, 700);
385    }
386    function setProtocolCallback(id, name)
387    {
388      var frm = document.forms['sample'];
389      var list = frm.protocol_id;
390      if (list.length < 2 || list[1].value == '0') // >
391      {
392        Forms.addListOption(list, 1, new Option());
393      }
394      list[1].value = id;
395      list[1].text = name;
396      list.selectedIndex = 1;
397      protocolChanged = true;
398    }
399    function protocolOnChange()
400    {
401      protocolChanged = true;
402    }
403
404    function selectBioPlateOnClick()
405    {
406      var frm = document.forms['sample'];
407      var url = '../bioplates/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setBioPlateCallback';
408      if (frm.bioplate_id.length > 1)
409      {
410        var id = Math.abs(parseInt(frm.bioplate_id[1].value));       
411        url += '&item_id='+id;
412      }
413      url += '&resetTemporary=1&tmpfilter:INT:bioPlateType.lockMode=<><%=BioWell.LockMode.LOCKED_AFTER_CREATE.getValue()%>';
414      url += '&tmpfilter:BOOLEAN:destroyed=false';
415      Main.openPopup(url, 'SelectBioplate', 1000, 700);
416    }
417    function setBioPlateCallback(id, name)
418    {
419      var frm = document.forms['sample'];
420      var list = frm.bioplate_id;
421      if (list.length < 2 || list[1].value == '0') // >
422      {
423        Forms.addListOption(list, 1, new Option());
424      }
425      list[1].value = id;
426      list[1].text = name;
427      list.selectedIndex = 1;
428      frm.biowell_id.remove(1);
429      frm.biowell_id.disabled = false;
430    }
431    function bioPlateOnChange()
432    {
433      var frm = document.forms['sample'];
434      var list = frm.bioplate_id;
435      frm.biowell_id.selectedIndex=0;
436      frm.biowell_id.remove(1);     
437    }
438
439    function initBioWell()
440    {
441      var frm = document.forms['sample'];
442      <%
443      if (currentBioWell != null)
444      {
445        %>
446        var list = frm.biowell_id;
447        var wellId = <%=currentBioWell.getId()%>;
448        Forms.addListOption(list, 1, new Option());
449        list[1].value = '<%=currentBioWell.getId()*(sample == null ? 1 : -1)%>';
450        list[1].text = '[<%=rowFormatter.format(currentBioWell.getRow())%>,<%=columnFormatter.format(currentBioWell.getColumn())%>]';
451        list.selectedIndex = 1;
452      <%
453      }
454      %>
455    }         
456    function selectBioWellOnClick()
457    {
458      var frm = document.forms['sample'];
459      var bioplate_list = frm.bioplate_id;     
460      var bioplateId = Math.abs(parseInt(bioplate_list[bioplate_list.selectedIndex].value))
461      if (Main.trimString(frm.bioplate_id.value) == 0)
462      {
463        alert("You must first select the bioplate where the biowell is located");
464        return;
465      }     
466       
467      var url = '../bioplates/wells/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setBioWellCallback';
468      if (frm.biowell_id.length > 1)
469      {
470        var id = Math.abs(parseInt(frm.biowell_id[1].value));       
471        url += '&item_id='+id;
472      }
473      url += '&bioplate_id='+bioplateId;
474      url += '&resetTemporary=1&tmpfilter:STRING:$mbm.name='+escape('=');
475      url += '&tmpfilter:STRING:originalBioMaterial.name='+escape('=');
476      url += '&columns=row,column';
477      Main.openPopup(url, 'SelectBiowell', 700, 700);
478    }
479    function setBioWellCallback(id, name)
480    {
481      var frm = document.forms['sample'];
482      var list = frm.biowell_id;
483      if (list.length < 2 || list[1].value == '0') // >
484      {
485        Forms.addListOption(list, 1, new Option());
486      }
487      list[1].value = id;
488      list[1].text = name;
489      list.selectedIndex = 1;
490    }
491   
492    function parentTypeOnClick()
493    {
494      var frm = document.forms['sample'];
495      var useSamples = frm.parentType[1].checked;
496      frm.biosource_id.disabled = useSamples;
497      frm.samples.disabled = !useSamples;
498      frm.used_quantity.disabled = !useSamples;
499      parentsChanged = true;
500    }
501    function bioSourceOnChange()
502    {
503      parentsChanged = true;
504    }
505    function selectBioSourceOnClick()
506    {
507      var frm = document.forms['sample'];
508      var url = '../biosources/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
509      url += '&callback=setBioSourceCallback&resetTemporary=1';
510      url += ItemSubtype.createRelatedFilter('sample', 'BIOSOURCE');
511      if (frm.biosource_id.length > 1)
512      {
513        var id = Math.abs(parseInt(frm.biosource_id[1].value));       
514        url += '&item_id='+id;
515      }
516      Main.openPopup(url, 'SelectBioSource', 1000, 700);
517    }
518    function setBioSourceCallback(id, name)
519    {
520      var frm = document.forms['sample'];
521      var list = frm.biosource_id;
522      if (list.length < 2 || list[1].value == '0') // >
523      {
524        Forms.addListOption(list, 1, new Option());
525      }
526      list[1].value = id;
527      list[1].text = name;
528      list.selectedIndex = 1;
529
530      frm.parentType[0].checked = true;
531      frm.parentType[1].checked = false;
532      parentTypeOnClick();
533      parentsChanged = true;
534    }
535   
536    function addSamplesOnClick()
537    {
538      var frm = document.forms['sample'];
539      var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
540      url += '&callback=addSampleCallback&resetTemporary=1';
541      url += ItemSubtype.createRelatedFilter('sample', 'SAMPLE');
542      Main.openPopup(url, 'AddSamples', 1000, 700);
543    }
544    function addSampleCallback(sampleId, name)
545    {
546      var frm = document.forms['sample'];
547      var item = Link.getItem('S', sampleId);
548      if (!item) item = new Item('S', sampleId, name+' [-]', '', '');
549      Link.addItem(frm.samples, item);
550      frm.parentType[0].checked = false;
551      frm.parentType[1].checked = true;
552      parentTypeOnClick();
553      parentsChanged = true;
554    }
555    function samplesOnChange()
556    {
557      var frm = document.forms['sample'];
558      var item = frm.samples[frm.samples.selectedIndex].item;
559      if (item && item.id)
560      {
561        frm.used_quantity.value = item.value;
562        frm.used_quantity.focus();
563      }
564      else
565      {
566        frm.used_quantity.value = '';
567      }
568    }
569    function usedQuantityOnBlur()
570    {
571      var frm = document.forms['sample'];
572      var usedQuantity = frm.used_quantity.value;
573      var displayQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
574      for (var i = 0; i < frm.samples.length; i++)  // >
575      {
576        var option = frm.samples[i];
577        if (option.selected && option.item.id)
578        {
579          option.item.value = usedQuantity;
580          var text = option.text.replace(/\[.*\]/, '['+displayQuantity+']');
581          option.text = text;
582        }
583      }
584    }
585
586    function removeOnClick()
587    {
588      Link.removeSelected(document.forms['sample'].samples);
589      parentsChanged = true;
590    }
591
592    function init()
593    {
594      <%
595      if (sample == null)
596      {
597        %>
598        var frm = document.forms['sample'];
599        frm.name.focus();
600        frm.name.select();
601        <%
602      }
603      %>
604      initBioWell();
605      initSamples();
606      parentTypeOnClick();   
607    }
608    function initSamples()
609    {
610      var samples = document.forms['sample'].samples;
611      <%
612      if (samplesQuery != null)
613      {
614        samplesQuery.include(Include.ALL);
615        samplesQuery.order(Orders.asc(Hql.property("name")));
616        ItemResultList<Sample> samples = samplesQuery.list(dc);
617        for (Sample s : samples)
618        {
619          if (sample != null)
620          {
621            String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(s), -1);
622            %>
623            Link.addNewItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
624            <%
625          }
626          else
627          {
628            %>
629            Link.addItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [-]', '', ''));
630            <%
631          }
632        }
633      }
634      %>
635    }
636    </script>
637  </base:head>
638  <base:body onload="init()">
639    <p>
640    <form action="index.jsp?ID=<%=ID%>" method="post" name="sample" onsubmit="return false;">
641    <input type="hidden" name="cmd" value="UpdateItem">
642
643    <h3 class="docked"><%=title%> <base:help tabcontrol="settings" /></h3>
644    <t:tabcontrol id="settings" contentstyle="<%="height: "+(int)(scale*370)+"px;"%>" 
645      position="bottom"  remember="<%=sample != null%>" switch="switchTab"
646      extensions="<%=invoker%>">
647    <t:tab id="info" title="Sample" validate="validateSample()" helpid="sample.edit">
648      <table class="form" cellspacing=0>
649      <tr>
650        <td class="prompt">Name</td>
651        <td><input <%=requiredClazz%> type="text" name="name" 
652          value="<%=HTML.encodeTags(name)%>" 
653          size="40" maxlength="<%=Sample.MAX_NAME_LENGTH%>"></td>
654      </tr>
655      <tr valign="top">
656        <td class="prompt">Type</td>
657        <td colspan="2">
658          <select name="subtype_id"
659            <%=!readCurrentSubtype ? "disabled readonly class=\"disabled selectionlist\"" : "class=\"selectionlist\""%>
660            onchange="subtypeOnChange()"
661            >
662          <%
663          if (!readCurrentSubtype)
664          {
665            %>
666            <option value="-1">- denied -
667            <%
668          }
669          else
670          {
671            %>
672            <option value="0">-none-
673            <%
674            int currentSubtypeId = currentSubtype == null ? 0 : currentSubtype.getId();
675            for (ItemSubtype subtype : subtypesQuery.list(dc))
676            {
677              int id = subtype.getId();
678              if (id != currentSubtypeId && subtype.isRemoved()) continue;
679              %>
680              <option value="<%=id == currentSubtypeId && sample != null ? -id : id%>" 
681                <%=id == currentSubtypeId ? "selected" : ""%>
682                title="<%=HTML.encodeTags(subtype.getDescription()) %>"
683                ><%=HTML.encodeTags(subtype.getName())%>
684              <%
685            }
686          }
687          %>
688          </select>
689        </td>
690      </tr>
691      <tr>
692        <td class="prompt">External ID</td>
693        <td><input <%=clazz%> type="text" name="external_id" 
694          value="<%=HTML.encodeTags(sample == null ? Values.getString(cc.getPropertyValue("externalId"), "") : sample.getExternalId())%>" 
695          size="40" maxlength="<%=Sample.MAX_EXTERNAL_ID_LENGTH%>"></td>
696      </tr>
697      <tr>
698        <td class="prompt">Original quantity</td>
699        <td><input <%=clazz%> type="text" name="original_quantity" 
700          value="<%=Values.formatNumber(sample == null ? Values.getFloat(cc.getPropertyValue("originalQuantity"), null): sample.getOriginalQuantity(), -1)%>" size="12" 
701          maxlength="10" onkeypress="return Numbers.numberOnly(event)"> (µg)</td>
702      </tr>
703      <tr>
704        <td class="prompt">Created</td>
705        <td>
706          <table border="0" cellspacing="0" cellpadding="0">
707          <tr>
708          <td>
709            <input <%=clazz%> type="text" name="event_date" <%=lockEventProperties ? "disabled" : ""%>
710              value="<%=HTML.encodeTags(dateFormatter.format(eventDate))%>" 
711              size="20" maxlength="20" title="Enter date in format: <%=htmlDateFormat%>">
712            &nbsp;
713          </td>
714          <td>
715          <base:button 
716            onclick="<%="Dates.selectDate('Created', 'sample', 'event_date', null, '"+jsDateFormat+"')"%>"
717            image="calendar.png" 
718            title="Calendar&hellip;" 
719            tooltip="Select a date from a calendar" 
720            disabled="<%=lockEventProperties%>"
721          />
722          </td>
723          </tr>
724          </table>
725        </td>
726      </tr>
727      <tr>
728        <td class="prompt">Registered</td>
729        <td><%=dateFormatter.format(creationEvent == null ? new Date() : creationEvent.getEntryDate())%></td>
730      </tr>
731      <tr>
732        <td class="prompt">Protocol</td>
733        <td>
734          <base:select 
735            id="protocol_id"
736            clazz="selectionlist"
737            required="false"
738            current="<%=currentProtocol%>"
739            denied="<%=!readCurrentProtocol%>"
740            recent="<%=recentProtocols%>"
741            defaultitems="<%=defaultProtocols%>"
742            newitem="<%=sample == null%>"
743            onselect="selectProtocolOnClick()"
744            onchange="protocolOnChange()"
745            disabled="<%=lockEventProperties %>"
746          />
747        </td>
748      </tr>
749      <tr>
750        <td class="prompt">Bioplate</td>
751        <td>
752          <base:select 
753            id="bioplate_id"
754            clazz="selectionlist"
755            required="false"
756            current="<%=currentBioPlate%>"
757            denied="<%=!readCurrentBioPlate%>"
758            recent="<%=recentBioPlates%>"
759            newitem="<%=sample == null%>"
760            onselect="selectBioPlateOnClick()"
761            onchange="bioPlateOnChange()"
762            disabled="<%=lockedWell%>"
763          />
764        </td>
765      </tr>
766      <tr>
767        <td class="prompt">Biowell</td>
768        <td>
769          <base:select 
770            id="biowell_id"
771            clazz="selectionlist"
772            required="false"           
773            current="<%=null %>"
774            denied="<%=!readCurrentBioWell%>"
775            newitem="<%=sample == null%>"
776            onselect="selectBioWellOnClick()"
777            onchange="bioWellOnChange()"
778            disabled="<%=lockedWell%>"
779          />
780        </td>
781      </tr>
782      <tr valign=top>
783        <td class="prompt">Description</td>
784        <td nowrap>
785          <textarea <%=clazz%> rows="4" cols="40" name="description" wrap="virtual"
786            ><%=HTML.encodeTags(sample == null ? cc.getPropertyValue("description") : sample.getDescription())%></textarea>
787          <a href="javascript:Main.zoom('Description', 'sample', 'description')"
788            title="Edit in larger window"><base:icon image="zoom.gif" /></a>
789        </td>
790      </tr>
791      </table>
792      <div align=right>&nbsp;<i><base:icon image="required.gif" /> = required information</i></div>
793    </t:tab>
794   
795    <t:tab id="parents" title="Parents" helpid="sample.parents" >
796      <table class="form" cellspacing=0>
797      <tr>
798        <td class="prompt">Parent type</td>
799        <td>
800          <input type="radio" name="parentType" id="parentType.biosource" 
801            value="BIOSOURCE" onclick="parentTypeOnClick()"
802            <%=parentType != Item.SAMPLE ? "checked" : ""%>
803            ><label for="parentType.biosource">Biosource</label>
804          <input type="radio" name="parentType" id="parentType.sample" 
805            value="SAMPLE" onclick="parentTypeOnClick()"
806            <%=parentType == Item.SAMPLE ? "checked" : ""%>
807            ><label for="parentType.sample">Sample</label>
808        </td>
809      </tr>
810      <tr>
811        <td class="prompt">Biosource</td>
812        <td>
813          <base:select 
814            id="biosource_id"
815            clazz="selectionlist"
816            buttonstyle="width: 150px;"
817            buttonicon="add.png"
818            buttontitle="Select biosource&hellip;"
819            required="false"
820            current="<%=currentBioSource%>"
821            denied="<%=!readCurrentBioSource%>"
822            recent="<%=recentBioSources%>"
823            selectrecent="false"
824            newitem="<%=sample == null%>"
825            onselect="selectBioSourceOnClick()"
826            onchange="bioSourceOnChange()"
827          />
828        </td>
829      </tr>
830      <tr valign="top">
831        <td class="prompt">Samples</td>
832        <td>
833          <table border="0" cellspacing="0" cellpadding="0">
834          <tr valign="top">
835          <td>
836            <select name="samples" size="5" multiple class="selectionlist" 
837              onchange="samplesOnChange()">
838            </select>&nbsp;
839            <input type="hidden" name="modifiedSamples" value="">
840            <input type="hidden" name="removedSamples" value="">
841          </td>
842          <td>
843            <table border="0" cellspacing="0" cellpadding="0">
844            <tr><td style="padding: 1px 0px 4px 0px;"><base:button 
845              style="width: 150px;"
846              onclick="addSamplesOnClick()" 
847              title="Add&nbsp;samples&hellip;" 
848              tooltip="Add samples"
849              /></td></tr>
850            <tr><td><base:button 
851              style="width: 150px;"
852              onclick="removeOnClick()" 
853              title="Remove" 
854              tooltip="Remove the selected samples"
855            /></td></tr>
856            </table>
857          </td>
858          </tr>
859          </table>
860        </td>
861      </tr>
862      <tr>
863        <td class="subprompt">-</td>
864        <td>used quantity
865        <input <%=clazz%> type="text" name="used_quantity" value=""
866              size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
867              onkeyup="usedQuantityOnBlur();"
868            > (µg)
869        </td>
870      </tr>         
871      </table>
872    </t:tab>
873
874    <t:tab id="annotations" title="Annotations &amp; parameters" 
875      helpid="annotations.edit" tooltip="Enter values for annotations and protocol parameters">
876      <iframe name="annotations" id="idAnnotations" src="../../common/annotations/wait.jsp" 
877        width="100%"  height="<%=(int)(scale*370)%>" frameborder=0 vspace=0 hspace=0
878        marginwidth=0 marginheight=0 scrolling="auto" style="overflow: visible"></iframe>
879    </t:tab>
880   
881    <t:tab id="inheritedAnnotations" title="Inherited annotations" helpid="annotations.edit.inherited">
882   
883      <iframe name="inheritedAnnotations" id="idInheritedAnnotations" src="../../common/annotations/wait.jsp" 
884        width="100%"  height="<%=(int)(scale*370)%>" frameborder=0 vspace=0 hspace=0
885        marginwidth=0 marginheight=0 scrolling="auto" style="overflow: visible"></iframe>
886    </t:tab>
887    </t:tabcontrol>
888
889    <table align="center">
890    <tr>
891      <td width="50%"><base:button onclick="saveSettings()" title="Save" /></td>
892      <td width="50%"><base:button onclick="window.close()" title="Cancel" /></td>
893    </tr>
894    </table>
895    </form>
896  </base:body>
897  </base:page>
898  <%
899}
900finally
901{
902  if (dc != null) dc.close();
903}
904%>
Note: See TracBrowser for help on using the repository browser.