source: extensions/net.sf.basedb.reggie/trunk/resources/libprep/select_rna.jsp @ 1897

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

Fixes #469: Better handling of login timeout in Reggie wizards

A background timer is started by calling the javascript method keepSessionAlive() in pages that need protection. The timer uses Ajax calls to SessionServlet to check if the session is still alive and update the last access time to prevent automatic timeout. In debug mode, a checkbox is appended to the bottom of the page which can be used to simulate a session timeout (actually, a real logout is done). This should trigger a popup window that asks the user to login again. Data in the wizard should be unaffected and it should be possible to proceed as usual once the login has been completed.

This feature has currently been added to the following wizards:

  • Partition wizard (activated in step 2)
  • DNA/RNA/FlowThrough registration (step 3)
  • Create aliquots on Bioanalyzer/Caliper? plates (step 3)
  • Create new mRNA plate
  • Assign barcodes to cDNA plate
File size: 42.4 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.Application"
5  import="net.sf.basedb.core.User"
6  import="net.sf.basedb.core.DbControl"
7  import="net.sf.basedb.core.SessionControl"
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  import="net.sf.basedb.util.Values"
12  import="net.sf.basedb.util.formatter.WellCoordinateFormatter"
13%>
14<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
15<%@ taglib prefix="m" uri="/WEB-INF/menu.tld" %>
16<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
17<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
18<%
19final SessionControl sc = Base.getExistingSessionControl(request, true);
20final String ID = sc.getId();
21final float scale = Base.getScale(sc);
22final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
23DbControl dc = null;
24try
25{
26  dc = sc.newDbControl();
27  final User user = User.getById(dc, sc.getLoggedInUserId());
28%>
29<base:page type="default" >
30<base:head scripts="ajax.js,js-draw.js,menu.js" styles="path.css,toolbar.css,menu.css">
31  <link rel="stylesheet" type="text/css" href="../css/reggie.css">
32  <link rel="stylesheet" type="text/css" href="../css/plate.css">
33  <script language="JavaScript" src="../reggie.js" type="text/javascript" charset="UTF-8"></script>
34  <script language="JavaScript" src="plate.js" type="text/javascript" charset="UTF-8"></script>
35  <script language="JavaScript" src="pools.js" type="text/javascript" charset="UTF-8"></script>
36
37<script language="JavaScript">
38var debug = false;
39
40var QUANTITY_REGULAR = 1.1;
41var QUANTITY_QC = 1.22;
42
43var Rna = function()
44{
45  var rna = {};
46  var flagged = [];
47  var info = [];
48 
49  /**
50    Create a new RNA object by name. More information
51    about the RNA is automatically loaded from the database.
52  */
53  rna.createByName = function(name)
54  {
55    var tmp = {};
56    tmp.name = name;
57    tmp.stratagene = name == STRATAGENE_NAME;
58    tmp.external = name == EXTERNAL_RNA_NAME;
59    tmp.info = rna.infoByName(name);
60    tmp.id = tmp.info.id;
61    return tmp;
62  }
63 
64  /**
65    Create a new RNA object by info object.
66  */
67  rna.createByInfo = function(info)
68  {
69    var tmp = {};
70    tmp.name = info.name;
71    tmp.stratagene = tmp.name == STRATAGENE_NAME;
72    tmp.external = tmp.name == EXTERNAL_RNA_NAME;
73    tmp.id = info.id;
74    tmp.info = info;
75    return tmp;
76  }
77 
78  /**
79    Get information about a RNA item with a given name.
80  */
81  rna.infoByName = function(name)
82  {
83    var key = 'N'+name;
84    if (!info[key])
85    {
86      rna.loadInfoByNames([name]);
87      if (!info[key]) info[key] = {};
88    }
89    return info[key];
90  }
91
92  /**
93    Load and cache RNA information for all RNA items with a name in the
94    given list.
95  */
96  rna.loadInfoByNames = function(names)
97  {
98    var submitInfo = {};
99    submitInfo.names = names;
100    if (debug) Main.debug(JSON.stringify(submitInfo));
101
102    var request = Ajax.getXmlHttpRequest();
103    var url = '../MRna.servlet?ID=<%=ID%>&cmd=GetRnaInfoFromNames'; 
104    request.open("POST", url, false);
105    request.setRequestHeader("Content-Type", "application/json");
106    request.send(JSON.stringify(submitInfo));
107
108    if (debug) Main.debug(request.responseText);
109    var response = JSON.parse(request.responseText); 
110    if (response.status != 'ok')
111    {
112      setFatalError(response.message);
113      return false;
114    }
115   
116    rna.cacheInfo(response.rna);
117  }
118 
119  rna.cacheInfo = function(rnaList)
120  {
121    for (var i = 0; i < rnaList.length; i++)
122    {
123      var r = rnaList[i];
124      info['N'+r.name] = r;
125      info['I'+r.id] = r;
126      if (r.flag) flagged[flagged.length] = r;
127    }
128  }
129
130  rna.unflag = function(r)
131  {
132    if (!r.info || !r.info.flag) return false;
133
134    r.info.flag = null;
135    for (var i = 0; i < flagged.length; i++)
136    {
137      if (r.id == flagged[i].id)
138      {
139        flagged.splice(i, 1);
140        break;
141      }
142    }
143    return true;
144  }
145 
146  rna.getFlagged = function()
147  {
148    return flagged;
149  }
150 
151  return rna;
152}();
153
154var WellPainter = function()
155{
156  var painter = {};
157 
158  // Add class indicators for replicates and QC assigned wells
159  painter.getClassNameForWell = function(well)
160  {
161    var cls = '';
162    if (well.extract)
163    {
164      if (well.replicate) cls += ' replicate';
165      if (well.extract.qc) cls += ' qc';
166    }
167    return cls;
168  }
169 
170  painter.getWellText = function(well)
171  {
172    var text = '';
173    if (well.duplicates)
174    {
175      well.setError('Duplicate RNA in this location');
176      text += '<div class="name">'+well.duplicates.join(', ')+'</div>';
177    }
178    else if (well.extract)
179    {
180      // The well contains RNA
181      var rna = well.extract;
182      var info = rna.info;
183      text += '<div class="name">'+rna.name+'</div>';
184     
185      var warningMsg = null;
186      if (info && info.id && !rna.stratagene && !rna.external)
187      {
188        var quantity = 1000 * (rna.qc ? QUANTITY_QC : QUANTITY_REGULAR);
189        var use = Math.ceil(quantity/info.NDConc);
190        var water = Math.round(50-use);
191        if (info.bioWell)
192        {
193          var rnaWell = info.bioWell;
194          text += '<div class="location">'+rnaWell.bioPlate.name+'['+WELL_ALPHA[rnaWell.row]+(rnaWell.column+1)+']</div>';
195        }
196        else
197        {
198          if (!warningMsg) warningMsg = 'No location';
199        }
200        if (info.remainingQuantity)
201        {
202          text += '<div class="quantity">'+Numbers.formatNumber(info.remainingQuantity, 2) + 'µg</div>';
203          if (info.remainingQuantity < (rna.qc ? QUANTITY_QC : QUANTITY_REGULAR))
204          {
205            if (!warningMsg) warningMsg = 'Low quantity';
206          }
207        }
208        else
209        {
210          if (!warningMsg) warningMsg = 'No quantity';
211        }
212        if (info.NDConc)
213        {
214          text += '<div class="ndconc">'+Numbers.formatNumber(info.NDConc, 2) + 'ng/µl</div>';
215          text += '<div class="volumes"><span class="volume">'+Numbers.formatNumber(use, 1)+'</span> + <span class="water">'+Numbers.formatNumber(water, 1)+'µl</span></div>';
216        }
217        else
218        {
219          if (!warningMsg) warningMsg = 'No NDConc value';
220        }
221        if (warningMsg)
222        {
223          well.setWarning(warningMsg);
224        }
225      }
226      else if (!rna.id)
227      {
228        well.setError('RNA not found');
229      }
230      if (rna.comment)
231      {
232        text += '<div class="comment">'+Main.encodeTags(rna.comment)+'</div>';
233      }
234    }
235    else if (well.copyText)
236    {
237      text = '<div class="copy-text">'+well.copyText+'</div>';
238    }
239    return text;
240  }
241 
242  return painter;
243}();
244
245
246var graphics;
247var pen;
248
249function init()
250{
251  keepSessionAlive('<%=ID%>', debug, '../');
252 
253  var frm = document.forms['reggie'];
254  var schema = PoolSchema.initList(frm.pool_schema);
255
256  Plate.init(8, 12, schema, WellPainter);
257  Plate.paint(Plate.getWells());
258  PoolSchema.buildPoolTableRow(schema, 12, true);
259 
260  var specialSelect = document.getElementById('iconSpecialSelect');
261  specialSelect.addEventListener('click', toggleSpecialSelect);
262 
263  graphics = new jsGraphics(document.getElementById('canvas'));
264  pen = new jsPen(new jsColor('#2288AA'), 2);
265 
266  Plate.name = findNextMRnaPlateName();
267  setInnerHTML('plateName', Plate.name);
268}
269
270function findNextMRnaPlateName()
271{
272  var request = Ajax.getXmlHttpRequest();
273  var url = '../MRna.servlet?ID=<%=ID%>&cmd=GetNextAutoGeneratedPlateName&bioPlateType=MRNA'; 
274  if (debug) Main.debug(url);
275  request.open("GET", url, false); 
276  request.send(null);
277
278  if (debug) Main.debug(request.responseText);
279  var response = JSON.parse(request.responseText); 
280  if (response.status != 'ok')
281  {
282    setFatalError(response.message);
283    return false;
284  }
285  return response.name;
286}
287
288
289// Toggle the 'special select' menu on and off
290function toggleSpecialSelect(event)
291{
292  var specialSelect = document.getElementById('iconSpecialSelect');
293  var pos = Main.getElementPosition(specialSelect);
294  Menu.toggleTopMenu(document.getElementById('menuSpecialSelect'), pos.left+pos.width/4, pos.top+pos.height);
295  event.stopPropagation();
296}
297
298/**
299  Parse a tab-separated data file. The columns must be in the following order:
300  0: RNA name
301  1: Row letter (A-H)
302  2: Column number (1-12)
303  3: QC flag (can be empty)
304*/
305function parseRnaFile(data)
306{
307  var lines = data.split(/[\n\r]+/);
308
309  // Load information about all RNA items in a batch (will improve performance)
310  var names = [];
311  for (var i = 0; i < lines.length; i++)
312  {
313    var line = lines[i];
314    if (line)
315    {
316      var cols = lines[i].split(/\t/);
317      if (cols.length < 3) throw 'On line '+(i+1)+': Too few columns (' + cols.length + ')';
318      names[names.length] = cols[0];
319    }
320  }
321  Rna.loadInfoByNames(names);
322 
323  // Place RNA on the plate
324  var duplicates = [];
325  for (var i = 0; i < lines.length; i++)
326  {
327    var line = lines[i];
328    if (line)
329    {
330      var cols = lines[i].split(/\t/);
331
332      var rna = Rna.createByName(cols[0]);
333      var row =  WELL_ALPHA.indexOf(cols[1].toUpperCase());
334      var col =  parseInt(cols[2], 10)-1;
335     
336      var well = Plate.getWell(row, col);
337      if (!well) throw 'On line '+(i+1)+': Invalid plate coordinate ['+cols[1]+','+cols[2]+']';
338
339      rna.qc = cols.length >= 4 && cols[3];
340      Rna.unflag(rna);
341     
342      // Check for duplicate RNA on same position (which is an error)
343      var pos = 'c'+col+'r'+row;
344      if (duplicates[pos])
345      {
346        well.addDuplicate(rna);
347      }
348      else
349      {
350        duplicates[pos] = rna.name;
351        well.setExtract(rna);
352      }
353    }
354  }
355 
356  updateNumFlaggedRna();
357 
358  // Check for replicates on the whole plate and repaint it
359  Plate.checkReplicates(null, true);
360  Plate.paint(Plate.getWells());
361}
362
363/**
364  Add 'Stratagene' to the selected wells.
365*/
366function setToStratagene()
367{
368  setToSpecial(STRATAGENE_NAME, true);
369}
370
371/**
372  Add 'External RNA' to the selected wells.
373*/
374function setToExternal()
375{
376  setToSpecial(EXTERNAL_RNA_NAME, false);
377}
378
379/**
380  Add special RNA to the selected wells.
381*/
382function setToSpecial(specialName, qc)
383{
384  var wells = Plate.getSelected();
385 
386  if (wells.length == 0)
387  {
388    alert('No wells have been selected');
389    return;
390  }
391 
392  // Count non-empty wells
393  var count = 0;
394  for (var i = 0; i < wells.length; i++)
395  {
396    var well = wells[i];
397    if (well.extract && !well.hasError()) count++;
398  }
399 
400  if (count > 0)
401  {
402    if (!confirm('Replace RNA in ' + count + ' wells with '+specialName+'?'))
403    {
404      return;
405    }
406  }
407 
408  var info = Rna.infoByName(specialName);
409  if (!info.id)
410  {
411    alert('Could not find any RNA with name=\''+specialName+'\'. Please check that it exists on the server.');
412    return;
413  }
414 
415  for (var i = 0; i < wells.length; i++)
416  {
417    var well = wells[i];
418    var rna = Rna.createByInfo(info);
419    rna.qc = qc;
420    well.setExtract(rna);
421    well.selected = false;
422  }
423 
424  Plate.paint(wells);
425 
426  // Check for replicated RNA if some have been replaced with Stratagene
427  if (count > 0) Plate.checkReplicates();
428}
429
430
431
432/**
433  Toggle the QC flag for the selected wells. The first non-empty
434  well is toggled and the rest of the wells will use the same new QC
435  value.
436*/
437function toggleQc()
438{
439  var wells = Plate.getSelected();
440
441  if (wells.length == 0)
442  {
443    alert('No wells have been selected');
444    return;
445  }
446 
447  var gotQc = false;
448  var newQc;
449  var count = 0;
450  for (var i = 0; i < wells.length; i++)
451  {
452    var well = wells[i];
453    if (well.extract)
454    {
455      // Toggle QC flag for the first well with RNA, then use the same flag for the rest
456      if (!gotQc)
457      {
458        gotQc = true;
459        newQc = !well.extract.qc;
460      }
461      well.extract.qc = newQc;
462      count++;
463    }
464  }
465 
466  if (count == 0)
467  {
468    alert('None of the selected wells contain any RNA');
469  }
470  else
471  {
472    Plate.paint(wells);
473  }
474}
475
476/**
477  Empty the selected wells from RNA. They can later be pasted again.
478*/
479function cutSelected()
480{
481  var wells = Plate.getSelected();
482 
483  if (wells.length == 0)
484  {
485    alert('No wells have been selected');
486    return;
487  }
488 
489  var count = 0;
490  var valid = 0;
491  for (var i = 0; i < wells.length; i++)
492  {
493    var well = wells[i];
494    if (well.extract) 
495    {
496      count++;
497      if (!well.hasError()) valid++;
498    }
499  }
500 
501  if (count == 0)
502  {
503    alert('None of the selected wells contain any RNA');
504    return;
505  }
506 
507  // Ask for confirmation before deleting from valid wells
508  if (valid > 0)
509  {
510    if (!confirm('Clear RNA from ' + count + ' of ' + wells.length + ' selected wells?'))
511    {
512      return;
513    }
514  }
515
516  copySelected();
517  for (var i = 0; i < wells.length; i++)
518  {
519    var well = wells[i];
520    well.setExtract(null);
521    well.selected = false;
522  }
523  Plate.paint(wells);
524  Plate.checkReplicates();
525}
526
527var copy;
528/**
529  Copy information about the selected wells. 
530*/
531function copySelected()
532{
533  // Clear existing wells in the copy
534  var repaint = [];
535  if (copy && copy.length > 0)
536  {
537    for (var i = 0; i < copy.length; i++)
538    {
539      var cp = copy[i];
540      cp.well.doneWithCopy();
541      repaint[repaint.length] = cp.well;
542    }
543  }
544  Plate.paint(repaint);
545 
546  // Place selected wells in the copy
547  var wells = Plate.getSelected();
548  copy = [];
549  for (var i = 0; i < wells.length; i++)
550  {
551    var well = wells[i];
552    copy[copy.length] = well.makeCopy();
553    well.selected = false;
554  }
555  Plate.paint(wells);
556}
557
558/**
559  Paste information into the selected wells.
560*/
561function pasteToSelected()
562{
563  if (!copy || copy.length == 0) 
564  {
565    alert('Nothing to paste. Please cut or copy wells first.');
566    return;
567  }
568 
569  var wells = Plate.getSelected();
570  // Count non-empty and valid wells
571  var count = 0;
572  for (var i = 0; i < wells.length; i++)
573  {
574    var well = wells[i];
575    if (well.extract && !well.hasError()) count++;
576  }
577 
578  if (count > 0)
579  {
580    if (!confirm('Replace RNA in ' + count + ' wells with copy?'))
581    {
582      return;
583    }
584  }
585 
586  var wi = 0;
587  var ci = 0;
588  var copyEmpty;
589  var askIfEmpty = true;
590  var repaint = [];
591 
592  while (wi < wells.length && ci < copy.length)
593  {
594    var well = wells[wi];
595    var cp = copy[ci];
596    var rna = null;
597    cp.well.doneWithCopy();
598    repaint[repaint.length] = cp.well;
599    if (cp.name)
600    {
601      rna = Rna.createByName(cp.name);
602      rna.comment = cp.comment;
603    }
604    else
605    {
606      // The copy is from an empty well
607      if (askIfEmpty)
608      {
609        askIfEmpty = false;
610        copyEmpty = confirm('Do you want to copy empty wells? If not, only non-empty well are copied.');
611      }
612    }
613    if (rna != null || copyEmpty)
614    {
615      well.setExtract(rna);
616      well.selected = false;
617      repaint[repaint.length] = well;
618      wi++;
619    }
620    ci++;
621  }
622  Plate.paint(repaint);
623  copy.splice(0, ci);
624  Plate.checkReplicates();
625}
626
627/*
628  If exactly two wells have been selected, switch the RNA in them.
629*/
630function switchSelected()
631{
632  var wells = Plate.getSelected();
633
634  if (wells.length != 2)
635  {
636    alert('Exactly 2 wells must be selected');
637    return;
638  }
639
640  var rna0 = wells[0].extract;
641  var rna1 = wells[1].extract;
642 
643  wells[0].setExtract(rna1);
644  wells[1].setExtract(rna0);
645  Plate.paint(wells);
646}
647
648// Set a comment on the selected wells
649function commentSelected(comment)
650{
651  var wells = Plate.getSelected();
652 
653  if (comment == undefined)
654  {
655    if (wells.length == 0)
656    {
657      alert('No wells have been selected');
658      return;
659    }
660   
661    var count = 0;
662    for (var i = 0; i < wells.length; i++)
663    {
664      var well = wells[i];
665      if (well.extract) 
666      {
667        count++;
668        if (well.extract.comment) comment = well.extract.comment;
669      }
670    }
671   
672    if (count == 0)
673    {
674      alert('None of the selected wells contain any RNA');
675      return;
676    }
677
678    comment = prompt('Comment', comment || '');
679    if (comment == null) return;
680  }
681 
682  if (comment == '') comment = null;
683  for (var i = 0; i < wells.length; i++)
684  {
685    var well = wells[i];
686    if (well.extract) well.extract.comment = comment;
687  }
688  Plate.paint(wells);
689}
690
691/**
692  Open a popup dialog for selecting a data files.
693*/
694function selectFile()
695{
696  Main.openPopup('select_file.jsp?ID=<%=ID%>', 'SelectFile', 600, 400); 
697}
698
699
700/**
701  Let the wizard automatically select among unprocessed RNA items.
702*/
703function autoSelect(options)
704{
705
706  var wells = Plate.getWells();
707  var selected = [];
708  var ignore = [];
709  var notEmpty = 0;
710 
711  // Count selected and non-empty wells and keep track of RNA that is already present
712  for (var i = 0; i < wells.length; i++)
713  {
714    var well = wells[i];
715    if (well.selected) 
716    {
717      selected[selected.length] = well;
718      if (well.extract && !well.hasError()) notEmpty++;
719    }
720    if (well.extract && well.extract.id)
721    {
722      ignore[ignore.length] = well.extract.id;
723    }
724  }
725  // Ignore RNA already flagged
726  var flagged = Rna.getFlagged();
727  for (var i = 0; i < flagged.length; i++)
728  {
729    var rna = flagged[i];
730    if (rna.id) ignore[ignore.length] = rna.id;
731  }
732 
733  if (!options)
734  {
735    if (selected.length == 0)
736    {
737      alert('Please select one or more wells were RNA should be placed.');
738      return;
739    }
740   
741    if (notEmpty > 0)
742    {
743      if (!confirm('Replace RNA in ' + notEmpty + ' wells?'))
744      {
745        return;
746      }
747    }
748   
749    var url = 'auto_select_rna.jsp?ID=<%=ID%>';
750    Main.openPopup(url, 'AutoSelectRNA', 600, 400);
751
752  }
753  else
754  {
755    var request = Ajax.getXmlHttpRequest();
756    var url = '../MRna.servlet?ID=<%=ID%>&cmd=AutoSelectRnaForMRna&numToSelect='+selected.length;
757    url += '&ignore='+ignore.join(',');
758   
759    if (options.remainingQuantity)
760    {
761      url += '&remainingQuantity='+options.remainingQuantity;
762    }
763    if (options.flag)
764    {
765      url += '&flag=1';
766    }
767    if (options.reProcess)
768    {
769      url += '&reProcess=1';
770    }
771   
772    request.open("GET", url, false);
773    request.send(null);
774
775    if (debug) Main.debug(request.responseText);
776    var response = JSON.parse(request.responseText); 
777    if (response.status != 'ok')
778    {
779      setFatalError(response.message);
780      return false;
781    }
782   
783    // Cache RNA information
784    Rna.cacheInfo(response.rna);
785    Rna.cacheInfo(response.flagged);
786   
787    if (response.rna.length == 0)
788    {
789      alert('Could not find any unprocessed RNA at this time.');
790    }
791   
792    updateNumFlaggedRna();
793   
794    for (var i = 0; i < response.rna.length; i++)
795    {
796      if (i < selected.length)
797      {
798        var well = selected[i];
799        // Create a new RNA object
800        var rna = Rna.createByName(response.rna[i].name);
801        well.setExtract(rna);
802        well.selected = false;
803      }
804    }
805   
806    // Check for replicates on the whole plate and repaint it
807    Plate.checkReplicates(null, true);
808    Plate.paint(Plate.getWells());
809   
810  }
811}
812
813
814var currentSelected;
815var currentIndex = 0;
816var subtypeRna = null;
817
818/**
819  Open a popup dialog for manual selection of RNA.
820 */
821function manualSelect()
822{
823  currentSelected = Plate.getSelected();
824  currentIndex = 0;
825 
826  if (currentSelected.length == 0)
827  {
828    alert('Please select one or more wells were RNA should be placed.');
829    return;
830  }
831 
832  if (subtypeRna == null)
833  {
834    var request = Ajax.getXmlHttpRequest();
835    var url = '../Subtype.servlet?ID=<%=ID%>&cmd=GetSubtypeInfo&name=RNA';
836    request.open("GET", url, false); 
837    request.send(null);
838
839    if (debug) Main.debug(request.responseText);
840    var response = JSON.parse(request.responseText); 
841    if (response.status != 'ok')
842    {
843      setFatalError(response.message);
844      return false;
845    }
846    subtypeRna = response.subtype;
847  }
848
849  var url = getRoot() + 'biomaterials/extracts/index.jsp?ID=<%=ID%>';
850  url += '&cmd=UpdateContext&mode=selectmultiple&callback=setRnaCallback&resetTemporary=1';
851  url += '&tmpfilter:INT:itemSubtype='+subtypeRna.id;
852  url += '&tmpfilter:DATE:creationEvent.eventDate='+encodeURIComponent('<>');
853  url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>=1');
854  url += '&'+encodeURIComponent('tmpfilter:STRING:&childCreationEvents(event.bioMaterial.name)')+'='+encodeURIComponent('<>%.m');
855  Main.openPopup(url, 'SelectRNA', 1000, 700);
856}
857
858/**
859  Callback method for manual selection.
860*/
861function setRnaCallback(id, name)
862{
863  if (currentIndex >= currentSelected.length)
864  {
865    return;
866  }
867  var well = currentSelected[currentIndex];
868 
869  // Keep a reference to the old rna in the well
870  var oldRna = well.extract;
871
872  // Create a new RNA object
873  var rna = Rna.createByName(name);
874  if (Rna.unflag(rna)) updateNumFlaggedRna();
875  well.setExtract(rna);
876  well.selected = false;
877  Plate.paint([well]);
878 
879  // Update replicate information
880  Plate.checkReplicates(name);
881  if (oldRna) Plate.checkReplicates(oldRna.name);
882 
883  // Move to the next item
884  currentIndex++;
885}
886
887// Update the 'Flagged RNA' information
888function updateNumFlaggedRna()
889{
890  var numFlagged = Rna.getFlagged().length;
891  if (numFlagged > 0)
892  {
893    setInnerHTML('flaggedRna', numFlagged + ' flagged RNA items.');
894    Main.show('flaggedRna');
895  }
896  else
897  {
898    Main.hide('flaggedRna');
899  }
900}
901
902// Toggle the selected status of a single well
903function toggleWell(row, column)
904{
905  var well = Plate.getWell(row, column);
906  Plate.toggleSelected([well]);
907}
908
909// Toggle the selected status of a complete row
910function toggleRow(row)
911{
912  Plate.toggleSelected(Plate.getRow(row));
913}
914
915// Toggle the selected status of a complete column
916function toggleColumn(column)
917{
918  Plate.toggleSelected(Plate.getColumn(column));
919}
920
921// Toggle the selected status of all wells
922function toggleAll()
923{
924  Plate.toggleSelected(Plate.getWells());
925}
926
927// Toggle the selected status of a complete pool (=two columns)
928function togglePool(pool)
929{
930  Plate.toggleSelected(Plate.getPool(pool));
931}
932function poolOnClick(event)
933{
934  var pool = event.target.getAttribute('data-pool-num');
935  if (pool) togglePool(pool);
936}
937function poolEnter(event)
938{
939  var pool = event.target.getAttribute('data-pool-num');
940  if (pool) highlightPool(pool, true);
941}
942function poolLeave(event)
943{
944  var pool = event.target.getAttribute('data-pool-num');
945  if (pool) highlightPool(pool, false);
946}
947
948
949// Some special toogle operations
950function specialToggle(what)
951{
952  var wells = [];
953  if (what == 'all' || what == 'empty' || what == 'none')
954  {
955    // All wells or all empty (will be filtered later)
956    wells = Plate.getWells();
957  }
958  else if (what == 'pools' || what == 'empty-pools')
959  {
960    // All primary pools or all empty in the primary pools (will be filtered later)
961    for (var i = 0; i < Plate.poolSchema.numPools; i++)
962    {
963      wells = wells.concat(Plate.getPool(i));
964    }
965  }
966  else if (what == 'stratagene')
967  {
968    // All wells with 'Stratagene'
969    var tmp = Plate.getWells();
970    for (var i = 0; i < tmp.length; i++)
971    {
972      var well = tmp[i];
973      if (well.extract && well.extract.stratagene) wells[wells.length] = well;
974    }
975  }
976  else if (what == 'external')
977  {
978    // All wells with 'External RNA'
979    var tmp = Plate.getWells();
980    for (var i = 0; i < tmp.length; i++)
981    {
982      var well = tmp[i];
983      if (well.extract && well.extract.external) wells[wells.length] = well;
984    }
985  }
986  else if (what == 'replicates')
987  {
988    // All wells with replicated RNA
989    var tmp = Plate.getWells();
990    for (var i = 0; i < tmp.length; i++)
991    {
992      var well = tmp[i];
993      if (well.extract && well.replicate) wells[wells.length] = well;
994    }
995  }
996  else if (what == 'error')
997  {
998    // All wells with an error
999    var tmp = Plate.getWells();
1000    for (var i = 0; i < tmp.length; i++)
1001    {
1002      var well = tmp[i];
1003      if (well.hasError()) wells[wells.length] = well;
1004    }
1005  }
1006  else if (what == 'warning')
1007  {
1008    // All wells with a warning
1009    var tmp = Plate.getWells();
1010    for (var i = 0; i < tmp.length; i++)
1011    {
1012      var well = tmp[i];
1013      if (well.warning) wells[wells.length] = well;
1014    }
1015  }
1016 
1017  // Extra filter for empty wells only
1018  if (what.indexOf('empty') != -1)
1019  {
1020    var tmp = wells;
1021    wells = [];
1022    for (var i = 0; i < tmp.length; i++)
1023    {
1024      if (!tmp[i].extract) wells[wells.length] = tmp[i];
1025    }
1026  }
1027 
1028  if (what == 'none')
1029  {
1030    Plate.setSelected(wells, false);
1031  }
1032  else
1033  {
1034    Plate.toggleSelected(wells);
1035  }
1036}
1037
1038// Highlight enable/disable all wells in a column
1039function highlightColumn(column, on)
1040{
1041  Main.addOrRemoveClass(document.getElementById('col.'+column), 'highlight-column', on);
1042  var wells = Plate.getColumn(column);
1043  Plate.setHighlight(wells, 'highlight-column', on);
1044}
1045
1046// Highlight enable/disable all wells in a row
1047function highlightRow(row, on)
1048{
1049  Main.addOrRemoveClass(document.getElementById('row.'+row), 'highlight-row', on);
1050  var wells = Plate.getRow(row);
1051  Plate.setHighlight(wells, 'highlight-row', on);
1052}
1053
1054// Highlight enable/disable all wells in a pool
1055function highlightPool(pool, on)
1056{
1057  Main.addOrRemoveClass(document.getElementById('pool.'+pool), 'highlight-pool', on);
1058  var wells = Plate.getPool(pool);
1059  Plate.setHighlight(wells, 'highlight-pool', on);
1060}
1061
1062/**
1063  Highlight all replicated wells with the same RNA as the given well.
1064*/
1065function highlightReplicated(row, column, on)
1066{
1067  var well = Plate.getWell(row, column);
1068  if (well.extract && well.replicate)
1069  {
1070    // Get center coordinates for the current well
1071    var pos = Main.getElementPosition(well.tag);
1072    var jsPos = new jsPoint(pos.left+pos.width/2, pos.top+pos.height/2);
1073
1074    var replicated = Plate.getWellsByName(well.extract.name);
1075    for (var i = 0; i < replicated.length; i++)
1076    {
1077      var rep = replicated[i];
1078      if (rep != well)
1079      {
1080        Main.addOrRemoveClass(rep.tag, 'highlight-replicated', on);
1081        if (rep.line)
1082        {
1083          // Clear any recent lines
1084          graphics.clearDrawing(rep.line);
1085          rep.line = null;
1086        }
1087        if (on)
1088        {
1089          // We draw a line between the current and replicated well
1090          var rPos = Main.getElementPosition(rep.tag);
1091          rep.line = graphics.drawLine(pen, jsPos, new jsPoint(rPos.left+rPos.width/2, rPos.top+rPos.height/2));
1092        }
1093      }
1094    }
1095  }
1096}
1097
1098/**
1099  Reacts to 'mouseup' and 'contextmenu' events for the bioplate. 
1100  This should bring up the cut/copy/paste context menu depending on which
1101  mouse button that was clicked.
1102*/
1103function contextEvent(event)
1104{
1105  var frm = document.forms['reggie'];
1106  var showContext = false;
1107 
1108  if (frm.contextMenu[0].checked)
1109  {
1110    // Context menu on 'right' mouse button
1111    // Can't just check the button since two events are sent ('mouseup' and 'contextmenu')
1112    showContext = event.type == 'contextmenu' && event.button == 2;
1113  }
1114  else
1115  {
1116    // Context menu on 'middle' mouse button
1117    showContext = event.button == 1;
1118  }
1119 
1120  if (showContext)
1121  {
1122    event.preventDefault(); // Prevents the default right-click menu from appearing
1123    var menu = document.getElementById('menuContext');
1124    // 1 pixel offset to avoid losing well focus outline
1125    contextX = event.clientX+1;
1126    contextY = event.clientY+1;
1127    // Need short delay since 'mouseup' are also sent as 'click' events
1128    // to the 'document' object which BASE already have a Menu.hideAll()
1129    // call which would hide the menu immediately
1130    setTimeout(showContextMenu, 100);
1131  }
1132}
1133
1134var contextX;
1135var contextY;
1136function showContextMenu()
1137{
1138  Menu.showTopMenu(document.getElementById('menuContext'), contextX, contextY);
1139}
1140
1141function goCreate()
1142{
1143  var submitInfo = {};
1144  var plateInfo = {};
1145  var flaggedRnaInfo = [];
1146 
1147  submitInfo.bioplate = plateInfo;
1148  submitInfo.flagged = flaggedRnaInfo;
1149  var frm = document.forms['reggie'];
1150 
1151  var schema = POOL_SCHEMA[frm.pool_schema.selectedIndex];
1152 
1153  plateInfo.name = Plate.name;
1154  plateInfo.comments = frm.comments.value;
1155  plateInfo.poolSchema = schema ? schema.id : null;
1156  plateInfo.wells = [];
1157
1158  var wells = Plate.getWells();
1159  var numErrors = 0;
1160  var numWarnings = 0;
1161  var numRna = 0;
1162  var numStratagene = 0;
1163  var numExternal = 0;
1164  for (var i = 0; i < wells.length; i++)
1165  {
1166    var well = wells[i];
1167    var rna = well.extract;
1168    if (well.hasWarning())
1169    {
1170      numWarnings++;
1171    }
1172    if (well.hasError())
1173    {
1174      numErrors++;
1175    }
1176    else
1177    {
1178      if (rna && rna.id)
1179      {
1180        var tmp = {};
1181        tmp.row = well.row;
1182        tmp.column = well.column;
1183        tmp.rna = {};
1184        tmp.rna.id = rna.id;
1185        tmp.rna.usedQuantity = rna.qc ? QUANTITY_QC : QUANTITY_REGULAR;
1186        tmp.rna.comment = rna.comment;
1187        plateInfo.wells[plateInfo.wells.length] = tmp;
1188        numRna++;
1189        if (rna.stratagene) numStratagene++;
1190        if (rna.external) numExternal++;
1191      }
1192    }
1193  }
1194
1195  var flagged = Rna.getFlagged();
1196  for (var i = 0; i < flagged.length; i++)
1197  {
1198    var rna = flagged[i];
1199    var tmp = {};
1200    tmp.id = rna.id;
1201    tmp.flag = rna.flag;
1202    flaggedRnaInfo[flaggedRnaInfo.length] = tmp;
1203  }
1204 
1205  if (numErrors > 0)
1206  {
1207    alert('There are ' + numErrors + ' wells with errors. Please fix them before creating the mRNA plate.');
1208    return;
1209  }
1210
1211  if (numRna == 0)
1212  {
1213    alert('There is no RNA in any wells');
1214    return;
1215  }
1216 
1217  if (numWarnings > 0)
1218  {
1219    if (!confirm('There are ' + numWarnings + ' wells with a warning. Continue anyway?')) return;
1220  }
1221 
1222  if (schema)
1223  {
1224    var numPrimary = schema.numPools * schema.numWellsPerPool;
1225    if (numRna < numPrimary)
1226    {
1227      if (!confirm('Some of the primary wells are missing RNA. Continue anyway?')) return;
1228    }
1229  }
1230 
1231  if (numRna == numStratagene+numExternal)
1232  {
1233    if (!confirm('There are only wells with Stratagene or external RNA on this plate. Continue anyway?')) return;
1234  }
1235 
1236  Main.addClass(document.getElementById('step.1.section'), 'disabled');
1237  Main.hide('gocancel');
1238  Main.hide('gocreate');
1239
1240  if (debug) Main.debug(JSON.stringify(submitInfo));
1241 
1242  var request = Ajax.getXmlHttpRequest();
1243  var url = '../MRna.servlet?ID=<%=ID%>';
1244  url += '&cmd=CreateMRnaPlate';
1245  request.open("POST", url, false);
1246  request.setRequestHeader("Content-Type", "application/json");
1247  request.send(JSON.stringify(submitInfo));
1248
1249  if (debug) Main.debug(request.responseText);
1250
1251  var response = JSON.parse(request.responseText);
1252  if (response.status != 'ok')
1253  {
1254    setFatalError(response.message);
1255    return false;
1256  }
1257
1258  var msg = '<ul>';
1259  for (var i = 0; i < response.messages.length; i++)
1260  {
1261    msg += '<li>' + response.messages[i];
1262  }
1263  msg += '</ul>';
1264  setInnerHTML('done', msg);
1265  Main.show('done');
1266  Main.show('gorestart');
1267}
1268
1269function toggleInfo(what)
1270{
1271  var frm = document.forms['reggie'];
1272  var show = frm[what].checked;
1273  Main.addOrRemoveClass(document.getElementById('plate'), 'hide-'+what, !show);
1274}
1275
1276function showFlaggedRna()
1277{
1278  currentSelected = Plate.getSelected();
1279  currentIndex = 0;
1280
1281  var flagged = Rna.getFlagged();
1282  Main.openPopup('show_flagged_rna.jsp?ID=<%=ID%>&numFlagged='+flagged.length+'&numSelected='+currentSelected.length, 'FlaggedRna', 600, 400);
1283}
1284
1285function poolSchemaOnChange()
1286{
1287  var frm = document.forms['reggie'];
1288  var schema = POOL_SCHEMA[frm.pool_schema.selectedIndex];
1289  Plate.setPoolSchema(schema);
1290  Plate.paint(Plate.getWells());
1291  PoolSchema.buildPoolTableRow(schema, Plate.columns, true);
1292}
1293
1294</script>
1295<style>
1296
1297/* A well assigned for QC include a background icon as indicator */
1298.well.qc
1299{
1300  background-image: url('../images/mrnaqc.png');
1301  background-position: 98% 25%;
1302  background-repeat: no-repeat;
1303}
1304
1305/* A well which contain replicate RNA is also marked with an icon */
1306.well.replicate
1307{
1308  background-image: url('../images/copy.png');
1309  background-position: 98% 25%;
1310  background-repeat: no-repeat;
1311}
1312
1313/* A well that is both a replicate and QC need to re-arrange the icons a bit */
1314.well.qc.replicate
1315{
1316  background-image: url('../images/mrnaqc.png'), url('../images/copy.png');
1317  background-position: 98% 25%, 98% 75%;
1318  background-repeat: no-repeat;
1319}
1320
1321.well .missing
1322{
1323  font-style: italic;
1324}
1325
1326.plate.hide-location .location
1327{
1328  display: none;
1329}
1330.plate.hide-quantity .quantity
1331{
1332  display: none;
1333}
1334.plate.hide-volumes .volumes
1335{
1336  display: none;
1337}
1338.plate.hide-ndconc .ndconc
1339{
1340  display: none;
1341}
1342.volume
1343{
1344  color: #C80000;
1345}
1346.water
1347{
1348  color: #0000C8;
1349}
1350.comment
1351{
1352  font-style: italic;
1353}
1354#iconSpecialSelect
1355{
1356  cursor: pointer;
1357}
1358#flaggedRna:before
1359{
1360  content: url('../images/flag.png');
1361  padding-right: 4px;
1362}
1363</style>
1364</base:head>
1365<base:body onload="init()">
1366  <p:path><p:pathelement 
1367    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
1368    /><p:pathelement title="Create new mRNA plate" 
1369    /></p:path>
1370  <div id="canvas" class="absolutefull" style="z-index: -1;">
1371  <div class="content">
1372  <%
1373  if (sc.getActiveProjectId() == 0)
1374  {
1375    %>
1376    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
1377      No project has been selected. You may proceed with the wizard but
1378      created items will not be shared.
1379    </div>
1380    <%
1381  }
1382  %>
1383  <m:menu
1384    id="menuSpecialSelect"
1385    style="display: none; font-weight: normal; text-align: left;">
1386    <m:menuitem 
1387      title="All" 
1388      onclick="specialToggle('all')"
1389      tooltip="Select/deselect all wells on the plate"
1390    />
1391    <m:menuitem 
1392      title="None" 
1393      onclick="specialToggle('none')"
1394      tooltip="Deselect all wells on the plate (no toggle!)"
1395    />
1396    <m:menuitem 
1397      title="Primary" 
1398      onclick="specialToggle('pools')"
1399      tooltip="Select/deselect all primary wells on the plate"
1400    />
1401    <m:menuitem 
1402      title="All empty" 
1403      onclick="specialToggle('empty')"
1404      tooltip="Select/deselect all empty wells on the plate"
1405    />
1406    <m:menuitem 
1407      title="Empty in primary" 
1408      onclick="specialToggle('empty-pools')"
1409      tooltip="Select/deselect all empty primary wells on the plate"
1410    />
1411    <m:menuseparator />
1412    <m:menuitem 
1413      icon="<%=home+"/images/stratagene.png"%>"
1414      title="Stratagene" 
1415      onclick="specialToggle('stratagene')"
1416      tooltip="Select/deselect all wells with Stratagene"
1417    />
1418    <m:menuitem 
1419      icon="<%=home+"/images/external.png"%>"
1420      title="External" 
1421      onclick="specialToggle('external')"
1422      tooltip="Select/deselect all wells with external RNA"
1423    />
1424    <m:menuitem 
1425      icon="<%=home+"/images/copy.png"%>"
1426      title="Replicates" 
1427      onclick="specialToggle('replicates')"
1428      tooltip="Select/deselect all wells with replicated RNA"
1429    />
1430    <m:menuitem 
1431      icon="<%=home+"/images/error.png"%>"
1432      title="Error" 
1433      onclick="specialToggle('error')"
1434      tooltip="Select/deselect all wells with an error"
1435    />
1436    <m:menuitem 
1437      icon="<%=home+"/images/warning.png"%>"
1438      title="Warning" 
1439      onclick="specialToggle('warning')"
1440      tooltip="Select/deselect all wells with an error"
1441    />
1442  </m:menu>
1443 
1444  <m:menu
1445    id="menuContext"
1446    style="display: none; font-weight: normal; text-align: left;">
1447    <m:menuitem 
1448      title="Comments&hellip;" 
1449      icon="<%=home+"/images/comment.png"%>" 
1450      onclick="commentSelected()"
1451      tooltip="Add a comment to the selected wells"
1452    />
1453    <m:menuseparator />
1454    <m:menuitem 
1455      title="Cut&hellip;" 
1456      icon="<%=home+"/images/cut.png"%>" 
1457      onclick="cutSelected()" 
1458      tooltip="Clear the selected wells" 
1459    />
1460    <m:menuitem 
1461      title="Copy" 
1462      icon="<%=home+"/images/copy.png"%>" 
1463      onclick="copySelected()" 
1464      tooltip="Make a copy of the selected RNA" 
1465    />
1466    <m:menuitem 
1467      title="Paste" 
1468      icon="<%=home+"/images/paste.png"%>" 
1469      onclick="pasteToSelected()" 
1470      tooltip="Paste RNA into selected wells" 
1471    />
1472    <m:menuitem 
1473      title="Switch" 
1474      icon="<%=home+"/images/switch.png"%>" 
1475      onclick="switchSelected()" 
1476      tooltip="Switch the selected wells (if exactly two)" 
1477    />
1478    <m:menuseparator />
1479    <m:menuitem 
1480      title="Toggle QC" 
1481      icon="<%=home+"/images/mrnaqc.png"%>" 
1482      onclick="toggleQc()" 
1483      tooltip="Select/deselect RNA for QC" 
1484    />
1485  </m:menu>
1486
1487  <form name="reggie" onsubmit="return false;">
1488 
1489  <table class="stepform" id="step.1.section" style="width: auto;">
1490  <tr>
1491    <td rowspan="3" class="stepno">1</td>
1492    <td class="steptitle">Fragmented mRNA plate</td>
1493  </tr>
1494  <tr>
1495    <td class="stepfields">
1496      <table class="bottomborder" style="width: 100%;">
1497      <tr>
1498        <td class="prompt">Name</td>
1499        <td class="input" id="plateName"></td>
1500        <td class="help">Select RNA items to use for the new mRNA plate.</td>
1501      </tr>
1502      <tr valign="top">
1503        <td class="prompt">Preliminary pool layout</td>
1504        <td class="input">
1505          <select name="pool_schema" onchange="poolSchemaOnChange()"></select>
1506        </td>
1507        <td class="help">Preliminary pool layout (can be changed later).</td>
1508      </tr>
1509      <tr valign="top">
1510        <td class="prompt">Comments</td>
1511        <td class="input">
1512          <textarea rows="2" style="width: 90%;" name="comments" value=""></textarea>
1513        </td>
1514        <td class="help">Comments about the new mRNA plate.</td>
1515      </tr>
1516      <tr style="vertical-align: top;">
1517        <td class="prompt">Show</td>
1518        <td class="input">
1519          <table>
1520          <tr>
1521            <td>
1522              <input type="checkbox" name="location" id="location" onclick="toggleInfo('location')" checked><label for="location">Bioplate location</label><br>
1523              <input type="checkbox" name="quantity" id="quantity" onclick="toggleInfo('quantity')" checked><label for="quantity">Remaining quantity</label><br>
1524            </td>
1525            <td>
1526              <input type="checkbox" name="ndconc" id="ndconc" onclick="toggleInfo('ndconc')"><label for="ndconc">NDConc</label><br>
1527              <input type="checkbox" name="volumes" id="volumes" onclick="toggleInfo('volumes')"><label for="volumes">Used volume+water</label><br>
1528            </td>
1529          </tr>
1530          </table>
1531        </td>
1532        <td class="help">Toggles visiblity of the selected information inside each well on the plate.</td>
1533      </tr>
1534      <tr style="vertical-align: top;">
1535        <td class="prompt">Context menu</td>
1536        <td class="input">
1537          <input type="radio" name="contextMenu" id="contextMenuRight" checked><label for="contextMenuRight">Right</label>
1538          <input type="radio" name="contextMenu" id="contextMenuMiddle"><label for="contextMenuMiddle">Middle</label> mouse button<br>
1539          <br>
1540        </td>
1541        <td class="help">Use the selected mouse button to display a context-menu when clicking on the plate.</td>
1542      </tr>
1543      </table>
1544    </td>
1545  </tr>
1546 
1547  <tr>
1548    <td>
1549      <tbl:toolbar subclass="bottomborder">
1550        <tbl:button 
1551          title="Load from file&hellip;" 
1552          image="<%=home+"/images/file.png"%>" 
1553          onclick="selectFile()" 
1554          tooltip="Load plate design from file"
1555        />
1556       
1557        <tbl:button 
1558          title="Auto-select&hellip;" 
1559          image="<%=home+"/images/wizard.png"%>" 
1560          onclick="autoSelect()" 
1561          tooltip="Let the wizard auto-select RNA"
1562        />
1563        <tbl:button 
1564          title="Manual select&hellip;" 
1565          image="<%=home+"/images/manual_rna.png"%>" 
1566          onclick="manualSelect()" 
1567          tooltip="Manually select RNA items" 
1568        />
1569        <tbl:button 
1570          title="Stratagene" 
1571          image="<%=home+"/images/stratagene.png"%>" 
1572          onclick="setToStratagene()" 
1573          tooltip="Place stratagene in the selected wells" 
1574        />
1575        <tbl:button 
1576          title="External" 
1577          image="<%=home+"/images/external.png"%>" 
1578          onclick="setToExternal()" 
1579          tooltip="Mark selected wells as used by external RNA" 
1580        />
1581        <tbl:button 
1582          title="Toggle QC" 
1583          image="<%=home+"/images/mrnaqc.png"%>" 
1584          onclick="toggleQc()" 
1585          tooltip="Select/deselect RNA for QC" 
1586        />
1587        <tbl:button 
1588          title="Comments&hellip;" 
1589          image="<%=home+"/images/comment.png"%>" 
1590          onclick="commentSelected()" 
1591          tooltip="Add a comment to the selected wells" 
1592        />
1593        <tbl:button 
1594          title="Cut&hellip;" 
1595          image="<%=home+"/images/cut.png"%>" 
1596          onclick="cutSelected()" 
1597          tooltip="Clear the selected wells" 
1598        />
1599        <tbl:button 
1600          title="Copy" 
1601          image="<%=home+"/images/copy.png"%>" 
1602          onclick="copySelected()" 
1603          tooltip="Make a copy of the selected RNA" 
1604        />
1605        <tbl:button 
1606          title="Paste" 
1607          image="<%=home+"/images/paste.png"%>" 
1608          onclick="pasteToSelected()" 
1609          tooltip="Paste RNA into selected wells" 
1610        />
1611        <tbl:button 
1612          title="Switch" 
1613          image="<%=home+"/images/switch.png"%>" 
1614          onclick="switchSelected()" 
1615          tooltip="Switch the selected wells (if exactly two)" 
1616        />
1617      </tbl:toolbar>
1618        <div id="flaggedRna" style="margin: 0.5em 1em 0 1em; display: none; " class="link" onclick="showFlaggedRna()">
1619          Flagged RNA items.
1620        </div>
1621
1622        <table class="plate hide-volumes hide-ndconc" style="margin: 1em 1em 0 1em;" id="plate"
1623          onmouseup="contextEvent(event)"
1624          oncontextmenu="contextEvent(event)"
1625          >
1626        <%
1627        int columns = 12;
1628        int rows = 8;
1629        WellCoordinateFormatter rowF = new WellCoordinateFormatter(true);
1630        WellCoordinateFormatter colF = new WellCoordinateFormatter(false);
1631        %>
1632        <tr class="header">
1633          <th>
1634            <base:icon image="<%=home+"/images/select_all.png"%>" 
1635              id="iconSpecialSelect"
1636              tooltip="Select/deselect wells on the plate with specific condition" 
1637            >
1638          </base:icon>
1639        </th>
1640          <%
1641          for (int c = 0; c < columns; ++c)
1642          {
1643            %>
1644            <th class="link" id="col.<%=c%>"
1645              onclick="toggleColumn(<%=c%>)" 
1646              onmouseover="highlightColumn(<%=c%>, true)"
1647              onmouseout="highlightColumn(<%=c%>, false)"
1648              title="Select/deselect all wells in this column"><%=colF.format(c)%></th>
1649            <%
1650          }
1651          %>
1652        </tr>
1653        <tbody>
1654        <%
1655        for (int r = 0; r < rows; ++r)
1656        {
1657          String row = rowF.format(r);
1658          %>
1659          <tr class="row-<%=r%>">
1660            <th class="link" id="row.<%=r%>"
1661              onclick="toggleRow(<%=r%>)"
1662              onmouseover="highlightRow(<%=r%>, true)"
1663              onmouseout="highlightRow(<%=r%>, false)"
1664              title="Select/deselect all wells in this row"><%=row%></th>
1665            <%
1666            for (int c = 0; c < columns; ++c)
1667            {
1668              %>
1669              <td id="well.<%=r%>.<%=c%>" 
1670                onclick="toggleWell(<%=r%>,<%=c%>)"
1671                onmouseenter="highlightReplicated(<%=r%>, <%=c%>, true)" 
1672                onmouseleave="highlightReplicated(<%=r%>, <%=c%>, false)"
1673                title="Select/deselect this well"></td>
1674              <%
1675            }
1676            %>
1677          </tr>
1678          <%
1679        }
1680        %>
1681        </tbody>
1682        <tr id="pool-row" 
1683          onclick="poolOnClick(event)" 
1684          onmouseover="poolEnter(event)" 
1685          onmouseout="poolLeave(event)">
1686          <th colspan="13">&nbsp;</th>
1687        </tr>
1688        </table>
1689        <div style="padding-left: 1em; padding-bottom: 0.5em; padding-top: 2px;">
1690          <base:icon image="<%=home+"/images/mrnaqc.png"%>" />=Selected for QC
1691          <base:icon image="<%=home+"/images/copy.png"%>" style="padding-left: 1em;" />=Replicated RNA
1692          <base:icon image="<%=home+"/images/error.png"%>" style="padding-left: 1em;" />=Error that prevent plate creation
1693          <base:icon image="<%=home+"/images/warning.png"%>" style="padding-left: 1em;" />=Warning but plate can be created
1694        </div>
1695    </td>
1696  </tr>
1697  </table>
1698 
1699
1700  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
1701
1702  <div id="done" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
1703
1704  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
1705  <tr>
1706    <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" /></td>
1707    <td><base:button id="gocreate" title="Create" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" /></td>
1708    <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
1709  </tr>
1710  </table>
1711  </form>
1712 
1713  <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>
1714 
1715</div>
1716  </div>
1717</base:body>
1718</base:page>
1719<%
1720}
1721finally
1722{
1723  if (dc != null) dc.close();
1724}
1725%>
Note: See TracBrowser for help on using the repository browser.