source: extensions/net.sf.basedb.reggie/branches/2.15-stable/resources/libprep/mrna_registration.jsp @ 2504

Last change on this file since 2504 was 2504, checked in by Nicklas Nordborg, 9 years ago

References #604: New wizard "RNA dilution registration"

The lab protocol wizard now display dilution date and operator if it exists.

The mRNA registration wizard now only list plates that has a dilution date set and the dilution date/operator has been removed from that wizard.

Added link to the new wizard on the index page. The counters have been updated to count only plates with/without dilution date.

File size: 18.8 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.User"
5  import="net.sf.basedb.core.DbControl"
6  import="net.sf.basedb.core.SessionControl"
7  import="net.sf.basedb.core.Application"
8  import="net.sf.basedb.clients.web.Base" 
9  import="net.sf.basedb.clients.web.util.HTML" 
10  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
11%>
12<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
13<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
14<%
15final SessionControl sc = Base.getExistingSessionControl(request, true);
16final String ID = sc.getId();
17final float scale = Base.getScale(sc);
18final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
19DbControl dc = null;
20try
21{
22  dc = sc.newDbControl();
23  final User user = User.getById(dc, sc.getLoggedInUserId());
24%>
25<base:page type="default" >
26<base:head scripts="ajax.js" styles="path.css">
27  <link rel="stylesheet" type="text/css" href="../css/reggie.css">
28  <script language="JavaScript" src="../reggie.js" type="text/javascript" charset="UTF-8"></script>
29
30<script language="JavaScript">
31
32var MRNA_QC_FILES_PATH = '/home/SCANB/MRnaPlateQC';
33var firstBrowse = true;
34var subtypeBioAnalyzerPdf;
35
36var debug = false;
37var currentStep = 1;
38
39var dateIsValid = [];
40
41var pdfIsValid = false;
42var commentsIsValid = false;
43
44function init()
45{
46  var frm = document.forms['reggie'];
47  var bioplates = getMRnaBioPlates();
48 
49  // Load existing mRNA plates not yet registered
50  var plates = frm.bioplate;
51  if (bioplates != null && bioplates.length > 0)
52  {
53    for (var i=0; i < bioplates.length; i++)
54    {
55      var bioplate = bioplates[i];
56      var option = new Option(bioplate.name, bioplate.id);
57      option.comments = bioplate.comments;
58      plates.options[plates.length] = option;
59    }
60    bioplateIsValid = true;
61    setInputStatus('bioplate', '', 'valid');
62    bioPlateOnChange();
63    outcomeOnChange();
64  }
65  else
66  {
67    var msg = 'No mRNA bioplates available for processing.';
68    setFatalError(msg);
69    return;
70  }
71
72  // All is ok
73  frm.bioplate.focus();
74}
75
76
77function goNextAuto()
78{
79  goNext(false);
80}
81
82function goNext(manual)
83{
84  setInnerHTML('gonext.message', '');
85  if (currentStep == 1)
86  {   
87    gotoStep2();
88  }
89  setCurrentStep(currentStep);
90}
91
92
93
94function getMRnaBioPlates()
95{
96  var frm = document.forms['reggie']; 
97 
98  var request = Ajax.getXmlHttpRequest();
99  try
100  {
101    showLoadingAnimation('Loading histology work lists...');
102    var url = '../MRna.servlet?ID=<%=ID%>&cmd=GetUnprocessedPlates&plateType=MRNA&onlyDiluted=1';   
103    request.open("GET", url, false); 
104    request.send(null);
105  }
106  finally
107  {
108    hideLoadingAnimation();
109  }
110 
111  if (debug) Main.debug(request.responseText);
112  var response = JSON.parse(request.responseText); 
113  if (response.status != 'ok')
114  {
115    setFatalError(response.message);
116    return false;
117  }
118  return response.bioplates;
119}
120
121function gotoStep2()
122{
123  var frm = document.forms['reggie']; 
124  frm.bioplate.disabled = true;
125  frm.outcome[0].disabled = true;
126  frm.outcome[1].disabled = true;
127
128 
129  currentStep = 2;
130  Main.show('step.2.section');
131  Main.addClass(document.getElementById('step.1.section'), 'disabled');
132  Main.hide('gonext');
133  Main.show('gocancel');
134  Main.show('goregister');
135 
136  // Load mRNA protocols
137  var mrnaProtocols = getProtocols('MRNA_PROTOCOL');
138  for (var i = 0; i < mrnaProtocols.length; i++)
139  {
140    var protocol = mrnaProtocols[i];
141    frm.mrnaProtocol[frm.mrnaProtocol.length] = new Option(protocol.name, protocol.id, protocol.isDefault);
142    setInputStatus('mrnaProtocol', '', 'valid');
143  }
144  if (frm.mrnaProtocol.length == 0)
145  {
146    frm.mrnaProtocol[0] = new Option('- none -', '');
147  }
148
149  if (document.getElementById('outcomeFailed').checked)
150  {
151    setInnerHTML('gonext.message', '<input type="checkbox" name="verifyFailure" onclick="verifyFailureOnClick()"> Check to verify registration of failure');
152    Main.addClass(document.getElementById('goregister'), 'disabled');
153  }
154 
155  frm.purificationDate.focus();
156}
157
158function getProtocols(subtype)
159{
160  var request = Ajax.getXmlHttpRequest();
161  try
162  {
163    showLoadingAnimation('Loading ' + subtype + ' protocols...');
164    var url = '../Protocol.servlet?ID=<%=ID%>&cmd=GetProtocols&subtype='+subtype;   
165    request.open("GET", url, false); 
166    request.send(null);
167  }
168  finally
169  {
170    hideLoadingAnimation();
171  }
172
173  if (debug) Main.debug(request.responseText);
174  var response = JSON.parse(request.responseText); 
175  if (response.status != 'ok')
176  {
177    setFatalError(response.message);
178    return false;
179  }
180  return response.protocols;
181}
182
183function bioPlateOnChange()
184{
185  var frm = document.forms['reggie'];
186  frm.comments.value = frm.bioplate[frm.bioplate.selectedIndex].comments;
187  commentsOnChange();
188}
189
190function outcomeOnChange()
191{
192  var frm = document.forms['reggie'];
193  Main.addOrRemoveClass(frm['pdf.path'], 'required', document.getElementById('outcomeSuccess').checked);
194  Main.addOrRemoveClass(frm['comments'], 'required', document.getElementById('outcomeFailed').checked);
195  pdfFileOnChange();
196  commentsOnChange();
197}
198
199function browseOnClick(extension)
200{
201  var frm = document.forms['reggie'];
202  if (frm[extension+'.path'].disabled) return;
203  if (firstBrowse)
204  {
205    firstBrowse = false;
206    setCurrentDirectory('<%=ID%>', MRNA_QC_FILES_PATH, debug, '../');
207    subtypeBioAnalyzerPdf = getSubtypeInfo('<%=ID%>', 'BIOANALYZER_PDF', debug, '../');
208  }
209  var url = getRoot() + 'filemanager/index.jsp?ID=<%=ID%>&cmd=SelectOne&callback=setFileCallback';
210  url += '&resetTemporary=1&tmpfilter:STRING:name='+escape('%.' + extension.substr(0, 3));
211  if (subtypeBioAnalyzerPdf)
212  {
213    url += '&tmpfilter:INT:itemSubtype='+subtypeBioAnalyzerPdf.id;
214  }
215  lastExtension = extension;
216  Main.openPopup(url, 'SelectFile', 1000, 700);
217}
218
219function setFileCallback(id, path)
220{
221  var frm = document.forms['reggie'];
222  frm[lastExtension+'.id'].value = id;
223  frm[lastExtension+'.path'].value = path;
224  setInputStatus(lastExtension, '', 'valid');
225  if (lastExtension == 'pdf')
226  {
227    pdfIsValid = true;
228  }
229}
230
231function pdfFileOnChange()
232{
233  var frm = document.forms['reggie'];
234  if (!frm['pdf.id'].value)
235  {
236    var outcomeSuccess = document.getElementById('outcomeSuccess');
237    pdfIsValid = false;
238    // A PDF is reuired for successful registration, optional after a failure
239    var status = outcomeSuccess.checked ? 'invalid' : 'warning';
240    if (!frm['pdf.path'].value)
241    {
242      setInputStatus('pdf', 'Missing', status);
243      pdfIsValid = !outcomeSuccess.checked;
244    }
245    else
246    {
247      setInputStatus('pdf', 'Use the Browse button to select a file', 'invalid');
248    }
249  }
250}
251
252function dateOnChange(dateField)
253{
254  var frm = document.forms['reggie'];
255
256  setInputStatus(dateField, '', '');
257  dateIsValid[dateField] = true;
258  var date = frm[dateField].value;
259
260  if (date == '')
261  {
262    setInputStatus(dateField, 'Missing date', 'warning');
263    return;
264  }
265
266  // Auto-fill the date if it's only given with 4(MMdd) or 6(yyMMdd) digits.   
267  date = autoFillDate(date);
268  frm[dateField].value = date;
269  if (!Dates.isDate(date, 'yyyyMMdd'))
270  {
271    setInputStatus(dateField, 'Not a valid date', 'invalid');
272    dateIsValid[dateField] = false;
273    return;
274  }
275 
276  setInputStatus(dateField, '', 'valid');
277}
278
279function setDate(frmName, dateField, date)
280{
281  var frm = document.forms['reggie'];
282  frm[dateField].value = date;
283  dateOnChange(dateField);
284  frm[dateField].focus();
285}
286
287function commentsOnChange()
288{
289  var frm = document.forms['reggie'];
290  commentsIsValid = false;
291  setInputStatus('comments', '', '');
292 
293  var comments = frm.comments.value;
294 
295  if (comments == '' && document.getElementById('outcomeFailed').checked)
296  {
297    setInputStatus('comments', 'Missing', 'invalid');
298    return;
299  }
300
301  setInputStatus('comments', '', 'valid');
302  commentsIsValid = true;
303}
304
305function step2IsValid()
306{
307  var frm = document.forms['reggie'];
308  if (!pdfIsValid || !commentsIsValid) return false;
309 
310  if (dateIsValid['purificationDate'] == false) return false;
311  if (dateIsValid['fragmentationDate'] == false) return false;
312  if (dateIsValid['cleanupDate'] == false) return false;
313 
314  if (document.getElementById('outcomeFailed').checked && !frm.verifyFailure.checked) return false;
315 
316  return true;
317}
318
319function verifyFailureOnClick()
320{
321  var frm = document.forms['reggie'];
322  var checked = frm.verifyFailure.checked;
323  Main.addOrRemoveClass(document.getElementById('goregister'), 'disabled', !checked);
324}
325
326function goRegister()
327{
328  if (!step2IsValid()) return;
329
330  var frm = document.forms['reggie'];
331  var pdfId = parseInt(frm['pdf.id'].value, 10);
332 
333  Main.hide('goregister');
334  Main.hide('gocancel');
335  Main.hide('gonext.message');
336  Main.addClass(document.getElementById('step.2.section'), 'disabled');
337
338  frm['pdf.path'].disabled = true;
339  Main.addClass(document.getElementById('btnPdf'), 'disabled');
340  frm.purificationDate.disabled = true;
341  frm.purificationOperator.disabled = true;
342  frm.fragmentationDate.disabled = true;
343  frm.fragmentationOperator.disabled = true;
344  frm.cleanupDate.disabled = true;
345  frm.cleanupOperator.disabled = true;
346  frm.mrnaProtocol.disabled = true;
347  frm.comments.disabled = true;
348 
349  var submitInfo = {};
350  submitInfo.bioplate = parseInt(frm.bioplate.value, 10);
351  submitInfo.mrnaProtocol = parseInt(frm.mrnaProtocol.value, 10);
352  submitInfo.failed = document.getElementById('outcomeSuccess').checked ? false : true;
353  submitInfo.pdf = pdfId;
354  submitInfo.purificationDate = frm.purificationDate.value;
355  submitInfo.purificationOperator = frm.purificationOperator.value;
356  submitInfo.fragmentationDate = frm.fragmentationDate.value;
357  submitInfo.fragmentationOperator = frm.fragmentationOperator.value;
358  submitInfo.cleanupDate = frm.cleanupDate.value;
359  submitInfo.cleanupOperator = frm.cleanupOperator.value;
360  submitInfo.comments = frm.comments.value;
361 
362  if (debug) Main.debug(JSON.stringify(submitInfo));
363  var url = '../MRna.servlet?ID=<%=ID%>&cmd=ImportMRnaQCResults';
364 
365  var request = Ajax.getXmlHttpRequest();
366  try
367  {
368    showLoadingAnimation('Performing registration...');
369    request.open("POST", url, false);
370    request.send(JSON.stringify(submitInfo));
371  }
372  finally
373  {
374    hideLoadingAnimation();
375  }
376 
377  if (debug) Main.debug(request.responseText);
378  var response = JSON.parse(request.responseText);
379 
380  if (response.messages && response.messages.length > 0)
381  {
382    var msg = '<ul>';
383    for (var i = 0; i < response.messages.length; i++)
384    {
385      var msgLine = response.messages[i];
386      if (msgLine.indexOf('[Warning]') >= 0)
387      {
388        msg += '<li class="warning">' + msgLine.replace('[Warning]', '');
389      }
390      else
391      {
392        msg += '<li>' + msgLine;
393      }
394    }
395    msg += '</ul>';
396    setInnerHTML('messages', msg);
397    Main.show('messages');
398  }
399 
400  if (response.status != 'ok')
401  {
402    Main.addClass(document.getElementById('messages'), 'failure');
403    setFatalError(response.message);
404    return false;
405  }
406
407  Main.show('gorestart');
408}
409
410
411</script>
412
413</base:head>
414<base:body onload="init()">
415
416  <p:path><p:pathelement 
417    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
418    /><p:pathelement title="mRNA registration and quality control results" 
419    /></p:path>
420
421  <div class="content">
422  <%
423  if (sc.getActiveProjectId() == 0)
424  {
425    %>
426    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
427      No project has been selected. You may proceed with the registration but
428      created items will not be shared.
429    </div>
430    <%
431  }
432  %>
433
434  <form name="reggie" onsubmit="return false;">
435    <input type="hidden" name="pdf.id" value="">
436 
437  <div id="step.1.section">
438  <table class="stepform">
439  <tr>
440    <td rowspan="3" class="stepno">1</td>
441    <td class="steptitle">Select mRNA bioplate</td>
442  </tr>
443  <tr>
444    <td class="stepfields">
445      <table>
446      <tr valign="top">
447        <td class="prompt">mRNA bioplate</td>
448        <td class="input"><select class="required" style="width:90%;" 
449            name="bioplate" id="bioplate" onchange="bioPlateOnChange()"></select>
450        </td>
451        <td class="status" id="bioplate.status"></td>
452        <td class="help"><span id="bioplate.message" class="message" style="display: none;"></span>
453          Select an existing mRNA bioplate. The list contain all mRNA bioplates that
454          has been diluted, but not yet registered as completed (determined by the absence of a
455          'creation' date).
456        </td>
457      </tr>
458      <tr valign="top">
459        <td class="prompt">Outcome</td>
460        <td class="input">
461          <input type="radio" name="outcome" id="outcomeSuccess" 
462            onchange="outcomeOnChange()" checked><label for="outcomeSuccess">Success</label> - continue processing to cDNA<br>
463          <input type="radio" name="outcome" id="outcomeFailed" 
464            onchange="outcomeOnChange()"><label for="outcomeFailed">Failure</label> - no further processing to cDNA
465        </td>
466        <td class="status"></td>
467        <td class="help">
468          Select the <b>Failure</b> option if further processing to cDNA is not possible.
469          No child cDNA plate will be created and existing RNA will be flagged and added
470          to the <b>Flagged RNA</b> list.
471        </td>
472      </tr>
473      </table>
474    </td>
475  </tr>
476  </table>
477  </div>
478 
479  <div id="step.2.section" style="display: none;">
480  <table class="stepform">
481  <tr>
482    <td rowspan="3" class="stepno">2</td>
483    <td class="steptitle">mRNA preparation information</td>
484  </tr>
485  <tr>
486    <td class="stepfields">
487      <table>
488      <tr valign="top">
489        <td class="prompt">Step</td>
490        <td style="width: 11em;"><b>Date</b></td>
491        <td><b>Operator</b></td>
492        <td class="status"></td>
493        <td class="help" rowspan="4">
494          <span id="mrnaDate.message" class="message" style="display: none;"></span>
495          Enter date and operator for each step in the mRNA preparation.
496          (YYYYMMDD or MMDD)
497        </td>
498      </tr>
499      <tr>
500        <td class="subprompt">Purification</td>
501        <td>
502          <input type="text" name="purificationDate" maxlength="10" style="width: 8em;"
503            onblur="dateOnChange('purificationDate')" onkeypress="focusOnEnter(event, 'purificationOperator')">
504            <base:icon 
505              onclick="Dates.selectDate('Purification date', 'reggie', 'purificationDate', 'setDate', 'yyyyMMdd')"
506              image="calendar.png" 
507              tooltip="Select a date from a calendar" 
508              tabindex="-1"
509            />
510        </td>
511        <td>
512          <input type="text" name="purificationOperator" value="<%=HTML.encodeTags(user.getName()) %>" 
513            style="width: 95%;" maxlength="255" onkeypress="focusOnEnter(event, 'fragmentationDate')">
514        </td>
515        <td class="status" id="purificationDate.status"></td>
516      </tr>
517      <tr>
518        <td class="subprompt">Fragmentation</td>
519        <td>
520          <input type="text" name="fragmentationDate" maxlength="10" style="width: 8em;"
521            onblur="dateOnChange('fragmentationDate')" onkeypress="focusOnEnter(event, 'fragmentationOperator')">
522            <base:icon 
523              onclick="Dates.selectDate('Fragmentation date', 'reggie', 'fragmentationDate', 'setDate', 'yyyyMMdd')"
524              image="calendar.png" 
525              tooltip="Select a date from a calendar" 
526              tabindex="-1"
527            />
528        </td>
529        <td>
530          <input type="text" name="fragmentationOperator" value="<%=HTML.encodeTags(user.getName()) %>" 
531            style="width: 95%;" maxlength="255" onkeypress="focusOnEnter(event, 'cleanupDate')">
532        </td>
533        <td class="status" id="fragmentationDate.status"></td>
534      </tr>
535      <tr>
536        <td class="subprompt">Cleanup</td>
537        <td>
538          <input type="text" name="cleanupDate" maxlength="10" style="width: 8em;"
539            onblur="dateOnChange('cleanupDate')" onkeypress="focusOnEnter(event, 'cleanupOperator')">
540            <base:icon 
541              onclick="Dates.selectDate('Cleanup date', 'reggie', 'cleanupDate', 'setDate', 'yyyyMMdd')"
542              image="calendar.png" 
543              tooltip="Select a date from a calendar" 
544              tabindex="-1"
545            />
546        </td>
547        <td>
548          <input type="text" name="cleanupOperator" value="<%=HTML.encodeTags(user.getName()) %>" 
549            style="width: 95%;" maxlength="255" onkeypress="focusOnEnter(event, 'pdf.path')">
550        </td>
551        <td class="status" id="cleanupDate.status"></td>
552      </tr>
553      <tr valign="top">
554        <td class="prompt">BA PDF file</td>
555        <td class="input" colspan="2">
556          <table>
557          <tr>
558          <td><input class="text required" type="text" 
559            name="pdf.path" value=""
560            size="50" onkeypress="doOnEnter(event, function(){document.getElementById('btnPdf').click()})"
561            onblur="pdfFileOnChange()"
562            ></td>
563          <td style="padding-left: 4px;"><base:button 
564              title="Browse&hellip;"
565              onclick="browseOnClick('pdf')"
566              id="btnPdf"
567              />
568          </td>
569          </tr>
570          </table>
571        </td>
572        <td class="status" id="pdf.status"></td>
573        <td class="help"><span id="pdf.message" class="message" style="display: none;"></span>
574          Select the <b>BioAnalyzer PDF file</b> that contains a printout with diagrams and other
575          useful documentation.
576        </td>
577      </tr>
578      <tr valign="top">
579        <td class="prompt">Protocol</td>
580        <td class="input" colspan="2"><select style="width:90%" name="mrnaProtocol" id="mrnaProtocol" 
581          onkeypress="focusOnEnter(event, 'mrnaOperator')"></select></td>
582        <td class="status" id="mrnaProtocol.status"></td>
583        <td class="help"><span id="mrnaProtocol.message" class="message" style="display: none;"></span>
584          Select the protocol which was used in the mRNA preparation.
585        </td>
586      </tr>
587      <tr valign="top">
588        <td class="prompt">Comments</td>
589        <td class="input" colspan="2"><textarea rows="4" cols="50" style="width: 90%;" name="comments" value="" onblur="commentsOnChange()"></textarea></td>
590        <td class="status" id="comments.status"></td>
591        <td class="help"><span id="comments.message" class="message" style="display: none;"></span>Comments about the mRNA processing.</td>
592      </tr>
593      </table>
594    </td>
595  </tr>
596  </table>
597  </div>
598 
599  <div class="loading" id="loading" style="display: none;"><table><tr><td><img src="../images/loading.gif"></td><td id="loading.msg">Please wait...</td></tr></table></div>
600 
601  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
602 
603  <div id="messages" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
604 
605  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
606    <tr>
607      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
608      <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
609      <td><base:button id="goregister" title="Register" image="<%=home+"/images/import.png"%>" onclick="goRegister()" style="display: none;"/></td>
610      <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
611      <td id="gonext.message" class="message"></td>
612    </tr>
613  </table>
614 
615  </form>
616  </div>
617 
618</base:body>
619</base:page>
620<%
621}
622finally
623{
624  if (dc != null) dc.close();
625}
626%>
Note: See TracBrowser for help on using the repository browser.