source: extensions/net.sf.basedb.reggie/trunk/resources/libprep/lib_registration.jsp @ 1968

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

References #473: Register library processing results

Swithced order of file selection so that the Qubit file is selected first. This makes it possible to validate that file at the same time the Caliper Well Table file is validated.

File size: 23.0 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">
31var debug = false;
32var currentStep = 1;
33
34var libDateIsValid = false;
35var wellTableIsValid = false;
36var qubitCsvIsValid = false;
37var libCommentsIsValid = false;
38
39function init()
40{
41  var frm = document.forms['reggie'];
42  var bioplates = getLibraryBioPlates();
43 
44  // Load existing Library plates not yet registered
45  var plates = frm.bioplate;
46  if (bioplates != null && bioplates.length > 0)
47  {
48    for (var i=0; i < bioplates.length; i++)
49    {
50      var bioplate = bioplates[i];
51      var option = new Option(bioplate.name, bioplate.id);
52      option.comments = bioplate.comments;
53      plates.options[plates.length] = option;
54    }
55    bioplateIsValid = true;
56    setInputStatus('bioplate', '', 'valid');
57    bioPlateOnChange();
58    outcomeOnChange();
59  }
60  else
61  {
62    var msg = 'No Library bioplates available for processing.';
63    setFatalError(msg);
64    return;
65  }
66
67  // All is ok
68  frm.bioplate.focus();
69}
70
71
72function goNextAuto()
73{
74  goNext(false);
75}
76
77function goNext(manual)
78{
79  setInnerHTML('gonext.message', '');
80  if (currentStep == 1)
81  {   
82    gotoStep2();
83  }
84  setCurrentStep(currentStep);
85}
86
87
88
89function getLibraryBioPlates()
90{
91  var frm = document.forms['reggie']; 
92 
93  var request = Ajax.getXmlHttpRequest();
94  try
95  {
96    showLoadingAnimation('Loading Library bioplates...');
97    var url = '../LibPrep.servlet?ID=<%=ID%>&cmd=GetLibraryPlatesForLibPrep';   
98    request.open("GET", url, false); 
99    request.send(null);
100  }
101  finally
102  {
103    hideLoadingAnimation();
104  }
105 
106  if (debug) Main.debug(request.responseText);
107  var response = JSON.parse(request.responseText); 
108  if (response.status != 'ok')
109  {
110    setFatalError(response.message);
111    return false;
112  }
113  return response.bioplates;
114}
115
116function gotoStep2()
117{
118  var frm = document.forms['reggie']; 
119  frm.bioplate.disabled = true;
120  frm.outcome[0].disabled = true;
121  frm.outcome[1].disabled = true;
122 
123  currentStep = 2;
124  Main.addClass(document.getElementById('step.1.section'), 'disabled');
125  Main.hide('gonext');
126  Main.show('gocancel');
127  Main.show('goregister');
128 
129  var libInfo = getStoredInfo(frm.bioplate.value);
130  if (libInfo)
131  {
132    if (debug) Main.debug(JSON.stringify(libInfo));
133    var failed = document.getElementById('outcomeFailed').checked
134   
135    if (libInfo.libDate) 
136    {
137      frm.libDate.value = libInfo.libDate;
138      libDateOnChange();
139    }
140    if (!failed)
141    {
142      if (libInfo.wellTable.id && libInfo.wellTable.path)
143      {
144        lastPrefix = 'welltable';
145        setFileCallback(libInfo.wellTable.id, libInfo.wellTable.path);
146      }
147      if (libInfo.caliperGxd.id && libInfo.caliperGxd.path)
148      {
149        lastPrefix = 'calipergxd';
150        setFileCallback(libInfo.caliperGxd.id, libInfo.caliperGxd.path);
151      }
152      if (libInfo.caliperPdf.id && libInfo.caliperPdf.path)
153      {
154        lastPrefix = 'caliperpdf';
155        setFileCallback(libInfo.caliperPdf.id, libInfo.caliperPdf.path);
156      }
157      if (libInfo.qubitCsv.id && libInfo.qubitCsv.path)
158      {
159        lastPrefix = 'qubitcsv';
160        setFileCallback(libInfo.qubitCsv.id, libInfo.qubitCsv.path);
161      }
162    }
163    if (libInfo.libOperator) frm.libOperator.value = libInfo.libOperator;
164    if (libInfo.libComments) 
165    {
166      frm.libComments.value = libInfo.libComments;
167      libDateOnChange();
168    }
169  }
170 
171  Main.show('step.2.section');
172  frm.libDate.focus();
173
174  // Load Library protocols
175  var libProtocols = getProtocols('LIBRARY_PROTOCOL');
176  for (var i = 0; i < libProtocols.length; i++)
177  {
178    var protocol = libProtocols[i];
179    frm.libProtocol[frm.libProtocol.length] = new Option(protocol.name, protocol.id, protocol.isDefault);
180    setInputStatus('libProtocol', '', 'valid');
181  }
182  if (frm.libProtocol.length == 0)
183  {
184    frm.libProtocol[0] = new Option('- none -', '');
185  }
186}
187
188function getProtocols(subtype)
189{
190  var request = Ajax.getXmlHttpRequest();
191  try
192  {
193    showLoadingAnimation('Loading ' + subtype + ' protocols...');
194    var url = '../Protocol.servlet?ID=<%=ID%>&cmd=GetProtocols&subtype='+subtype;   
195    request.open("GET", url, false); 
196    request.send(null);
197  }
198  finally
199  {
200    hideLoadingAnimation();
201  }
202
203  if (debug) Main.debug(request.responseText);
204  var response = JSON.parse(request.responseText); 
205  if (response.status != 'ok')
206  {
207    setFatalError(response.message);
208    return false;
209  }
210  return response.protocols;
211}
212
213function bioPlateOnChange()
214{
215  var frm = document.forms['reggie'];
216}
217
218function outcomeOnChange()
219{
220  var frm = document.forms['reggie'];
221  var failed = document.getElementById('outcomeFailed').checked
222
223  if (failed)
224  {
225    Main.addClass(frm.libComments, 'required');
226    Main.hide('filesSection');
227  }
228  else
229  {
230    Main.removeClass(frm.libComments, 'required');
231    Main.show('filesSection');
232  }
233}
234
235var lastPrefix;
236function browseOnClick(prefix, extension)
237{
238  var frm = document.forms['reggie'];
239  if (frm[prefix+'.path'].disabled) return;
240 
241  var url = getRoot() + 'filemanager/index.jsp?ID=<%=ID%>&cmd=SelectOne&callback=setFileCallback';
242  url += '&resetTemporary=1&tmpfilter:STRING:name='+escape('%.' + extension);
243  lastPrefix = prefix;
244  Main.openPopup(url, 'SelectFile', 1000, 700);
245}
246
247function setFileCallback(id, path)
248{
249  var frm = document.forms['reggie'];
250  frm[lastPrefix+'.id'].value = id;
251  frm[lastPrefix+'.path'].value = path;
252 
253  if (lastPrefix == 'welltable')
254  {
255    setTimeout(preValidateCsvFile, 100);
256  }
257  else if (lastPrefix == 'qubitcsv')
258  {
259    qubitCsvFileOnChange();
260  }
261  else
262  {
263    setInputStatus(lastPrefix, '', 'valid');
264  }
265}
266
267function libDateOnChange()
268{
269  var frm = document.forms['reggie'];
270  libDateIsValid = false;
271  setInputStatus('libDate', '', '');
272 
273  var libDate = frm.libDate.value;
274  if (libDate == '')
275  {
276    setInputStatus('libDate', 'Missing', 'invalid');
277    return;
278  }
279
280  // Auto-fill the date if it's only given with 4(MMdd) or 6(yyMMdd) digits.   
281  libDate = autoFillDate(libDate);
282  frm.libDate.value = libDate;
283 
284  if (!Dates.isDate(libDate, 'yyyyMMdd'))
285  {
286    setInputStatus('libDate', 'Not a valid date', 'invalid');
287    return;
288  }
289 
290  setInputStatus('libDate', '', 'valid');
291  libDateIsValid = true;
292}
293
294
295function preValidateCsvFile()
296{
297  var frm = document.forms['reggie'];
298  var csvId = frm['welltable.id'].value;
299  var csvPath = frm['welltable.path'].value;
300 
301  wellTableIsValid = false;
302 
303  if (!csvId) 
304  {
305    setInputStatus('welltable', 'Missing', 'invalid');
306    return;
307  }
308 
309  Main.addClass(document.body, 'please-wait');
310  setInputStatus('welltable', 'Checking...', 'checking');
311  var qubitCsv = frm['qubitcsv.id'].value;
312  var url = '../LibPrep.servlet?ID=<%=ID%>&cmd=PreValidateCaliperWellTable&csv='+csvId+'&bioplate='+frm.bioplate.value+'&qubit='+qubitCsv;
313 
314  var request = Ajax.getXmlHttpRequest();
315  Ajax.setReadyStateHandler(request, onWellTableValidated);
316  request.open("POST", url, true); 
317  request.send('');
318}
319
320function onWellTableValidated(request)
321{
322  Main.removeClass(document.body, 'please-wait');
323  if (debug) Main.debug(request.responseText);
324  var response = JSON.parse(request.responseText); 
325  var numWarnings = 0;
326  if (response.messages && response.messages.length > 0)
327  {
328    var msg = '<ul>';
329    for (var i = 0; i < response.messages.length; i++)
330    {
331      var msgLine = response.messages[i];
332      if (msgLine.indexOf('[Warning]') >= 0)
333      {
334        msg += '<li class="warning">' + msgLine.replace('[Warning]', '');
335        numWarnings++;
336      }
337      else
338      {
339        msg += '<li>' + msgLine;
340      }
341    }
342    msg += '</ul>';
343    setInnerHTML('messages', msg);
344    Main.show('messages');
345  }
346  else
347  {
348    Main.hide('messages'); 
349  }
350 
351  if (response.status != 'ok')
352  {
353    setInputStatus('welltable', response.message, 'invalid');
354    Main.addClass(document.getElementById('messages'), 'failure');
355    return;
356  }
357
358  setInputStatus('welltable', '', numWarnings > 0 ? 'warning' : 'valid');
359  wellTableIsValid = true;
360}
361
362
363function qubitCsvFileOnChange()
364{
365  var frm = document.forms['reggie'];
366  qubitCsvIsValid = false;
367  if (!frm['qubitcsv.id'].value)
368  {
369    // A PDF is reuired for successful registration, optional after a failure
370    var msg = frm['qubitcsv.path'].value ? 'Use the Browse button to select a file' : 'Missing';
371    setInputStatus('qubitcsv', msg, 'invalid');
372    return;
373  }
374  qubitCsvIsValid = true;
375  setInputStatus('qubitcsv', '', 'valid');
376}
377
378function libCommentsOnChange()
379{
380  var failed = document.getElementById('outcomeFailed').checked;
381  if (!failed) return;
382
383  var frm = document.forms['reggie'];
384  libCommentsIsValid = false;
385  setInputStatus('libComments', '', '');
386 
387  var comments = frm.libComments.value;
388  if (comments == '')
389  {
390    setInputStatus('libComments', 'Missing', 'invalid');
391    return;
392  }
393
394  setInputStatus('libComments', '', 'valid');
395  libCommentsIsValid = true;
396}
397
398
399function step2IsValid()
400{
401  var failed = document.getElementById('outcomeFailed').checked;
402  if (failed)
403  {
404    return libDateIsValid && libCommentsIsValid;
405  }
406  else
407  {
408    return libDateIsValid && wellTableIsValid && qubitCsvIsValid;
409  }
410}
411
412function goRegister()
413{
414  if (!step2IsValid()) return;
415 
416  Main.hide('messages');
417  Main.hide('goregister');
418  Main.hide('gocancel');
419
420  var frm = document.forms['reggie'];
421  var libPlateId = parseInt(frm.bioplate.value, 10);
422  var submitInfo = {};
423  submitInfo.bioplate = libPlateId;
424
425  Main.addClass(document.getElementById('step.2.section'), 'disabled');
426  var url = '../LibPrep.servlet?ID=<%=ID%>&cmd=ImportLibPrepResults';
427  var failed = document.getElementById('outcomeFailed').checked;
428  submitInfo.failed = failed;
429   
430  if (!failed)
431  {
432    saveToLocalStorage(libPlateId);
433    submitInfo.wellTableCsv = parseInt(frm['welltable.id'].value, 10);
434    submitInfo.caliperGxd = parseInt(frm['calipergxd.id'].value, 10);
435    submitInfo.caliperPdf = parseInt(frm['caliperpdf.id'].value, 10);
436    submitInfo.qubitCsv = parseInt(frm['qubitcsv.id'].value, 10);
437  }
438   
439  submitInfo.libDate = frm.libDate.value;
440  submitInfo.libProtocol = parseInt(frm.libProtocol.value, 10);
441  submitInfo.libOperator = frm.libOperator.value;
442  submitInfo.libComments = frm.libComments.value;
443 
444  if (debug) Main.debug(JSON.stringify(submitInfo));
445 
446  var request = Ajax.getXmlHttpRequest();
447  try
448  {
449    showLoadingAnimation('Performing registration...');
450    request.open("POST", url, false);
451    request.send(JSON.stringify(submitInfo));
452  }
453  finally
454  {
455    hideLoadingAnimation();
456  }
457 
458  if (debug) Main.debug(request.responseText);
459  var response = JSON.parse(request.responseText);
460 
461  if (response.messages && response.messages.length > 0)
462  {
463    var msg = '<ul>';
464    for (var i = 0; i < response.messages.length; i++)
465    {
466      var msgLine = response.messages[i];
467      if (msgLine.indexOf('[Warning]') >= 0)
468      {
469        msg += '<li class="warning">' + msgLine.replace('[Warning]', '');
470      }
471      else
472      {
473        msg += '<li>' + msgLine;
474      }
475    }
476    msg += '</ul>';
477    setInnerHTML('messages', msg);
478    Main.show('messages');
479  }
480 
481  if (response.status != 'ok')
482  {
483    Main.addClass(document.getElementById('messages'), 'failure');
484    setFatalError(response.message);
485    return false;
486  }
487  else
488  {
489    removeFromLocalStorage(libPlateId);
490  }
491
492  Main.show('gorestart');
493}
494
495
496/**
497  Save as much information as possible about the library registration.
498  The information is stored in the localStorage()
499  under the key 'reggie.libplate.<id>.info' where
500  <id> is the ID of the library plate.
501*/
502function saveToLocalStorage(libPlateId)
503{
504  if (window.localStorage)
505  {
506    var frm = document.forms['reggie'];
507    var libInfo = new Object();
508    libInfo.id = libPlateId;
509    libInfo.libDate = frm.libDate.value;
510    libInfo.wellTable = { id: frm['welltable.id'].value, path: frm['welltable.path'].value };
511    libInfo.caliperGxd = { id: frm['calipergxd.id'].value, path: frm['calipergxd.path'].value };
512    libInfo.caliperPdf = { id: frm['caliperpdf.id'].value, path: frm['caliperpdf.path'].value };
513    libInfo.qubitCsv = { id: frm['qubitcsv.id'].value, path: frm['qubitcsv.path'].value };
514    libInfo.libProtocol = frm.libProtocol.value;
515    libInfo.libOperator = frm.libOperator.value;
516    libInfo.libComments = frm.libComments.value;
517   
518    window.localStorage.setItem('reggie.libplate.' + libPlateId + '.info', JSON.stringify(libInfo));
519    if (debug)
520    {
521      Main.debug(libPlateId + ': ' + window.localStorage.getItem('reggie.libplate.' + libPlateId + '.info'));
522    }
523  }
524}
525
526function removeFromLocalStorage(libPlateId)
527{
528  if (!window.localStorage) return;
529  if (debug) Main.debug('removeFromLocalStorage:' + libPlateId);
530  window.localStorage.removeItem('reggie.libplate.' + libPlateId + '.info');
531}
532
533function getStoredInfo(libPlateId)
534{
535  if (!window.localStorage) return null;
536  try
537  {
538    var stored = window.localStorage.getItem('reggie.libplate.' + libPlateId + '.info');
539    if (debug) Main.debug(libPlateId + ': ' + stored);
540    return stored ? JSON.parse(stored) : null;
541  }
542  catch (e)
543  {
544    Main.debug('Could not load stored information for tube ' + tubeId + ': ' + e);
545  }
546}
547
548
549</script>
550<style>
551body.please-wait
552{
553  cursor: wait !important;
554}
555</style>
556
557</base:head>
558<base:body onload="init()">
559
560  <p:path><p:pathelement 
561    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
562    /><p:pathelement title="Library registration" 
563    /></p:path>
564
565  <div class="content">
566  <%
567  if (sc.getActiveProjectId() == 0)
568  {
569    %>
570    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
571      No project has been selected. You may proceed with the registration but
572      created items will not be shared.
573    </div>
574    <%
575  }
576  %>
577
578  <form name="reggie" onsubmit="return false;">
579    <input type="hidden" name="pdf.id" value="">
580 
581  <div id="step.1.section">
582  <table class="stepform">
583  <tr>
584    <td rowspan="3" class="stepno">1</td>
585    <td class="steptitle">Select Library bioplate</td>
586  </tr>
587  <tr>
588    <td class="stepfields">
589      <table>
590      <tr valign="top">
591        <td class="prompt">Library bioplate</td>
592        <td class="input"><select class="required" style="width:90%;" 
593            name="bioplate" id="bioplate" onchange="bioPlateOnChange()"></select>
594        </td>
595        <td class="status" id="bioplate.status"></td>
596        <td class="help"><span id="bioplate.message" class="message" style="display: none;"></span>
597          Select an existing Library bioplate. The list contain all Library bioplates that
598          has not yet been processed (determined by the absence of a 'creation' date).
599        </td>
600      </tr>
601      <tr valign="top" id="outcomeSection">
602        <td class="prompt">Outcome</td>
603        <td class="input">
604          <input type="radio" name="outcome" id="outcomeSuccess" 
605            onchange="outcomeOnChange()" checked><label for="outcomeSuccess">Success</label> - continue processing<br>
606          <input type="radio" name="outcome" id="outcomeFailed" 
607            onchange="outcomeOnChange()"><label for="outcomeFailed">Failure</label> - no further processing
608        </td>
609        <td class="status"></td>
610        <td class="help">
611          Select the <b>Failure</b> option if further processing to pooled libraries is not possible.
612          Existing RNA will be flagged and added to the <b>Flagged RNA</b> list.
613        </td>
614      </tr>
615      </table>
616    </td>
617  </tr>
618  </table>
619  </div>
620 
621 
622  <div id="step.2.section" style="display: none;">
623  <table class="stepform">
624  <tr>
625    <td rowspan="3" class="stepno">2</td>
626    <td class="steptitle">Full plate registration</td>
627  </tr>
628  <tr>
629    <td class="stepfields">
630      <table>
631      <tr valign="top">
632        <td class="prompt">Date</td>
633        <td class="input">
634          <input type="text" class="required" name="libDate" value="" size="12" maxlength="10"
635            onblur="libDateOnChange()" onkeypress="focusOnEnter(event, 'qubitcsv.path')">
636        </td>
637        <td class="status" id="libDate.status"></td>
638        <td class="help">
639          <span id="libDate.message" class="message" style="display: none;"></span>(YYYYMMDD or MMDD)
640        </td>
641      </tr>
642      <tbody id="filesSection">
643      <tr>
644        <td class="prompt">Qubit files</td>
645        <td class="input"></td>
646        <td class="status"></td>
647        <td class="help"></td>
648      </tr>
649      <tr valign="top">
650        <td class="subprompt">Conc. CSV</td>
651        <td class="input">
652          <input type="hidden" name="qubitcsv.id" value="">
653          <table>
654          <tr>
655          <td><input class="text required" type="text" 
656            name="qubitcsv.path" value=""
657            size="50" onkeypress="doOnEnter(event, function(){document.getElementById('btnQubitCsv').click()})"
658            onblur="qubitCsvFileOnChange()"
659            ></td>
660          <td style="padding-left: 4px;"><base:button 
661              title="Browse&hellip;"
662              onclick="browseOnClick('qubitcsv', 'csv')"
663              id="btnQubitCsv"
664              />
665          </td>
666          </tr>
667          </table>
668        </td>
669        <td class="status" id="qubitcsv.status"></td>
670        <td class="help"><span id="qubitcsv.message" class="message" style="display: none;"></span>
671          Select the <b>Qubit CSV</b> file that contains the table with concentration
672          measurements.
673        </td>
674      </tr>
675      <tr>
676        <td class="prompt">Caliper files</td>
677        <td class="input"></td>
678        <td class="status"></td>
679        <td class="help"></td>
680      </tr>
681      <tr valign="top">
682        <td class="subprompt">Well table CSV</td>
683        <td class="input">
684          <input type="hidden" name="welltable.id" value="">
685          <table>
686          <tr>
687          <td><input class="text required" type="text" 
688            name="welltable.path" value=""
689            size="50" onkeypress="doOnEnter(event, function(){document.getElementById('btnWellTable').click()})"
690            onblur="csvFileOnChange()"
691            ></td>
692          <td style="padding-left: 4px;"><base:button 
693              title="Browse&hellip;"
694              onclick="browseOnClick('welltable', 'csv')"
695              id="btnWellTable"
696              />
697          </td>
698          </tr>
699          </table>
700        </td>
701        <td class="status" id="welltable.status"></td>
702        <td class="help"><span id="welltable.message" class="message" style="display: none;"></span>
703           Select the <b>Well Table CSV</b> file that contains the exported analysis
704           result from the Caliper software.
705        </td>
706      </tr>
707      <tr valign="top">
708        <td class="subprompt">GXD raw data</td>
709        <td class="input">
710          <input type="hidden" name="calipergxd.id" value="">
711          <table>
712          <tr>
713          <td><input class="text" type="text" 
714            name="calipergxd.path" value=""
715            size="50" onkeypress="doOnEnter(event, function(){document.getElementById('btnCaliperGxd').click()})"
716            ></td>
717          <td style="padding-left: 4px;"><base:button 
718              title="Browse&hellip;"
719              onclick="browseOnClick('calipergxd', 'gxd')"
720              id="btnCaliperGxd"
721              />
722          </td>
723          </tr>
724          </table>
725        </td>
726        <td class="status" id="calipergxd.status"></td>
727        <td class="help"><span id="calipergxd.message" class="message" style="display: none;"></span>
728          Select the <b>GXD raw data file</b> from Caliper.
729        </td>
730      </tr>
731      <tr valign="top">
732        <td class="subprompt">PDF file</td>
733        <td class="input">
734          <input type="hidden" name="caliperpdf.id" value="">
735          <table>
736          <tr>
737          <td><input class="text" type="text" 
738            name="caliperpdf.path" value=""
739            size="50" onkeypress="doOnEnter(event, function(){document.getElementById('btnCaliperPdf').click()})"
740            ></td>
741          <td style="padding-left: 4px;"><base:button 
742              title="Browse&hellip;"
743              onclick="browseOnClick('caliperpdf', 'pdf')"
744              id="btnCaliperPdf"
745              />
746          </td>
747          </tr>
748          </table>
749        </td>
750        <td class="status" id="caliperpdf.status"></td>
751        <td class="help"><span id="caliperpdf.message" class="message" style="display: none;"></span>
752          Select the <b>PDF file</b> that contains a printout with diagrams and other
753          useful documentation.
754        </td>
755      </tr>
756      </tbody>
757      <tr valign="top">
758        <td class="prompt">Protocol</td>
759        <td class="input"><select style="width:90%" name="libProtocol" id="libProtocol" 
760          onkeypress="focusOnEnter(event, 'libOperator')"></select></td>
761        <td class="status" id="libProtocol.status"></td>
762        <td class="help"><span id="libProtocol.message" class="message" style="display: none;"></span>
763          Select the protocol used for library preparation.
764        </td>
765      </tr>
766      <tr valign="top">
767        <td class="prompt">Operator</td>
768        <td class="input">
769          <input type="text" name="libOperator" value="<%=HTML.encodeTags(user.getName()) %>" 
770            style="width: 90%;" maxlength="255" onkeypress="focusOnEnter(event, 'libComments')">
771        </td>
772        <td class="status" id="libOperator.status"></td>
773        <td class="help">
774          <span id="libOperator.message" class="message" style="display: none;"></span>
775        </td>
776      </tr>
777      <tr valign="top">
778        <td class="prompt">Comments</td>
779        <td class="input"><textarea rows="4" cols="50" style="width: 90%;" name="libComments" value="" onblur="libCommentsOnChange()"></textarea></td>
780        <td class="status" id="libComments.status"></td>
781        <td class="help"><span id="libComments.message" class="message" style="display: none;"></span>Comments about the library preparation.</td>
782      </tr>
783      </table>
784    </td>
785  </tr>
786  </table>
787  </div>
788 
789 
790  <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>
791 
792  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
793 
794  <div id="messages" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
795 
796  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
797    <tr>
798      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
799      <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
800      <td><base:button id="goregister" title="Register" image="<%=home+"/images/import.png"%>" onclick="goRegister()" style="display: none;"/></td>
801      <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
802      <td id="gonext.message" class="message"></td>
803    </tr>
804  </table>
805 
806  </form>
807  </div>
808 
809</base:body>
810</base:page>
811<%
812}
813finally
814{
815  if (dc != null) dc.close();
816}
817%>
Note: See TracBrowser for help on using the repository browser.