source: trunk/www/biomaterials/extracts/edit_extract.jsp @ 2753

Last change on this file since 2753 was 2753, checked in by Nicklas Nordborg, 17 years ago

Fixes #404: Replace deprecated Values class with the new one in all JSP pages

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Id
File size: 18.2 KB
Line 
1<%-- $Id: edit_extract.jsp 2753 2006-10-20 11:04:36Z nicklas $
2  ------------------------------------------------------------------
3  Copyright (C) Authors contributing to this file.
4
5  This file is part of BASE - BioArray Software Environment.
6  Available at http://base.thep.lu.se/
7
8  BASE is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License
10  as published by the Free Software Foundation; either version 2
11  of the License, or (at your option) any later version.
12
13  BASE is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330,
21  Boston, MA  02111-1307, USA.
22  ------------------------------------------------------------------
23
24
25  @author Nicklas
26  @version 2.0
27--%>
28<%@ page
29  import="net.sf.basedb.core.SessionControl"
30  import="net.sf.basedb.core.DbControl"
31  import="net.sf.basedb.core.Item"
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.Extract"
37  import="net.sf.basedb.core.BioMaterialEvent"
38  import="net.sf.basedb.core.Protocol"
39  import="net.sf.basedb.core.ProtocolType"
40  import="net.sf.basedb.core.PermissionDeniedException"
41  import="net.sf.basedb.core.BaseException"
42  import="net.sf.basedb.core.ItemQuery"
43  import="net.sf.basedb.core.ItemResultList"
44  import="net.sf.basedb.core.Include"
45  import="net.sf.basedb.core.query.Orders"
46  import="net.sf.basedb.core.query.Hql"
47  import="net.sf.basedb.clients.web.Base"
48  import="net.sf.basedb.clients.web.util.HTML"
49  import="net.sf.basedb.util.Values"
50  import="java.util.List"
51  import="java.util.Set"
52  import="java.util.HashSet"
53  import="java.util.Date"
54%>
55<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
56<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
57<%
58final Item itemType = Item.EXTRACT;
59final SessionControl sc = Base.getExistingSessionControl(pageContext, true);
60final ItemContext cc = Base.getAndSetCurrentContext(sc, itemType, null, null);
61final int itemId = cc.getId();
62final String ID = sc.getId();
63final float scale = Base.getScale(sc);
64final DbControl dc = sc.newDbControl();
65try
66{
67  String title = null;
68  Extract extract = null;
69  BioMaterialEvent creationEvent = null;
70  boolean isPooled = false;
71
72  boolean readCurrentProtocol = true;
73  Protocol currentProtocol = null;
74  boolean readCurrentSample = true;
75  Sample currentSample = null;
76  Float usedFromSample = null;
77  String name = null;
78  ItemQuery<Extract> extractsQuery = null;
79 
80  // Load recently used items
81  List<Protocol> recentProtocols = (List<Protocol>)cc.getRecent(dc, Item.PROTOCOL);
82  List<Sample> recentSamples = (List<Sample>)cc.getRecent(dc, Item.SAMPLE);
83 
84  if (itemId == 0)
85  {
86    title = "Create extract";
87    cc.removeObject("item");
88    if (cc.getPropertyFilter("creationEvent.protocol.name") != null)
89    {
90      currentProtocol = Base.getFirstMatching(dc, Protocol.getQuery(), "name", cc.getPropertyFilter("creationEvent.protocol.name"));
91    }
92    int sampleId = Values.getInt(request.getParameter("sample_id"));
93    if (sampleId != 0)
94    {
95      currentSample  = Sample.getById(dc, sampleId);
96      isPooled = false;
97      name = currentSample.getName() + ".e" + (currentSample.countExtracts() + 1);     
98    }
99    else if(Values.getBoolean(request.getParameter("pooled")))
100    {
101      isPooled = true;
102      name = Values.getString(cc.getPropertyValue("name"), "New pooled extract");
103    }
104    else
105    {
106      isPooled = Values.getBoolean(cc.getPropertyValue("pooled"));
107      name = Values.getString(cc.getPropertyValue("name"), "New extract");
108    }
109  }
110  else
111  {
112    extract = Extract.getById(dc, itemId);
113    cc.setObject("item", extract);
114    title = "Edit extract -- " + HTML.encodeTags(extract.getName());
115 
116    creationEvent = extract.getCreationEvent();
117    isPooled = extract.isPooled();
118    name = extract.getName();
119   
120    try
121    {
122      currentProtocol = creationEvent.getProtocol();
123    }
124    catch (PermissionDeniedException ex)
125    {
126      readCurrentProtocol = false;
127    }
128 
129    try
130    {
131      currentSample = extract.getSample();
132      if (currentSample != null) usedFromSample = creationEvent.getUsedQuantity(currentSample);
133    }
134    catch (PermissionDeniedException ex)
135    {
136      readCurrentSample = false;
137    }
138 
139    // Query to retrieve pooled extracts
140    extractsQuery = (ItemQuery<Extract>)creationEvent.getSources();
141    extractsQuery.include(Include.MINE, Include.SHARED, Include.IN_PROJECT, Include.OTHERS);
142    extractsQuery.order(Orders.asc(Hql.property("name")));
143 
144  }
145  if (extract != null && !extract.hasPermission(Permission.WRITE))
146  {
147    throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
148  }
149  final String clazz = "class=\"text\"";
150  final String requiredClazz = "class=\"text required\"";
151  %>
152
153  <base:page type="popup" title="<%=title%>">
154  <base:head scripts="tabcontrol.js,annotations.js,linkitems.js" styles="tabcontrol.css">
155    <script language="JavaScript">
156    // Validate the "Extract" tab
157    function validateExtract()
158    {
159      var frm = document.forms['extract'];
160      if (Main.trimString(frm.name.value) == '')
161      {
162        alert("You must enter a name");
163        frm.name.focus();
164        return false;
165      }
166      return true;
167    }
168
169    // Submit the form
170    function saveSettings()
171    {
172      var frm = document.forms['extract'];
173      if (TabControl.validateActiveTab('settings'))
174      {
175        if (annotationsLoaded)
176        {
177          Annotations.addModifiedAnnotationsToForm(frames.annotations, frm);
178        }
179        if (inheritedAnnotationsLoaded)
180        {
181          Annotations.addInheritedAnnotationsToForm(frames.inheritedAnnotations, frm);
182        }
183        frm.modifiedExtracts.value = Link.exportModified(frm, 'E', true).join(',');
184        frm.removedExtracts.value = Link.getActionIds(-1, 'E').join(',');
185        frm.submit();
186      }
187    }
188   
189    var annotationsLoaded = false;
190    var inheritedAnnotationsLoaded = false;
191    var parentsChanged = false;
192    function switchTab(tabControlId, tabId)
193    {
194      if (TabControl.setActiveTab(tabControlId, tabId))
195      {
196        if (tabId == 'annotations' && !annotationsLoaded)
197        {
198          Annotations.loadAnnotateFrame(frames.annotations, '<%=ID%>', '<%=itemType.name()%>', <%=itemId%>);
199          annotationsLoaded = true;
200        }
201        else if (tabId == 'inheritedAnnotations' && 
202          (parentsChanged || !inheritedAnnotationsLoaded))
203        {
204          Annotations.loadInheritFrame(frames.inheritedAnnotations, '<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, getParents());
205          inheritedAnnotationsLoaded = true;
206          parentsChanged = false;
207        }
208      }
209    }
210
211    function getParents()
212    {
213      var frm = document.forms['extract'];
214      var parents = new Array();
215      if (frm.pooled[0].checked)
216      {
217        var sampleId = Math.abs(parseInt(frm.sample_id[frm.sample_id.selectedIndex].value));
218        if (sampleId > 0) parents[parents.length] = 'SAMPLE:'+sampleId;
219      }
220      else
221      {
222        var ids = Link.getListIds(frm.extracts, 'E');
223        if (ids.length > 0)
224        {
225          parents[parents.length] = 'EXTRACT:'+ids.join(':');
226        }
227      }
228      return parents;
229    }
230   
231    function selectProtocolOnClick()
232    {
233      var frm = document.forms['extract'];
234      var url = '../../admin/protocols/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setProtocolCallback';
235      if (frm.protocol_id.length > 1)
236      {
237        var id = Math.abs(parseInt(frm.protocol_id[1].value));       
238        url += '&item_id='+id;
239      }
240      url += '&filter:INT:protocolType=<%=SystemItems.getId(ProtocolType.EXTRACTION)%>';
241      Main.openPopup(url, 'SelectProtocol', 1000, 700);
242    }
243    function setProtocolCallback(id, name)
244    {
245      var frm = document.forms['extract'];
246      var list = frm.protocol_id;
247      if (list.length < 2 || list[1].value == '0') // >
248      {
249        Forms.addListOption(list, 1, new Option());
250      }
251      list[1].value = id;
252      list[1].text = name;
253      list.selectedIndex = 1;
254    }
255   
256    function pooledOnClick()
257    {
258      var frm = document.forms['extract'];
259      var isPooled = frm.pooled[1].checked
260      frm.sample_id.disabled = isPooled;
261      frm.used_from_sample.disabled = isPooled;
262      frm.extracts.disabled = !isPooled;
263      frm.used_quantity.disabled = !isPooled;
264      parentsChanged = true;
265    }
266    function sampleOnChange()
267    {
268      parentsChanged = true;
269    }
270   
271    function selectSampleOnClick()
272    {
273      var frm = document.forms['extract'];
274      if (frm.pooled[1].checked)
275      {
276        alert('This is a pooled extract, which cannot have a sample as it\'s parent');
277        return;
278      }
279      var url = '../samples/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setSampleCallback';
280      if (frm.sample_id.length > 1)
281      {
282        var id = Math.abs(parseInt(frm.sample_id[1].value));       
283        url += '&item_id='+id;
284      }
285      Main.openPopup(url, 'SelectSample', 1000, 700);
286    }
287    function setSampleCallback(id, name)
288    {
289      var frm = document.forms['extract'];
290      var list = frm.sample_id;
291      if (list.length < 2 || list[1].value == '0') // >
292      {
293        Forms.addListOption(list, 1, new Option());
294      }
295      list[1].value = id;
296      list[1].text = name;
297      list.selectedIndex = 1;
298      parentsChanged = true;
299    }
300   
301    function addExtractsOnClick()
302    {
303      var frm = document.forms['extract'];
304      if (!frm.pooled[1].checked)
305      {
306        alert('This is not a pooled extract');
307        return;
308      }
309      Main.openPopup('index.jsp?ID=<%=ID%>&mode=selectmultiple&callback=addExtractCallback', 'AddExtracts', 1000, 700);
310    }
311   
312    function addExtractCallback(extractId, name)
313    {
314      var item = Link.getItem('E', extractId);
315      if (!item) item = new Item('E', extractId, name+' [-]', '', '');
316      Link.addItem(document.forms['extract'].extracts, item);
317      parentsChanged = true;
318    }
319    function extractsOnChange()
320    {
321      var frm = document.forms['extract'];
322      var item = frm.extracts[frm.extracts.selectedIndex].item;
323      if (item && item.id)
324      {
325        frm.used_quantity.value = item.value;
326        frm.used_quantity.focus();
327      }
328      else
329      {
330        frm.used_quantity.value = '';
331      }
332    }
333    function usedQuantityOnBlur()
334    {
335      var frm = document.forms['extract'];
336      var usedQuantity = frm.used_quantity.value;
337      usedQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
338      for (var i = 0; i < frm.extracts.length; i++) // >
339      {
340        var option = frm.extracts[i];
341        if (option.selected && option.item.id)
342        {
343          option.item.value = usedQuantity;
344          var text = option.text.replace(/\[.*\]/, '['+usedQuantity+']');
345          option.text = text;
346        }
347      }
348    }
349    function usedFromSampleOnBlur()
350    {
351      var frm = document.forms['extract'];
352     
353      var sampleId = parseInt(frm.sample_id[frm.sample_id.selectedIndex].value);
354      if (sampleId < 0)
355      {
356        frm.sample_id[frm.sample_id.selectedIndex].value = -sampleId;
357      }
358    }
359   
360
361    function removeOnClick()
362    {
363      Link.removeSelected(document.forms['extract'].extracts);
364      parentsChanged = true;
365    }
366
367    function init()
368    {
369      <%
370      if (extract == null)
371      {
372        %>
373        var frm = document.forms['extract'];
374        frm.name.focus();
375        frm.name.select();
376        <%
377      }
378      %>
379      initExtracts();
380      pooledOnClick();
381    }
382    function initExtracts()
383    {
384      var extracts = document.forms['extract'].extracts;
385      <%
386      if (extract != null && extract.isPooled())
387      {
388        ItemResultList<Extract> extracts = extractsQuery.list(dc);
389        for (Extract e : extracts)
390        {
391          String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(e), -1);
392          %>
393          Link.addNewItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
394          <%
395        }
396      }
397      else if (extract == null && Values.getBoolean(request.getParameter("pooled")))
398      {
399        for (int eId : cc.getSelected())
400        {
401          Extract extractToPool = Extract.getById(dc, eId);
402          %>
403          Link.addItem(extracts, new Item('E', <%=extractToPool.getId()%>, '<%=HTML.javaScriptEncode(extractToPool.getName())%> [-]', '', ''));
404          <%
405        }
406      }
407      %>
408    }
409    </script>
410  </base:head>
411  <base:body onload="init()">
412    <p>
413    <form action="index.jsp?ID=<%=ID%>" method="post" name="extract" onsubmit="return false;">
414    <input type="hidden" name="cmd" value="UpdateItem">
415
416    <h3 class="docked"><%=title%> <base:help tabcontrol="settings" /></h3>
417    <t:tabcontrol id="settings" contentstyle="<%="height: "+(int)(scale*370)+"px;"%>" 
418      position="bottom"  remember="<%=extract != null%>" switch="switchTab">
419    <t:tab id="info" title="Extract" validate="validateExtract()" helpid="extract.edit">
420      <table class="form" cellspacing=0>
421      <tr>
422        <td class="prompt">Name</td>
423        <td><input <%=requiredClazz%> type="text" name="name" 
424          value="<%=HTML.encodeTags(name)%>" 
425          size="40" maxlength="<%=Extract.MAX_NAME_LENGTH%>"></td>
426      </tr>
427      <tr>
428        <td class="prompt">External ID</td>
429        <td><input <%=clazz%> type="text" name="external_id" 
430          value="<%=HTML.encodeTags(extract == null ? Values.getString(cc.getPropertyValue("externalId"), "") : extract.getExternalId())%>" 
431          size="40" maxlength="<%=Extract.MAX_EXTERNAL_ID_LENGTH%>"></td>
432      </tr>
433      <tr>
434        <td class="prompt">Original quantity</td>
435        <td><input <%=clazz%> type="text" name="original_quantity" 
436          value="<%=Values.formatNumber(extract == null ? Values.getFloat(cc.getPropertyValue("originalQuantity"), null): extract.getOriginalQuantity(), -1)%>" size="12" 
437          maxlength="10" onkeypress="return Numbers.numberOnly(event)"> (µg)</td>
438      </tr>
439      <tr>
440        <td class="prompt">Remaining quantity</td>
441        <td><%=Values.formatNumber(extract == null ? null : extract.getRemainingQuantity(), 2, " µg")%></td>
442      </tr>
443      <tr>
444        <td class="prompt">Created</td>
445        <td>
446          <table border="0" cellspacing="0" cellpadding="0">
447          <tr>
448          <td>
449            <input <%=clazz%> type="text" name="event_date" 
450              value="<%=Values.formatDate(creationEvent == null ? Values.getDate(cc.getPropertyValue("creationEvent.eventDate"), new Date()): creationEvent.getEventDate())%>" 
451              size="12" maxlength="10" onkeypress="return Dates.dateOnly(event)">
452            (yyyy-mm-dd)&nbsp;
453          </td>
454          <td>
455          <base:button 
456            onclick="Dates.selectDate('Date', 'extract', 'event_date')"
457            image="calendar.png" 
458            title="Calendar&hellip;" 
459            tooltip="Select a date from a calendar" 
460          />
461          </td>
462          </tr>
463          </table>
464        </td>
465      </tr>
466      <tr>
467        <td class="prompt">Registered</td>
468        <td><%=Values.formatDate(creationEvent == null ? new Date() : creationEvent.getEntryDate())%></td>
469      </tr>
470      <tr>
471        <td class="prompt">Protocol</td>
472        <td>
473          <base:select 
474            id="protocol_id"
475            clazz="selectionlist"
476            required="false"
477            current="<%=currentProtocol%>"
478            denied="<%=!readCurrentProtocol%>"
479            recent="<%=recentProtocols%>"
480            newitem="<%=extract == null%>"
481            onselect="selectProtocolOnClick()"
482          />
483        </td>
484      </tr>
485      <tr valign=top>
486        <td class="prompt">Description</td>
487        <td nowrap>
488          <textarea <%=clazz%> rows="4" cols="40" name="description" wrap="virtual"
489            ><%=HTML.encodeTags(extract == null ? cc.getPropertyValue("description") : extract.getDescription())%></textarea>
490          <a href="javascript:Main.zoom('Description', 'extract', 'description')"
491            title="Edit in larger window"><base:icon image="zoom.gif" /></a>
492        </td>
493      </tr>
494      </table>
495      <div align=right>&nbsp;<i><base:icon image="required.gif" /> = required information</i></div>
496    </t:tab>
497   
498    <t:tab id="parents" title="Parents" helpid="extract.parent">
499      <table class="form" cellspacing=0>
500      <tr>
501        <td class="prompt">Pooled</td>
502        <td>
503          <input type="radio" name="pooled" value="0" onclick="pooledOnClick()"
504            <%=!isPooled ? "checked" : ""%>
505            >no
506          <input type="radio" name="pooled" value="1" onclick="pooledOnClick()"
507            <%=isPooled ? "checked" : ""%>
508            >yes
509        </td>
510      </tr>
511      <tr valign="top">
512        <td class="prompt">Sample</td>
513        <td>
514          <base:select 
515            id="sample_id"
516            clazz="selectionlist"
517            required="false"
518            current="<%=currentSample%>"
519            denied="<%=!readCurrentSample%>"
520            recent="<%=recentSamples%>"
521            selectrecent="false"
522            newitem="<%=extract == null%>"
523            onselect="selectSampleOnClick()"
524            onchange="sampleOnChange()"
525          />
526          Used
527          <input <%=clazz%> type="text" name="used_from_sample" value="<%=Values.formatNumber(usedFromSample, -1)%>"
528            size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
529            onblur="usedFromSampleOnBlur()"> (µg)
530        </td>
531      </tr>
532      <tr valign="top">
533        <td class="prompt">Extracts</td>
534        <td>
535          <table border="0" cellspacing="0" cellpadding="0">
536          <tr valign="top">
537          <td>
538            <select name="extracts" size="5" multiple style="width: 20em;" 
539              onchange="extractsOnChange()">
540            </select>&nbsp;<br>
541            Used
542            <input <%=clazz%> type="text" name="used_quantity" value=""
543              size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
544              onkeyup="usedQuantityOnBlur()"
545            > (µg)
546            <input type="hidden" name="modifiedExtracts" value="">
547            <input type="hidden" name="removedExtracts" value="">
548          </td>
549          <td>
550            <table border="0">
551            <tr><td width="150"><base:button 
552              onclick="addExtractsOnClick()" 
553              title="Add&nbsp;extracts&hellip;" 
554              tooltip="Add extracts"
555              /></td></tr>
556            <tr><td width="150"><base:button 
557              onclick="removeOnClick()" 
558              title="Remove" 
559              tooltip="Remove the selected extracts"
560            /></td></tr>
561            </table>
562          </td>
563          </tr>
564          </table>
565        </td>
566      </tr>
567      </table>
568    </t:tab>
569
570    <t:tab id="annotations" title="Annotations" helpid="annotations.edit">
571      <iframe name="annotations" id="idAnnotations" src="../../common/annotations/wait.jsp" 
572        width="100%"  height="<%=(int)(scale*370)%>" frameborder=0 vspace=0 hspace=0
573        marginwidth=0 marginheight=0 scrolling="auto" style="overflow: visible"></iframe>
574    </t:tab>
575   
576    <t:tab id="inheritedAnnotations" title="Inherited annotations" helpid="annotations.edit.inherited">
577   
578      <iframe name="inheritedAnnotations" id="idInheritedAnnotations" src="../../common/annotations/wait.jsp" 
579        width="100%"  height="<%=(int)(scale*370)%>" frameborder=0 vspace=0 hspace=0
580        marginwidth=0 marginheight=0 scrolling="auto" style="overflow: visible"></iframe>
581    </t:tab>
582    </t:tabcontrol>
583
584    <table align="center">
585    <tr>
586      <td width="50%"><base:button onclick="saveSettings()" title="Save" /></td>
587      <td width="50%"><base:button onclick="window.close()" title="Cancel" /></td>
588    </tr>
589    </table>
590    </form>
591  </base:body>
592  </base:page>
593  <%
594}
595finally
596{
597  if (dc != null) dc.close();
598}
599%>
Note: See TracBrowser for help on using the repository browser.