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

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

References #424, #425, #457, #479. Re-designed protocols to make the header section a bit more compact when the comment text is large. Display a warning when the remaining RNA quanitity is below 1.5 times the required amount (eg. 1.1µg or 1.22µg).

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