extensions/net.sf.basedb.meludi/trunk/resources/libprep/select_dna_for_start_plate.js

Code
Comments
Other
Rev Date Author Line
3449 28 Jul 15 olle 1 var SelectDna = function()
3449 28 Jul 15 olle 2 {
3449 28 Jul 15 olle 3   var selectdna = {};
3449 28 Jul 15 olle 4   var barcodesByName = [];
3449 28 Jul 15 olle 5   
3449 28 Jul 15 olle 6   var EXTERNAL_DNA_NAME = 'External.d';
3449 28 Jul 15 olle 7   var debug = 0;
3449 28 Jul 15 olle 8   
3573 05 Nov 15 olle 9   var currentSelected;
3573 05 Nov 15 olle 10   var names = [];
3631 27 Nov 15 olle 11   var originalNames = [];
3631 27 Nov 15 olle 12   var originalNamesHasBeenLoaded = false;
3619 23 Nov 15 olle 13   var protocolMap = {};
3582 06 Nov 15 olle 14   var kitNum = 0;
3582 06 Nov 15 olle 15   var selectedKitName;
4200 01 Nov 16 olle 16   var startPlatePrefix;
3573 05 Nov 15 olle 17
3449 28 Jul 15 olle 18   var graphics;
3449 28 Jul 15 olle 19   var pen;
3449 28 Jul 15 olle 20   
3449 28 Jul 15 olle 21   var quantitiesAreValid = false;
3449 28 Jul 15 olle 22   var plateNameIsValid = false;
3449 28 Jul 15 olle 23   var subtypeDna;
3573 05 Nov 15 olle 24   var subtypeDnaNormalized;
3617 23 Nov 15 olle 25   var MINIMAL_DNA_VOLUME = 1.0; //µl
3573 05 Nov 15 olle 26   var THIN_SPACE = ' ';
3573 05 Nov 15 olle 27   
3573 05 Nov 15 olle 28   var jsonRowIndex = {"A": 0, "B": 1, "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7};
3573 05 Nov 15 olle 29   var jsonColIndex = {"1": 0, "2": 1, "3": 2, "4": 3, "5": 4, "6": 5, "7": 6, "8": 7, "9": 8, "10": 9, "11": 10, "12": 11};
3590 11 Nov 15 olle 30   var jsonRowLetter = {0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H"};
3590 11 Nov 15 olle 31   var jsonColNumber = {0: "1", 1: "2", 2: "3", 3: "4", 4: "5", 5: "6", 6: "7", 7: "8", 8: "9", 9: "10", 10: "11", 11: "12"};
3449 28 Jul 15 olle 32
3449 28 Jul 15 olle 33   // Page initialization
3449 28 Jul 15 olle 34   selectdna.initPage = function()
3449 28 Jul 15 olle 35   {
3449 28 Jul 15 olle 36     // Step 1
3449 28 Jul 15 olle 37     Events.addEventHandler('step-1', 'wizard-validate', selectdna.validateStep1);
3449 28 Jul 15 olle 38
3449 28 Jul 15 olle 39     // Step 2
3449 28 Jul 15 olle 40     Events.addEventHandler('step-2', 'wizard-initialize', selectdna.initializeStep2);
3449 28 Jul 15 olle 41     Events.addEventHandler('step-2', 'wizard-validate', selectdna.validateStep2);
3449 28 Jul 15 olle 42
3449 28 Jul 15 olle 43     Events.addEventHandler('max_delta_ct', 'change', selectdna.maxDeltaCtOnChange);
3449 28 Jul 15 olle 44     Events.addEventHandler('max_delta_ct', 'keypress', Events.numberOnly);
3449 28 Jul 15 olle 45
3449 28 Jul 15 olle 46     // Step 3
3449 28 Jul 15 olle 47     Events.addEventHandler('step-3', 'wizard-initialize', selectdna.initializeStep3);
3573 05 Nov 15 olle 48     //Events.addEventHandler('step-3', 'wizard-validate', selectdna.validateStep3);
3631 27 Nov 15 olle 49     Buttons.addClickHandler('btnManualSelectExtract', selectdna.manualSelectExtract);
3631 27 Nov 15 olle 50     Buttons.addClickHandler('btnManualSelectControl', selectdna.manualSelectControl);
3631 27 Nov 15 olle 51     Events.addEventHandler('plate', 'base-selected', selectdna.manuallySelectedExtract);
3631 27 Nov 15 olle 52     Buttons.addClickHandler('btnManualSelectReset', selectdna.manualSelectReset);
3449 28 Jul 15 olle 53
3573 05 Nov 15 olle 54     // Step 4
3573 05 Nov 15 olle 55     Events.addEventHandler('step-4', 'wizard-initialize', selectdna.initializeStep4);
3573 05 Nov 15 olle 56     Events.addEventHandler('step-4', 'wizard-validate', selectdna.validateStep4);
3573 05 Nov 15 olle 57
3449 28 Jul 15 olle 58     Events.addEventHandler('plateName', 'change', selectdna.plateNameOnChange);
3449 28 Jul 15 olle 59     Events.addEventHandler('pool_schema', 'change', selectdna.poolSchemaOnChange);
3449 28 Jul 15 olle 60     Events.addEventHandler('barcode_variant', 'change', selectdna.barcodeVariantOnChange);
3617 23 Nov 15 olle 61 /*
3449 28 Jul 15 olle 62     Events.addEventHandler('quantity_regular', 'change', selectdna.quantityOnChange);
3617 23 Nov 15 olle 63 */
3617 23 Nov 15 olle 64     Events.addEventHandler('min_vol_dna', 'change', selectdna.minVolDnaOnChange);
3596 12 Nov 15 olle 65 /*
3449 28 Jul 15 olle 66     Events.addEventHandler('quantity_qc', 'change', selectdna.quantityOnChange);
3596 12 Nov 15 olle 67 */
3617 23 Nov 15 olle 68 /*
3449 28 Jul 15 olle 69     Events.addEventHandler('quantity_regular', 'keypress', Events.numberOnly);
3617 23 Nov 15 olle 70 */
3617 23 Nov 15 olle 71     Events.addEventHandler('min_vol_dna', 'keypress', Events.numberOnly);
3596 12 Nov 15 olle 72 /*
3449 28 Jul 15 olle 73     Events.addEventHandler('quantity_qc', 'keypress', Events.numberOnly);
3596 12 Nov 15 olle 74 */
3449 28 Jul 15 olle 75     
3449 28 Jul 15 olle 76     //Events.addEventHandler('warning_quantity', 'change', selectdna.warningLevelOnChange);
3449 28 Jul 15 olle 77     Events.addEventHandler('warning_quality_score', 'change', selectdna.warningLevelOnChange);
3449 28 Jul 15 olle 78     //Events.addEventHandler('warning_quantity', 'keypress', Events.numberOnly);
3449 28 Jul 15 olle 79     Events.addEventHandler('warning_quality_score', 'keypress', Events.numberOnly);
3449 28 Jul 15 olle 80     
3449 28 Jul 15 olle 81     Events.addEventHandler('location', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 82     Events.addEventHandler('quantity', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 83     Events.addEventHandler('quality-score', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 84     Events.addEventHandler('qubitconc', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 85     Events.addEventHandler('volumes', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 86     Events.addEventHandler('qiacube-date', 'click', selectdna.toggleInfo);
3449 28 Jul 15 olle 87     
3449 28 Jul 15 olle 88     Events.addEventHandler('pool-row', 'click', selectdna.togglePool);
3449 28 Jul 15 olle 89     Events.addEventHandler('pool-row', 'mouseover', selectdna.highlightPool);
3449 28 Jul 15 olle 90     Events.addEventHandler('pool-row', 'mouseout', selectdna.highlightPool);
3594 12 Nov 15 olle 91
3594 12 Nov 15 olle 92 /*    
3449 28 Jul 15 olle 93     Buttons.addClickHandler('btnLoadFromFile', selectdna.selectFile);
3449 28 Jul 15 olle 94     Buttons.addClickHandler('btnAutoSelect', selectdna.autoSelect);
3449 28 Jul 15 olle 95     Buttons.addClickHandler('btnManualSelect', selectdna.manualSelect);
3449 28 Jul 15 olle 96     Events.addEventHandler('plate', 'base-selected', selectdna.manuallySelected);
3449 28 Jul 15 olle 97     Buttons.addClickHandler('btnStratagene', selectdna.setToStratagene);
3449 28 Jul 15 olle 98     Buttons.addClickHandler('btnExternal', selectdna.setToExternal);
3449 28 Jul 15 olle 99     Buttons.addClickHandler('btnToggleQc', selectdna.toggleQc);
3449 28 Jul 15 olle 100     Buttons.addClickHandler('btnComment', selectdna.commentSelected);
3449 28 Jul 15 olle 101     Buttons.addClickHandler('btnCutSelected', selectdna.cutSelected);
3449 28 Jul 15 olle 102     Buttons.addClickHandler('btnCopySelected', selectdna.copySelected);
3449 28 Jul 15 olle 103     Buttons.addClickHandler('btnPasteToSelected', selectdna.pasteToSelected);
3709 20 Jan 16 olle 104 */
3449 28 Jul 15 olle 105     Buttons.addClickHandler('btnSwitch', selectdna.switchSelected);
3709 20 Jan 16 olle 106
3624 25 Nov 15 olle 107     Buttons.addClickHandler('downloadLibPrepFile', selectdna.downloadLibPrepFile);
3593 12 Nov 15 olle 108
3449 28 Jul 15 olle 109     Events.addEventHandler('iconSpecialSelect', 'click', selectdna.toggleSpecialSelect);
3449 28 Jul 15 olle 110     Events.addEventHandler('plate', 'mouseup', selectdna.contextEvent);
3449 28 Jul 15 olle 111     Events.addEventHandler('plate', 'contextmenu', selectdna.contextEvent);
3449 28 Jul 15 olle 112     Events.addEventHandler('mnuComment', 'click', selectdna.commentSelected);
3593 12 Nov 15 olle 113 /*
3449 28 Jul 15 olle 114     Events.addEventHandler('mnuToggleQc', 'click', selectdna.toggleQc);
3449 28 Jul 15 olle 115     Events.addEventHandler('mnuCutSelected', 'click', selectdna.cutSelected);
3449 28 Jul 15 olle 116     Events.addEventHandler('mnuCopySelected', 'click', selectdna.copySelected);
3449 28 Jul 15 olle 117     Events.addEventHandler('mnuPasteToSelected', 'click', selectdna.pasteToSelected);
3709 20 Jan 16 olle 118 */
3449 28 Jul 15 olle 119     Events.addEventHandler('mnuSwitch', 'click', selectdna.switchSelected);
3449 28 Jul 15 olle 120     Events.addEventHandler('mnuCaseSummary', 'click', selectdna.showCaseSummary);
3593 12 Nov 15 olle 121 /*
3449 28 Jul 15 olle 122     Events.addEventHandler('mnuFlagLowQualityScore', 'click', selectdna.flagSelected);
3449 28 Jul 15 olle 123     Events.addEventHandler('mnuFlagNotEnoughRemainingQuantity', 'click', selectdna.flagSelected);
3449 28 Jul 15 olle 124     Events.addEventHandler('mnuFlagOther', 'click', selectdna.flagSelected);
3593 12 Nov 15 olle 125 */
3449 28 Jul 15 olle 126
3449 28 Jul 15 olle 127     Events.addEventHandler('flaggedDna', 'click', selectdna.showFlaggedDna);
3449 28 Jul 15 olle 128
3685 12 Jan 16 olle 129     Events.addEventHandler('listview', 'click', selectdna.viewProtocol);
3685 12 Jan 16 olle 130     Events.addEventHandler('plateview', 'click', selectdna.viewProtocol);
3449 28 Jul 15 olle 131
3449 28 Jul 15 olle 132     // Navigation
3449 28 Jul 15 olle 133     Buttons.addClickHandler('gocancel', Wizard.cancelWizard);
3449 28 Jul 15 olle 134     Buttons.addClickHandler('gorestart', Wizard.restartWizard);
3449 28 Jul 15 olle 135     Buttons.addClickHandler('gonext', Wizard.goNextOnClick);
3449 28 Jul 15 olle 136     Buttons.addClickHandler('goregister', Wizard.goRegister);
3590 11 Nov 15 olle 137     Buttons.addClickHandler('gocreate', selectdna.createProtocol);
3449 28 Jul 15 olle 138     
3449 28 Jul 15 olle 139     // Final registration
3449 28 Jul 15 olle 140     Events.addEventHandler('wizard', 'wizard-submit', selectdna.submit);
3449 28 Jul 15 olle 141
4200 01 Nov 16 olle 142     // Load configuration
4200 01 Nov 16 olle 143     selectdna.loadConfiguration();
4200 01 Nov 16 olle 144   }
4200 01 Nov 16 olle 145
4200 01 Nov 16 olle 146   selectdna.loadConfiguration = function()
4200 01 Nov 16 olle 147   {
4200 01 Nov 16 olle 148     var url = '../Session.servlet?ID='+App.getSessionId();
4200 01 Nov 16 olle 149     url += '&cmd=GetConfiguration';
4200 01 Nov 16 olle 150     var request = Ajax.getXmlHttpRequest();
4200 01 Nov 16 olle 151     request.open("GET", url, true);
4200 01 Nov 16 olle 152     Ajax.setReadyStateHandler(request, selectdna.onConfiguration, selectdna.onConfiguration);
4200 01 Nov 16 olle 153     request.send(null);
4200 01 Nov 16 olle 154   }
4200 01 Nov 16 olle 155
4200 01 Nov 16 olle 156   selectdna.onConfiguration = function(request)
4200 01 Nov 16 olle 157   {
4200 01 Nov 16 olle 158     if (debug)
4200 01 Nov 16 olle 159     {
4200 01 Nov 16 olle 160       App.debug(Strings.encodeTags(request.responseText));
4200 01 Nov 16 olle 161     }
4200 01 Nov 16 olle 162
4200 01 Nov 16 olle 163     var response;
4200 01 Nov 16 olle 164     var error = false;
4200 01 Nov 16 olle 165     try
4200 01 Nov 16 olle 166     {
4200 01 Nov 16 olle 167       response = JSON.parse(request.responseText);
4200 01 Nov 16 olle 168       if (response.status != 'ok')
4200 01 Nov 16 olle 169       {
4200 01 Nov 16 olle 170         error = response.message || response.stacktrace || 'Unexpected error';
4200 01 Nov 16 olle 171       }
4200 01 Nov 16 olle 172     }
4200 01 Nov 16 olle 173     catch (ex)
4200 01 Nov 16 olle 174     {
4200 01 Nov 16 olle 175       error = ex;
4200 01 Nov 16 olle 176     }
4200 01 Nov 16 olle 177     if (error) App.debug(error);
4200 01 Nov 16 olle 178
4200 01 Nov 16 olle 179     // Get configuration result
4200 01 Nov 16 olle 180     var conf = response.configuration;
4200 01 Nov 16 olle 181     // Check for start plate prefix
4200 01 Nov 16 olle 182     startPlatePrefix = conf.startPlateItemPrefix;
4200 01 Nov 16 olle 183
4200 01 Nov 16 olle 184     // Continue with initializing info for start plate
3449 28 Jul 15 olle 185     var url = '../Extraction.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 186 /*
3449 28 Jul 15 olle 187     url += '&cmd=GetStartItemLists';
3449 28 Jul 15 olle 188 */
3449 28 Jul 15 olle 189     url += '&cmd=GetProcessedStartItemLists';
3644 03 Dec 15 olle 190     url += '&orderDesc=true';
3644 03 Dec 15 olle 191     url += '&anItemNotOnLibPlate=true';
3719 22 Jan 16 olle 192     url += '&ignoreQpcrBranch=true';
3719 22 Jan 16 olle 193     Wizard.showLoadingAnimation('Loading processed items...');
3449 28 Jul 15 olle 194     Wizard.asyncJsonRequest(url, selectdna.initializeStep1);
3449 28 Jul 15 olle 195   }
3449 28 Jul 15 olle 196
3449 28 Jul 15 olle 197   selectdna.initializeStep1 = function(response)
3449 28 Jul 15 olle 198   {
3449 28 Jul 15 olle 199     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 200     var itemLists = response.itemLists;
3631 27 Nov 15 olle 201
3631 27 Nov 15 olle 202     // Reset JSONArray for original names    
3631 27 Nov 15 olle 203     originalNames = [];
3631 27 Nov 15 olle 204     originalNamesHasBeenLoaded = false;
3631 27 Nov 15 olle 205
3449 28 Jul 15 olle 206     var startList = frm.startList;
3449 28 Jul 15 olle 207     if (itemLists.length > 0)
3449 28 Jul 15 olle 208     {
3449 28 Jul 15 olle 209       for (var i=0; i < itemLists.length; i++)
3449 28 Jul 15 olle 210       {
3449 28 Jul 15 olle 211         var itemList = itemLists[i];
3449 28 Jul 15 olle 212         var name = (i+1) + ': ' + Strings.encodeTags(itemList.name);
3449 28 Jul 15 olle 213         if (itemList.sourceItemNames)
3449 28 Jul 15 olle 214         {
3449 28 Jul 15 olle 215           name += ' -- (';
3449 28 Jul 15 olle 216           name += itemList.numMeludiItems;
3449 28 Jul 15 olle 217           name += ' + ' + itemList.numExtraItems;
3449 28 Jul 15 olle 218           name += ')';
3449 28 Jul 15 olle 219         }
3449 28 Jul 15 olle 220         if (itemList.extractionDate)
3449 28 Jul 15 olle 221         {
3449 28 Jul 15 olle 222           name += ' -- [' + selectdna.asDate(itemList.extractionDate) + ']';
3449 28 Jul 15 olle 223         }
3449 28 Jul 15 olle 224         var selected = (i == 0);
3449 28 Jul 15 olle 225         var option = new Option(name, itemList.id, selected, selected);
3449 28 Jul 15 olle 226         option.itemList = itemList;
3449 28 Jul 15 olle 227         startList.options[startList.length] = option;
3449 28 Jul 15 olle 228       }
3449 28 Jul 15 olle 229       startList.options[0].selected = true;
3449 28 Jul 15 olle 230     }
3449 28 Jul 15 olle 231     else
3449 28 Jul 15 olle 232     {
3449 28 Jul 15 olle 233       Wizard.setFatalError('No start lists available.');
3449 28 Jul 15 olle 234       return;
3449 28 Jul 15 olle 235     }
3449 28 Jul 15 olle 236     Doc.show('step-1');
3449 28 Jul 15 olle 237     Doc.show('gocancel');
3449 28 Jul 15 olle 238     Doc.show('gonext');
3449 28 Jul 15 olle 239     Doc.hide('goregister');
3590 11 Nov 15 olle 240     Doc.hide('gocreate');
3449 28 Jul 15 olle 241     Doc.hide('extractSourceItems');
3449 28 Jul 15 olle 242   }
3449 28 Jul 15 olle 243
3449 28 Jul 15 olle 244   selectdna.validateStep1 = function(event)
3449 28 Jul 15 olle 245   {
3449 28 Jul 15 olle 246     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 247 /*
3449 28 Jul 15 olle 248     var startList = null;
3449 28 Jul 15 olle 249     for (var i = 0; i < frm.startList.length; i++)
3449 28 Jul 15 olle 250     {
3449 28 Jul 15 olle 251       if (frm.startList[i].selected)
3449 28 Jul 15 olle 252       {
3449 28 Jul 15 olle 253         startList = frm.startList[i];
3449 28 Jul 15 olle 254       }
3449 28 Jul 15 olle 255     }
3449 28 Jul 15 olle 256     if (startList == null)
3449 28 Jul 15 olle 257     {
3449 28 Jul 15 olle 258       event.preventDefault();
3449 28 Jul 15 olle 259     }
3449 28 Jul 15 olle 260 */
3449 28 Jul 15 olle 261   }
3449 28 Jul 15 olle 262   
3449 28 Jul 15 olle 263   selectdna.initializeStep2 = function(event)
3449 28 Jul 15 olle 264   {
3449 28 Jul 15 olle 265     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 266     var startItemList = null;
3449 28 Jul 15 olle 267     var jsonStartItemListIds = [];
3449 28 Jul 15 olle 268     var numSelected = 0;
3449 28 Jul 15 olle 269     for (var i = 0; i < frm.startList.length; i++)
3449 28 Jul 15 olle 270     {
3449 28 Jul 15 olle 271       if (frm.startList[i].selected)
3449 28 Jul 15 olle 272       {
3449 28 Jul 15 olle 273         var jsonStartList = {};
3449 28 Jul 15 olle 274         jsonStartList.id = frm.startList[i].value;
3449 28 Jul 15 olle 275         jsonStartItemListIds[numSelected] = jsonStartList;
3449 28 Jul 15 olle 276         numSelected++;
3449 28 Jul 15 olle 277       }
3449 28 Jul 15 olle 278     }
3449 28 Jul 15 olle 279 //alert("select_dna_for_start_plate.js::initializeStep2(): numSelected = " + numSelected);
3449 28 Jul 15 olle 280     if (numSelected == 0)
3449 28 Jul 15 olle 281     {
3449 28 Jul 15 olle 282       event.preventDefault();
3449 28 Jul 15 olle 283     }
3449 28 Jul 15 olle 284
3449 28 Jul 15 olle 285     frm.startList.disabled = true;
3449 28 Jul 15 olle 286
3449 28 Jul 15 olle 287     Wizard.setCurrentStep(2);
3449 28 Jul 15 olle 288     Doc.show('step-2');
3449 28 Jul 15 olle 289     Doc.show('gocancel');
3449 28 Jul 15 olle 290     Doc.show('gonext');
3518 01 Oct 15 olle 291     Doc.addClass('gonext', 'disabled');
3449 28 Jul 15 olle 292     
3449 28 Jul 15 olle 293     var url = '../Extraction.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 294     url += '&cmd=GetListOfItemsFromStartItemLists';
3449 28 Jul 15 olle 295     url += '&startListIds='+JSON.stringify(jsonStartItemListIds);
3449 28 Jul 15 olle 296     url += '&itemType=DNA';
3644 03 Dec 15 olle 297     url += '&itemNotOnLibPlate=true';
3719 22 Jan 16 olle 298     url += '&ignoreQpcrBranch=true';
3449 28 Jul 15 olle 299     Wizard.asyncJsonRequest(url, selectdna.dnaItemListLoaded);
3449 28 Jul 15 olle 300   }
3449 28 Jul 15 olle 301
3449 28 Jul 15 olle 302   selectdna.dnaItemListLoaded = function(response)
3449 28 Jul 15 olle 303   {
3449 28 Jul 15 olle 304     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 305
3449 28 Jul 15 olle 306     var maxDeltaCt = frm.max_delta_ct.value;
3449 28 Jul 15 olle 307     var items = response.items;
3449 28 Jul 15 olle 308 //alert("selectdna.dnaItemListLoaded(): maxDeltaCt = " + maxDeltaCt + " items.length = " + items.length);
3449 28 Jul 15 olle 309
3449 28 Jul 15 olle 310     var sourceItemList = frm.extractDnaItems;
3449 28 Jul 15 olle 311
3449 28 Jul 15 olle 312     // Reset option list
3573 05 Nov 15 olle 313 //alert("selectdna.dnaItemListLoaded(): sourceItemList.length = " + sourceItemList.length + " sourceItemList = " + sourceItemList);
3449 28 Jul 15 olle 314     while (sourceItemList.length > 0)
3449 28 Jul 15 olle 315     {
3573 05 Nov 15 olle 316       sourceItemList.options[sourceItemList.length - 1] = null;
3449 28 Jul 15 olle 317     }
3449 28 Jul 15 olle 318
3449 28 Jul 15 olle 319     if (items.length > 0)
3449 28 Jul 15 olle 320     {
3449 28 Jul 15 olle 321       var numItems = items.length;
3449 28 Jul 15 olle 322       for (var i=0; i < items.length; i++)
3449 28 Jul 15 olle 323       {
3449 28 Jul 15 olle 324         var item = items[i];
3449 28 Jul 15 olle 325         // Only items with delta-Ct values included in list
3449 28 Jul 15 olle 326         if (item.deltaCt != null)
3449 28 Jul 15 olle 327         {
3449 28 Jul 15 olle 328           var name = (i+1) + ': ' + Strings.encodeTags(item.name);
3449 28 Jul 15 olle 329           if (item.bioWell)
3449 28 Jul 15 olle 330           {
3449 28 Jul 15 olle 331             name += ' -- ' + Strings.encodeTags(item.bioWell.bioPlate.name + ' (' + item.bioWell.location+')');
3449 28 Jul 15 olle 332           }
3719 22 Jan 16 olle 333           if (item.deltaCt)
3719 22 Jan 16 olle 334           {
3719 22 Jan 16 olle 335             name += ' -- (ΔCt = ' + Numbers.formatNumber(item.deltaCt, 2) + ')';
3719 22 Jan 16 olle 336           }
3449 28 Jul 15 olle 337           var selected = true;
3449 28 Jul 15 olle 338           if (item.deltaCt > maxDeltaCt)
3449 28 Jul 15 olle 339           {
3449 28 Jul 15 olle 340             selected = false;
3449 28 Jul 15 olle 341           }
3449 28 Jul 15 olle 342           var option = new Option(name, item.id, selected, selected);
3449 28 Jul 15 olle 343           option.item = item;
3449 28 Jul 15 olle 344           sourceItemList.options[sourceItemList.length] = option;
3449 28 Jul 15 olle 345         }
3449 28 Jul 15 olle 346       }
3449 28 Jul 15 olle 347     }
3449 28 Jul 15 olle 348 /*
3449 28 Jul 15 olle 349     else
3449 28 Jul 15 olle 350     {
3449 28 Jul 15 olle 351       Wizard.setFatalError('No items available for processing.');
3449 28 Jul 15 olle 352       return;
3449 28 Jul 15 olle 353     }
3449 28 Jul 15 olle 354 */
3518 01 Oct 15 olle 355     Doc.removeClass('gonext', 'disabled');
3449 28 Jul 15 olle 356   }
3449 28 Jul 15 olle 357   
3449 28 Jul 15 olle 358   selectdna.maxDeltaCtOnChange = function(event)
3449 28 Jul 15 olle 359   {
3449 28 Jul 15 olle 360     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 361     var startItemList = null;
3449 28 Jul 15 olle 362     var jsonStartItemListIds = [];
3449 28 Jul 15 olle 363     var numSelected = 0;
3449 28 Jul 15 olle 364     for (var i = 0; i < frm.startList.length; i++)
3449 28 Jul 15 olle 365     {
3449 28 Jul 15 olle 366       if (frm.startList[i].selected)
3449 28 Jul 15 olle 367       {
3449 28 Jul 15 olle 368         var jsonStartList = {};
3449 28 Jul 15 olle 369         jsonStartList.id = frm.startList[i].value;
3449 28 Jul 15 olle 370         jsonStartItemListIds[numSelected] = jsonStartList;
3449 28 Jul 15 olle 371         numSelected++;
3449 28 Jul 15 olle 372       }
3449 28 Jul 15 olle 373     }
3518 01 Oct 15 olle 374     Doc.addClass('gonext', 'disabled');
3449 28 Jul 15 olle 375
3449 28 Jul 15 olle 376     var url = '../Extraction.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 377     url += '&cmd=GetListOfItemsFromStartItemLists';
3449 28 Jul 15 olle 378     url += '&startListIds='+JSON.stringify(jsonStartItemListIds);
3449 28 Jul 15 olle 379     url += '&itemType=DNA';
3719 22 Jan 16 olle 380     url += '&itemNotOnLibPlate=true';
3719 22 Jan 16 olle 381     url += '&ignoreQpcrBranch=true';
3449 28 Jul 15 olle 382     Wizard.asyncJsonRequest(url, selectdna.dnaItemListLoaded);
3449 28 Jul 15 olle 383   }
3449 28 Jul 15 olle 384   
3449 28 Jul 15 olle 385   selectdna.validateStep2 = function(event)
3449 28 Jul 15 olle 386   {
3449 28 Jul 15 olle 387     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 388     var jsonItems = [];
3449 28 Jul 15 olle 389     var numSelected = 0;
3449 28 Jul 15 olle 390     for (var i = 0; i < frm.extractDnaItems.length; i++)
3449 28 Jul 15 olle 391     {
3449 28 Jul 15 olle 392       if (frm.extractDnaItems[i].selected)
3449 28 Jul 15 olle 393       {
3449 28 Jul 15 olle 394 /*
3449 28 Jul 15 olle 395         var jsonItem = {};
3449 28 Jul 15 olle 396         jsonItem.id = frm.extractDnaItems[i].value;
3449 28 Jul 15 olle 397         jsonItem = frm.extractDnaItems[i].item;
3449 28 Jul 15 olle 398 */
3449 28 Jul 15 olle 399         var item = frm.extractDnaItems[i].item;
3449 28 Jul 15 olle 400         jsonItems[numSelected] = item;
3449 28 Jul 15 olle 401         names[numSelected] = item.name;
3449 28 Jul 15 olle 402 //alert("select_dna_for_start_plate.js::validateStep2(): numSelected = " + numSelected + " jsonItem = " + JSON.stringify(jsonItems[numSelected]));
3449 28 Jul 15 olle 403         numSelected++;
3449 28 Jul 15 olle 404       }
3449 28 Jul 15 olle 405     }
3449 28 Jul 15 olle 406 //alert("select_dna_for_start_plate.js::validateStep2(): numSelected = " + numSelected);
3449 28 Jul 15 olle 407   }
3449 28 Jul 15 olle 408   
3449 28 Jul 15 olle 409   selectdna.initializeStep3 = function(event)
3573 05 Nov 15 olle 410   {
3573 05 Nov 15 olle 411     var frm = document.forms['meludi'];
3573 05 Nov 15 olle 412     var startItemList = null;
3573 05 Nov 15 olle 413     var jsonStartItemListIds = [];
3573 05 Nov 15 olle 414     var numSelected = 0;
3573 05 Nov 15 olle 415     for (var i = 0; i < frm.startList.length; i++)
3573 05 Nov 15 olle 416     {
3573 05 Nov 15 olle 417       if (frm.startList[i].selected)
3573 05 Nov 15 olle 418       {
3573 05 Nov 15 olle 419         var jsonStartList = {};
3573 05 Nov 15 olle 420         jsonStartList.id = frm.startList[i].value;
3573 05 Nov 15 olle 421         jsonStartItemListIds[numSelected] = jsonStartList;
3573 05 Nov 15 olle 422         numSelected++;
3573 05 Nov 15 olle 423       }
3573 05 Nov 15 olle 424     }
3573 05 Nov 15 olle 425     if (numSelected == 0)
3573 05 Nov 15 olle 426     {
3573 05 Nov 15 olle 427       event.preventDefault();
3573 05 Nov 15 olle 428     }
3631 27 Nov 15 olle 429 //alert("select_dna_for_start_plate.js::initializeStep3(): numSelected = " + numSelected + " names.length = " + names.length + " names = " + JSON.stringify(names));
3573 05 Nov 15 olle 430
3573 05 Nov 15 olle 431     frm.startList.disabled = true;
3573 05 Nov 15 olle 432
3573 05 Nov 15 olle 433     Wizard.setCurrentStep(3);
3573 05 Nov 15 olle 434     Doc.show('step-3');
3573 05 Nov 15 olle 435     Doc.show('gocancel');
3573 05 Nov 15 olle 436     Doc.show('gonext');
3631 27 Nov 15 olle 437     Doc.addClass('gonext', 'disabled');
3631 27 Nov 15 olle 438     // Disable manual select buttons until kit tables have been loaded
3631 27 Nov 15 olle 439     Doc.addClass('btnManualSelectExtract', 'disabled');
3631 27 Nov 15 olle 440     Doc.addClass('btnManualSelectControl', 'disabled');
3631 27 Nov 15 olle 441     Doc.addClass('btnManualSelectReset', 'disabled');
3631 27 Nov 15 olle 442     // Disable kit tables until they have been loaded
3631 27 Nov 15 olle 443     Doc.hide('kitplatetablecontent');
3631 27 Nov 15 olle 444     // Hide lib prep kit menu, that is only used internally
3631 27 Nov 15 olle 445     Doc.hide('libPrepKit');
3573 05 Nov 15 olle 446
3631 27 Nov 15 olle 447     // Original names will only be loaded the first time this function is called
3631 27 Nov 15 olle 448     if (!originalNamesHasBeenLoaded)
3631 27 Nov 15 olle 449     {
3631 27 Nov 15 olle 450       // Reset JSONArray for original names
3631 27 Nov 15 olle 451       originalNames = [];
3631 27 Nov 15 olle 452
3631 27 Nov 15 olle 453       for (var i = 0; i < names.length; i++)
3631 27 Nov 15 olle 454       {
3631 27 Nov 15 olle 455         var name = names[i];
3631 27 Nov 15 olle 456         originalNames[originalNames.length] = name;
3631 27 Nov 15 olle 457       }
3631 27 Nov 15 olle 458       originalNamesHasBeenLoaded = true;
3631 27 Nov 15 olle 459     }
3631 27 Nov 15 olle 460
3573 05 Nov 15 olle 461     var numItems = names.length;
3573 05 Nov 15 olle 462     // Check what library preparation kits are available
3573 05 Nov 15 olle 463     var url = '../LibPrep.servlet?ID='+App.getSessionId();
3573 05 Nov 15 olle 464     url += '&cmd=GetLibPrepKitsAsPlates';
3573 05 Nov 15 olle 465     url += '&numItems=' + encodeURIComponent(numItems);
3573 05 Nov 15 olle 466     
3631 27 Nov 15 olle 467     Wizard.showLoadingAnimation('Loading information about kits...');
3573 05 Nov 15 olle 468     Wizard.asyncJsonRequest(url, selectdna.kitPlatesInfoLoaded);
3573 05 Nov 15 olle 469   }
3573 05 Nov 15 olle 470
3573 05 Nov 15 olle 471   selectdna.kitPlatesInfoLoaded = function(response)
3573 05 Nov 15 olle 472   {
3573 05 Nov 15 olle 473     var frm = document.forms['meludi'];  
3573 05 Nov 15 olle 474     var platesInfo = response.plates;
3573 05 Nov 15 olle 475     if (platesInfo)
3573 05 Nov 15 olle 476     {
3573 05 Nov 15 olle 477       // Find header data
3573 05 Nov 15 olle 478       var numItems = names.length;
3610 20 Nov 15 olle 479       var numUsedActiveKits = 0;
3610 20 Nov 15 olle 480       var numUnusedActiveKits = 0;
3610 20 Nov 15 olle 481       var usedActiveKitsJsonArr = [];
3610 20 Nov 15 olle 482       var unusedActiveKitsJsonArr = [];
3610 20 Nov 15 olle 483       var activeKitsJsonArr = [];
3573 05 Nov 15 olle 484       for (var i = 0; i < platesInfo.length; i++)
3573 05 Nov 15 olle 485       {
3573 05 Nov 15 olle 486         var plateInfo = platesInfo[i];
3573 05 Nov 15 olle 487         var bioplate = plateInfo;
3573 05 Nov 15 olle 488         var expirationDate = bioplate.expirationDate;
3573 05 Nov 15 olle 489         var numTimesUsed = bioplate.timesUsed;
3573 05 Nov 15 olle 490         var unusedWellsJsonArr = bioplate.unusedWells;
3573 05 Nov 15 olle 491         var effUnusedWellsJsonArr = bioplate.effUnusedWells;
3573 05 Nov 15 olle 492         var reservedWellsJsonArr = bioplate.reservedWells;
3573 05 Nov 15 olle 493         var numUnusedWells = unusedWellsJsonArr.length;
3573 05 Nov 15 olle 494         var jsonKit = {};
3621 25 Nov 15 olle 495         jsonKit['id'] = bioplate.kitId;
3573 05 Nov 15 olle 496         jsonKit['name'] = bioplate.kitName;
3573 05 Nov 15 olle 497         jsonKit['expirationDate'] = expirationDate;
3573 05 Nov 15 olle 498         jsonKit['numTimesUsed'] = numTimesUsed;
3573 05 Nov 15 olle 499         jsonKit['unusedWells'] = unusedWellsJsonArr;
3573 05 Nov 15 olle 500         jsonKit['effUnusedWells'] = effUnusedWellsJsonArr;
3573 05 Nov 15 olle 501         jsonKit['reservedWells'] = reservedWellsJsonArr;
3573 05 Nov 15 olle 502         jsonKit['numUnusedWells'] = numUnusedWells;
3573 05 Nov 15 olle 503         if (numUnusedWells < 48)
3573 05 Nov 15 olle 504         {
3610 20 Nov 15 olle 505           numUsedActiveKits++;
3610 20 Nov 15 olle 506           usedActiveKitsJsonArr[usedActiveKitsJsonArr.length] = jsonKit;
3573 05 Nov 15 olle 507         }
3573 05 Nov 15 olle 508         else
3573 05 Nov 15 olle 509         {
3610 20 Nov 15 olle 510           numUnusedActiveKits++;
3610 20 Nov 15 olle 511           unusedActiveKitsJsonArr[unusedActiveKitsJsonArr.length] = jsonKit;
3573 05 Nov 15 olle 512         }
3573 05 Nov 15 olle 513       }
3573 05 Nov 15 olle 514       // List used kits first
3610 20 Nov 15 olle 515       for (var i=0; i < usedActiveKitsJsonArr.length; i++)
3573 05 Nov 15 olle 516       {
3610 20 Nov 15 olle 517         activeKitsJsonArr[activeKitsJsonArr.length] = usedActiveKitsJsonArr[i];
3573 05 Nov 15 olle 518       }
3573 05 Nov 15 olle 519       // List unused kits after
3610 20 Nov 15 olle 520       for (var i=0; i < unusedActiveKitsJsonArr.length; i++)
3573 05 Nov 15 olle 521       {
3610 20 Nov 15 olle 522         activeKitsJsonArr[activeKitsJsonArr.length] = unusedActiveKitsJsonArr[i];
3573 05 Nov 15 olle 523       }
3573 05 Nov 15 olle 524
3573 05 Nov 15 olle 525       // Form header
3573 05 Nov 15 olle 526       var html = '';
3573 05 Nov 15 olle 527       html += '<b>Number of DNA items: ' + numItems + '</b><br>';
3582 06 Nov 15 olle 528 /*
3610 20 Nov 15 olle 529       html += '<b>Unused and active kits (' + numUnusedActiveKits + ')</b><br>';
3610 20 Nov 15 olle 530       html += '<b>Used and active kits (' + numUsedActiveKits + '):</b><br>';
3582 06 Nov 15 olle 531 */
3582 06 Nov 15 olle 532       html += '<br>';
3573 05 Nov 15 olle 533       html += 'Gray wells: Used<br>';
3573 05 Nov 15 olle 534       html += 'Dark green wells: Unused but ignored due to placement rules<br>';
3573 05 Nov 15 olle 535       html += 'Light green wells: Unused<br>';
3573 05 Nov 15 olle 536       html += 'Yellow wells: Unused and reserved for selected FPA aliquots<br>';
3573 05 Nov 15 olle 537       html += '<br>';
3573 05 Nov 15 olle 538
3610 20 Nov 15 olle 539       // Display data for used and active kits
3582 06 Nov 15 olle 540       var defaultKitSelected = false;
3582 06 Nov 15 olle 541       var checkedStr = "";
3582 06 Nov 15 olle 542       kitNum = 0;
3610 20 Nov 15 olle 543       // Used and active kits
3610 20 Nov 15 olle 544       html += '<td class="prompt"><b>Used and active kits (' + numUsedActiveKits + '):</b></td>';
3582 06 Nov 15 olle 545       html += '<br>';
3582 06 Nov 15 olle 546       html += '<br>';
3573 05 Nov 15 olle 547       for (var i = 0; i < platesInfo.length; i++)
3573 05 Nov 15 olle 548       {
3573 05 Nov 15 olle 549         var plateInfo = platesInfo[i];
3573 05 Nov 15 olle 550         var bioplate = plateInfo;
3573 05 Nov 15 olle 551         var unusedWellsJsonArr = bioplate.unusedWells;
3573 05 Nov 15 olle 552         var numUnusedWells = unusedWellsJsonArr.length;
3573 05 Nov 15 olle 553         if (numUnusedWells < 48)
3573 05 Nov 15 olle 554         {
3573 05 Nov 15 olle 555           // Display half plate chart of unused wells for FPA aliquots
3582 06 Nov 15 olle 556           var kitName = bioplate.kitName;
3582 06 Nov 15 olle 557           var expirationDate = bioplate.expirationDate;
3582 06 Nov 15 olle 558           var timesUsed = bioplate.timesUsed;
3582 06 Nov 15 olle 559           var checkedStr = "";
3582 06 Nov 15 olle 560           if (!defaultKitSelected)
3582 06 Nov 15 olle 561           {
3582 06 Nov 15 olle 562             selectedKitName = kitName;
3582 06 Nov 15 olle 563             defaultKitSelected = true;
3582 06 Nov 15 olle 564             checkedStr = " checked";
3582 06 Nov 15 olle 565           }
3582 06 Nov 15 olle 566           html += '<td style="width: 3em;"><input type="radio" name="uselibprepkit.'+kitNum+'" id="uselibprepkit.'+kitNum+'" value="'+kitName+'"'+checkedStr+'><b>Kit: ' + kitName + '</b> [Exp. ' + Strings.encodeTags(expirationDate) + '] #Times used: ' + timesUsed + '</td><br>';
3573 05 Nov 15 olle 567           html += selectdna.buildKitInfoPlate(bioplate);
3573 05 Nov 15 olle 568           html += '<br>';
3582 06 Nov 15 olle 569           kitNum++;
3573 05 Nov 15 olle 570         }
3573 05 Nov 15 olle 571       }
3582 06 Nov 15 olle 572       // Unused kits
3610 20 Nov 15 olle 573       html += '<td class="prompt"><b>Unused kits (' + unusedActiveKitsJsonArr.length + '):</b></td>';
3582 06 Nov 15 olle 574       html += '<br>';
3610 20 Nov 15 olle 575       for (var i=0; i < unusedActiveKitsJsonArr.length; i++)
3582 06 Nov 15 olle 576       {
3610 20 Nov 15 olle 577         var jsonKit = unusedActiveKitsJsonArr[i];
3582 06 Nov 15 olle 578         var kitName = jsonKit['name'];
3582 06 Nov 15 olle 579         var expirationDate = jsonKit['expirationDate'];
3582 06 Nov 15 olle 580         var checkedStr = "";
3582 06 Nov 15 olle 581         if (!defaultKitSelected)
3582 06 Nov 15 olle 582         {
3582 06 Nov 15 olle 583           selectedKitName = kitName;
3582 06 Nov 15 olle 584           defaultKitSelected = true;
3582 06 Nov 15 olle 585           checkedStr = " checked";
3582 06 Nov 15 olle 586         }
3582 06 Nov 15 olle 587         html += '<br>';
3582 06 Nov 15 olle 588         html += '<td style="width: 3em;"><input type="radio" name="uselibprepkit.'+kitNum+'" id="uselibprepkit.'+kitNum+'" value="'+kitName+'"'+checkedStr+'><b>Kit: ' + kitName + '</b> [Exp. ' + Strings.encodeTags(expirationDate) + ']</td>';
3582 06 Nov 15 olle 589         kitNum++;
3582 06 Nov 15 olle 590       }
3582 06 Nov 15 olle 591       html += '<br>';
3610 20 Nov 15 olle 592       if (activeKitsJsonArr.length == 0)
3582 06 Nov 15 olle 593       {
3582 06 Nov 15 olle 594         Wizard.setFatalError('No library preparation kits available.');
3582 06 Nov 15 olle 595         return;
3582 06 Nov 15 olle 596       }
3573 05 Nov 15 olle 597       Doc.element('kitplatetablecontent').innerHTML = html;
3631 27 Nov 15 olle 598       Doc.show('kitplatetablecontent');
3573 05 Nov 15 olle 599
3582 06 Nov 15 olle 600       for (var i=0; i < kitNum; i++)
3582 06 Nov 15 olle 601       {
3582 06 Nov 15 olle 602         // Add event handler for radio buttons
3582 06 Nov 15 olle 603         Events.addEventHandler('uselibprepkit.'+i, 'change', selectdna.kitOnChange, { 'index': i });
3582 06 Nov 15 olle 604       }
3582 06 Nov 15 olle 605
3582 06 Nov 15 olle 606       // Library preparation kit selection menu (hidden, but used internally)
3573 05 Nov 15 olle 607       var libPrepKitList = frm.libPrepKit;
3610 20 Nov 15 olle 608       if (activeKitsJsonArr.length > 0)
3573 05 Nov 15 olle 609       {
3610 20 Nov 15 olle 610         for (var i=0; i < activeKitsJsonArr.length; i++)
3573 05 Nov 15 olle 611         {
3610 20 Nov 15 olle 612           var jsonKit = activeKitsJsonArr[i];
3573 05 Nov 15 olle 613           var kitName = jsonKit['name'];
3573 05 Nov 15 olle 614           var expirationDate = jsonKit['expirationDate'];
3573 05 Nov 15 olle 615           var numTimesUsed = jsonKit['numTimesUsed'];
3573 05 Nov 15 olle 616           var numUnusedWells = jsonKit['numUnusedWells'];
3573 05 Nov 15 olle 617           //
3573 05 Nov 15 olle 618           var name = Strings.encodeTags(kitName);
3573 05 Nov 15 olle 619           if (numUnusedWells != null && numTimesUsed != null)
3573 05 Nov 15 olle 620           {
3573 05 Nov 15 olle 621             name += ' -- (';
3573 05 Nov 15 olle 622             name += '#Unused wells: ' + numUnusedWells;
3573 05 Nov 15 olle 623             name += ' #Times used: ' + numTimesUsed;
3573 05 Nov 15 olle 624             name += ')';
3573 05 Nov 15 olle 625           }
3573 05 Nov 15 olle 626           if (expirationDate)
3573 05 Nov 15 olle 627           {
3573 05 Nov 15 olle 628             name += ' [Exp. ' + Strings.encodeTags(expirationDate) + ']';
3573 05 Nov 15 olle 629           }
3573 05 Nov 15 olle 630           var selected = (i == 0);
3573 05 Nov 15 olle 631           var option = new Option(name, kitName, selected, selected);
3573 05 Nov 15 olle 632           option.jsonKit = jsonKit;
3573 05 Nov 15 olle 633           libPrepKitList.options[libPrepKitList.length] = option;
3573 05 Nov 15 olle 634         }
3573 05 Nov 15 olle 635         libPrepKitList.options[0].selected = true;
3573 05 Nov 15 olle 636       }
3573 05 Nov 15 olle 637       else
3573 05 Nov 15 olle 638       {
3573 05 Nov 15 olle 639         Wizard.setFatalError('No library preparation kits available.');
3573 05 Nov 15 olle 640         return;
3573 05 Nov 15 olle 641       }
3573 05 Nov 15 olle 642     }
3631 27 Nov 15 olle 643     Doc.removeClass('gonext', 'disabled');
3631 27 Nov 15 olle 644     // Enable manual select buttons after kit tables have been loaded
3631 27 Nov 15 olle 645     Doc.removeClass('btnManualSelectExtract', 'disabled');
3631 27 Nov 15 olle 646     Doc.removeClass('btnManualSelectControl', 'disabled');
3631 27 Nov 15 olle 647     Doc.removeClass('btnManualSelectReset', 'disabled');
3573 05 Nov 15 olle 648   }
3573 05 Nov 15 olle 649
3582 06 Nov 15 olle 650   selectdna.kitOnChange = function(event)
3582 06 Nov 15 olle 651   {
3582 06 Nov 15 olle 652     var frm = document.forms['meludi'];
3582 06 Nov 15 olle 653     var target = event.currentTarget;
3582 06 Nov 15 olle 654
3582 06 Nov 15 olle 655     var index = Data.int(target, 'index');
3582 06 Nov 15 olle 656
3582 06 Nov 15 olle 657     extraMaterialIsValid = true;
3582 06 Nov 15 olle 658
3582 06 Nov 15 olle 659     selectedKitName = frm['uselibprepkit.'+index].value;
3582 06 Nov 15 olle 660
3582 06 Nov 15 olle 661     // Reset all other radio buttons
3582 06 Nov 15 olle 662     for (var i=0; i < kitNum; i++)
3582 06 Nov 15 olle 663     {
3582 06 Nov 15 olle 664       if (i != index)
3582 06 Nov 15 olle 665       {
3582 06 Nov 15 olle 666         Doc.element('uselibprepkit.'+i).checked = false;
3582 06 Nov 15 olle 667       }
3582 06 Nov 15 olle 668     }
3582 06 Nov 15 olle 669   }
3582 06 Nov 15 olle 670
3573 05 Nov 15 olle 671   selectdna.initializeStep4 = function(event)
3449 28 Jul 15 olle 672   {    
3619 23 Nov 15 olle 673     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 674     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3449 28 Jul 15 olle 675     TOTAL_VOLUME = isNeoPrep ? 45 : 10; // µl
3449 28 Jul 15 olle 676     MINIMAL_DNA_VOLUME = 1.0; // µl
3449 28 Jul 15 olle 677
3573 05 Nov 15 olle 678     Doc.show('step-4');
3449 28 Jul 15 olle 679     
3449 28 Jul 15 olle 680     var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 681     url += '&cmd=GetStratagene';
3449 28 Jul 15 olle 682     Wizard.asyncJsonRequest(url, selectdna.stratageneLoaded);
3449 28 Jul 15 olle 683
3619 23 Nov 15 olle 684     Meludi.loadProtocols('LIBRARY_PROTOCOL', 'libraryPreparationProtocol');
3619 23 Nov 15 olle 685     Doc.addClass('libraryPreparationProtocol', 'list-loading');
3619 23 Nov 15 olle 686     frm.libraryPreparationProtocol[0] = new Option('loading...', '');
3619 23 Nov 15 olle 687
3619 23 Nov 15 olle 688     // Get library preparation protocol
3619 23 Nov 15 olle 689     var url = '../Protocol.servlet?ID='+App.getSessionId();
3619 23 Nov 15 olle 690     url += '&cmd=GetProtocols&subtype=LIBRARY_PROTOCOL';
3619 23 Nov 15 olle 691     Wizard.asyncJsonRequest(url, selectdna.protocolsLoaded);
3619 23 Nov 15 olle 692
3449 28 Jul 15 olle 693     var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 694     url += '&cmd=GetNextAutoGeneratedPlateName';
3449 28 Jul 15 olle 695     url += '&bioPlateType=' + (isNeoPrep ? 'NEOPREP' : 'DNA');
4200 01 Nov 16 olle 696     url += '&bioPlatePrefix=' + startPlatePrefix;
3449 28 Jul 15 olle 697     Wizard.showLoadingAnimation('Loading next '+(isNeoPrep ? 'NeoPrep' : 'DNA') + ' plate');
3449 28 Jul 15 olle 698     Wizard.asyncJsonRequest(url, selectdna.nextPlateNameLoaded);
3449 28 Jul 15 olle 699     
3449 28 Jul 15 olle 700     var url = '../LibPrep.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 701     url += '&cmd=GetAllBarcodeInfo';
3449 28 Jul 15 olle 702     Wizard.asyncJsonRequest(url, selectdna.barcodesLoaded);
3449 28 Jul 15 olle 703   }
3619 23 Nov 15 olle 704   
3619 23 Nov 15 olle 705   selectdna.protocolsLoaded = function(response)
3619 23 Nov 15 olle 706   {
3619 23 Nov 15 olle 707     var frm = document.forms['meludi'];
3619 23 Nov 15 olle 708     var protocols = response.protocols;
3449 28 Jul 15 olle 709
3619 23 Nov 15 olle 710     Doc.removeClass('libraryPreparationProtocol', 'list-loading');
3619 23 Nov 15 olle 711     frm.libraryPreparationProtocol.length = 0;
3619 23 Nov 15 olle 712     for (var i = 0; i < protocols.length; i++)
3619 23 Nov 15 olle 713     {
3619 23 Nov 15 olle 714       var name = protocols[i].name;
3619 23 Nov 15 olle 715       var id = protocols[i].id;
3619 23 Nov 15 olle 716       protocolMap[id] = name;
3619 23 Nov 15 olle 717       frm.libraryPreparationProtocol[frm.libraryPreparationProtocol.length] = new Option(name, id, false, true);
3619 23 Nov 15 olle 718     }    
3619 23 Nov 15 olle 719     frm.libraryPreparationProtocol[frm.libraryPreparationProtocol.length] = new Option('- none -', '');
3619 23 Nov 15 olle 720   }
3619 23 Nov 15 olle 721
3449 28 Jul 15 olle 722   selectdna.barcodesLoaded = function(response)
3449 28 Jul 15 olle 723   {
3449 28 Jul 15 olle 724     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 725     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3449 28 Jul 15 olle 726
3449 28 Jul 15 olle 727     var barcodes = response.barcodes;
3449 28 Jul 15 olle 728     var selectBarcodeHtml = '';
3449 28 Jul 15 olle 729     for (var i = 0; i < barcodes.length; i++)
3449 28 Jul 15 olle 730     {
3449 28 Jul 15 olle 731       if (i % 8 == 0 && i > 0)
3449 28 Jul 15 olle 732       {
3449 28 Jul 15 olle 733         selectBarcodeHtml += '<div class="menuseparator"></div>';
3449 28 Jul 15 olle 734       }
3449 28 Jul 15 olle 735       var barcode = barcodes[i];
3449 28 Jul 15 olle 736       barcodesByName[barcode.name] = barcode;
3449 28 Jul 15 olle 737       selectBarcodeHtml += '<div class="menuitem interactable enabled" id="bc-'+barcode.id+'" data-barcode-name="'+Strings.encodeTags(barcode.name)+'">';
3449 28 Jul 15 olle 738       selectBarcodeHtml += Strings.encodeTags(barcode.name)+'</div>';
3449 28 Jul 15 olle 739     }
3449 28 Jul 15 olle 740     Doc.element('select-barcode-all').innerHTML = selectBarcodeHtml;
3461 30 Jul 15 olle 741
3461 30 Jul 15 olle 742 /*    
3449 28 Jul 15 olle 743     selectdna.quantityOnChange();
3449 28 Jul 15 olle 744     selectdna.warningLevelOnChange();    
3449 28 Jul 15 olle 745     
3449 28 Jul 15 olle 746     // Init plate, pool schema and barcode variants
3449 28 Jul 15 olle 747     graphics = new jsGraphics(Doc.element('canvas'));
3449 28 Jul 15 olle 748     pen = new jsPen(new jsColor('#2288AA'), 2);
3449 28 Jul 15 olle 749     var columns = isNeoPrep ? 2 : 12;
3449 28 Jul 15 olle 750     var rows = 8;
3449 28 Jul 15 olle 751     var schema = PoolSchema.initList(frm.pool_schema, null, isNeoPrep ? 'neoprep' : 'manual');
3449 28 Jul 15 olle 752     Plate.init(rows, columns, schema, WellPainter);
3449 28 Jul 15 olle 753     Events.sendChangeEvent(frm.pool_schema);
3449 28 Jul 15 olle 754     // Set default for showing info for plate well
3449 28 Jul 15 olle 755     selectdna.setDefaultInfo('location');
3461 30 Jul 15 olle 756     //selectdna.setDefaultInfo('quantity');
3449 28 Jul 15 olle 757     selectdna.setDefaultInfo('volumes');
3449 28 Jul 15 olle 758     selectdna.setDefaultInfo('quality-score');
3449 28 Jul 15 olle 759     selectdna.setDefaultInfo('qubitconc');
3461 30 Jul 15 olle 760     //selectdna.setDefaultInfo('qiacube-date');
3449 28 Jul 15 olle 761
3449 28 Jul 15 olle 762     // Pre-fill plate wells with selected DNA
3449 28 Jul 15 olle 763     if (names.length > 0)
3449 28 Jul 15 olle 764     {
3449 28 Jul 15 olle 765       Dna.loadInfoByNames(names);
3449 28 Jul 15 olle 766
3449 28 Jul 15 olle 767       var wellsArray = [];      
3449 28 Jul 15 olle 768       for (var i = 0; i < names.length; i++)
3449 28 Jul 15 olle 769       {
3449 28 Jul 15 olle 770         var row = i % 8;
3449 28 Jul 15 olle 771         var column = Math.floor(i/8)
3449 28 Jul 15 olle 772         var well = Plate.getWell(row, column);
3449 28 Jul 15 olle 773         wellsArray[i] = well;
3449 28 Jul 15 olle 774         var name = names[i];
3449 28 Jul 15 olle 775         // Create a new DNA object
3449 28 Jul 15 olle 776         var dna = Dna.createByName(name);
3449 28 Jul 15 olle 777         dna.name = name + '.fpa';
3449 28 Jul 15 olle 778         Dna.unflag(dna);
3449 28 Jul 15 olle 779         well.setExtract(dna);
3449 28 Jul 15 olle 780         well.selected = false;
3449 28 Jul 15 olle 781         // Place FPB sample in corresponding well on right side of plate
3449 28 Jul 15 olle 782         well = Plate.getWell(row, column + 6);
3449 28 Jul 15 olle 783         wellsArray[i+names.length] = well;
3449 28 Jul 15 olle 784         // Create a new DNA object
3449 28 Jul 15 olle 785         dna = Dna.createByName(name);
3449 28 Jul 15 olle 786         dna.name = name + '.fpb';
3449 28 Jul 15 olle 787         Dna.unflag(dna);
3449 28 Jul 15 olle 788         well.setExtract(dna);
3449 28 Jul 15 olle 789         well.selected = false;
3449 28 Jul 15 olle 790       }      
3449 28 Jul 15 olle 791       Plate.checkReplicates();
3449 28 Jul 15 olle 792       Plate.paint(wellsArray);
3449 28 Jul 15 olle 793       selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 794       names = [];
3449 28 Jul 15 olle 795     }
3449 28 Jul 15 olle 796     //
3449 28 Jul 15 olle 797     Doc.show('step-3');
3449 28 Jul 15 olle 798     Doc.show('gocancel');
3449 28 Jul 15 olle 799     Doc.show('goregister');
3590 11 Nov 15 olle 800     Doc.show('gocreate');
3449 28 Jul 15 olle 801     Wizard.setNoConfirmOnFirstStep(false);
3449 28 Jul 15 olle 802     Wizard.keepSessionAlive();
3461 30 Jul 15 olle 803 */
3449 28 Jul 15 olle 804   }
3449 28 Jul 15 olle 805   
3449 28 Jul 15 olle 806   selectdna.stratageneLoaded = function(response)
3449 28 Jul 15 olle 807   {
3449 28 Jul 15 olle 808     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 809     var stratagene = response.stratagene;
3449 28 Jul 15 olle 810
3449 28 Jul 15 olle 811     for (var i = 0; i < stratagene.length; i++)
3449 28 Jul 15 olle 812     {
3449 28 Jul 15 olle 813       var s = stratagene[i];
3449 28 Jul 15 olle 814       var name = s.name;
3449 28 Jul 15 olle 815       if (s.bioWell)
3449 28 Jul 15 olle 816       {
3449 28 Jul 15 olle 817         name += ' -- ' + s.bioWell.bioPlate.name + ' ('+s.bioWell.location + ')';
3449 28 Jul 15 olle 818       }
3449 28 Jul 15 olle 819       frm.stratagene[frm.stratagene.length] = new Option(name, s.name);
3449 28 Jul 15 olle 820     }
3449 28 Jul 15 olle 821   }
3449 28 Jul 15 olle 822
3449 28 Jul 15 olle 823   selectdna.nextPlateNameLoaded = function(response)
3449 28 Jul 15 olle 824   {
3449 28 Jul 15 olle 825     var frm = document.forms['meludi'];
3461 30 Jul 15 olle 826     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3449 28 Jul 15 olle 827     Plate.name = response.name;
3449 28 Jul 15 olle 828 /*
3449 28 Jul 15 olle 829     Doc.element('plateName').innerHTML = Strings.encodeTags(Plate.name);
3449 28 Jul 15 olle 830 */
3449 28 Jul 15 olle 831     frm.plateName.value = Strings.encodeTags(Plate.name);
3449 28 Jul 15 olle 832     plateNameIsValid = true;
3449 28 Jul 15 olle 833     Wizard.setInputStatus('plateName', 'valid');
3461 30 Jul 15 olle 834
3573 05 Nov 15 olle 835     // Get library preparation kit to use
3573 05 Nov 15 olle 836     var kitName = 'None selected';
3573 05 Nov 15 olle 837     var jsonKit = {};
3573 05 Nov 15 olle 838     for (var i = 0; i < frm.libPrepKit.length; i++)
3461 30 Jul 15 olle 839     {
3582 06 Nov 15 olle 840 /*
3573 05 Nov 15 olle 841       if (frm.libPrepKit[i].selected)
3461 30 Jul 15 olle 842       {
3573 05 Nov 15 olle 843         kitName = frm.libPrepKit[i].value;
3573 05 Nov 15 olle 844         jsonKit = frm.libPrepKit[i].jsonKit;
3461 30 Jul 15 olle 845       }
3582 06 Nov 15 olle 846 */
3582 06 Nov 15 olle 847       if (frm.libPrepKit[i].value == selectedKitName)
3582 06 Nov 15 olle 848       {
3582 06 Nov 15 olle 849         kitName = frm.libPrepKit[i].value;
3582 06 Nov 15 olle 850         jsonKit = frm.libPrepKit[i].jsonKit;
3582 06 Nov 15 olle 851       }
3461 30 Jul 15 olle 852     }
3573 05 Nov 15 olle 853     var expirationDate = jsonKit['expirationDate'];
3573 05 Nov 15 olle 854     var numTimesUsed = jsonKit['numTimesUsed'];
3573 05 Nov 15 olle 855     var unusedWellsJsonArr = jsonKit['unusedWells'];
3573 05 Nov 15 olle 856     var reservedWellsJsonArr = jsonKit['reservedWells'];
3573 05 Nov 15 olle 857     var numUnusedWells = jsonKit['numUnusedWells'];
3573 05 Nov 15 olle 858 //alert("select_dna_for_start_plate.js::nextPlateNameLoaded(): numItems = " + numItems + " kitName = " + kitName + " unusedWellsJsonArr = " + JSON.stringify(unusedWellsJsonArr) + " reservedWellsJsonArr = " + JSON.stringify(reservedWellsJsonArr));
3573 05 Nov 15 olle 859 //alert("select_dna_for_start_plate.js::nextPlateNameLoaded(): numItems = " + numItems + " kitName = " + kitName + " reservedWellsJsonArr = " + JSON.stringify(reservedWellsJsonArr));
3621 25 Nov 15 olle 860 //alert("select_dna_for_start_plate.js::nextPlateNameLoaded(): kitName = " + kitName + " kitId = " + jsonKit['id']);
3573 05 Nov 15 olle 861     //
3685 12 Jan 16 olle 862     frm.tsLibPrepKit.value = kitName;
3685 12 Jan 16 olle 863     frm.tsLibPrepKit.disabled = true;
3621 25 Nov 15 olle 864     frm.hiddenLibPrepKitId.value = jsonKit['id'];
3573 05 Nov 15 olle 865
3461 30 Jul 15 olle 866     // Place pre-selected DNA on plate
3461 30 Jul 15 olle 867     selectdna.quantityOnChange();
3461 30 Jul 15 olle 868     selectdna.warningLevelOnChange();
3461 30 Jul 15 olle 869     
3461 30 Jul 15 olle 870     // Init plate, pool schema and barcode variants
3461 30 Jul 15 olle 871     graphics = new jsGraphics(Doc.element('canvas'));
3461 30 Jul 15 olle 872     pen = new jsPen(new jsColor('#2288AA'), 2);
3461 30 Jul 15 olle 873     var columns = isNeoPrep ? 2 : 12;
3461 30 Jul 15 olle 874     var rows = 8;
3596 12 Nov 15 olle 875     // Disable pool schema menu
3596 12 Nov 15 olle 876     frm.pool_schema.disabled = true;
3461 30 Jul 15 olle 877     var schema = PoolSchema.initList(frm.pool_schema, null, isNeoPrep ? 'neoprep' : 'manual');
3461 30 Jul 15 olle 878     Plate.init(rows, columns, schema, WellPainter);
3461 30 Jul 15 olle 879     Events.sendChangeEvent(frm.pool_schema);
3461 30 Jul 15 olle 880     // Set default for showing info for plate well
3461 30 Jul 15 olle 881     selectdna.setDefaultInfo('location');
3461 30 Jul 15 olle 882     //selectdna.setDefaultInfo('quantity');
3461 30 Jul 15 olle 883     selectdna.setDefaultInfo('volumes');
3461 30 Jul 15 olle 884     selectdna.setDefaultInfo('quality-score');
3461 30 Jul 15 olle 885     selectdna.setDefaultInfo('qubitconc');
3461 30 Jul 15 olle 886     //selectdna.setDefaultInfo('qiacube-date');
3461 30 Jul 15 olle 887
3461 30 Jul 15 olle 888     // Pre-fill plate wells with selected DNA
3461 30 Jul 15 olle 889     if (names.length > 0)
3461 30 Jul 15 olle 890     {
3461 30 Jul 15 olle 891       Dna.loadInfoByNames(names);
3461 30 Jul 15 olle 892
3667 15 Dec 15 olle 893       var wellsArray = [];
3667 15 Dec 15 olle 894       // FPA half
3461 30 Jul 15 olle 895       for (var i = 0; i < names.length; i++)
3461 30 Jul 15 olle 896       {
3573 05 Nov 15 olle 897         var wellStr = reservedWellsJsonArr[i];
3573 05 Nov 15 olle 898         var row = selectdna.wellStrToRow(wellStr);
3573 05 Nov 15 olle 899         var column = selectdna.wellStrToCol(wellStr);
3461 30 Jul 15 olle 900         var well = Plate.getWell(row, column);
3461 30 Jul 15 olle 901         var name = names[i];
3461 30 Jul 15 olle 902         // Create a new DNA object
3667 15 Dec 15 olle 903         var dna = Dna.createByParentName(name, name + '.fpa');
3461 30 Jul 15 olle 904         Dna.unflag(dna);
3461 30 Jul 15 olle 905         well.setExtract(dna);
3461 30 Jul 15 olle 906         well.selected = false;
3667 15 Dec 15 olle 907         wellsArray[i] = well;
3667 15 Dec 15 olle 908       }
3667 15 Dec 15 olle 909       // FPB half
3667 15 Dec 15 olle 910       for (var i = 0; i < names.length; i++)
3667 15 Dec 15 olle 911       {
3667 15 Dec 15 olle 912         var wellStr = reservedWellsJsonArr[i];
3667 15 Dec 15 olle 913         var row = selectdna.wellStrToRow(wellStr);
3667 15 Dec 15 olle 914         var column = selectdna.wellStrToCol(wellStr);
3461 30 Jul 15 olle 915         // Place FPB sample in corresponding well on right side of plate
3667 15 Dec 15 olle 916         var well = Plate.getWell(row, column + 6);
3667 15 Dec 15 olle 917         var name = names[i];
3461 30 Jul 15 olle 918         // Create a new DNA object
3667 15 Dec 15 olle 919         var dna = Dna.createByParentName(name, name + '.fpb');
3461 30 Jul 15 olle 920         Dna.unflag(dna);
3461 30 Jul 15 olle 921         well.setExtract(dna);
3461 30 Jul 15 olle 922         well.selected = false;
3667 15 Dec 15 olle 923         wellsArray[i+names.length] = well;
3667 15 Dec 15 olle 924       }
3461 30 Jul 15 olle 925       Plate.checkReplicates();
3461 30 Jul 15 olle 926       Plate.paint(wellsArray);
3461 30 Jul 15 olle 927       selectdna.updateNumFlaggedDna();
3461 30 Jul 15 olle 928       names = [];
3461 30 Jul 15 olle 929     }
3461 30 Jul 15 olle 930     //
3461 30 Jul 15 olle 931     Doc.show('step-3');
3461 30 Jul 15 olle 932     Doc.show('gocancel');
3461 30 Jul 15 olle 933     Doc.show('goregister');
3590 11 Nov 15 olle 934     Doc.show('gocreate');
3461 30 Jul 15 olle 935     Wizard.setNoConfirmOnFirstStep(false);
3461 30 Jul 15 olle 936     Wizard.keepSessionAlive();
3449 28 Jul 15 olle 937   }
3573 05 Nov 15 olle 938
3573 05 Nov 15 olle 939   selectdna.wellStrToRow = function(wellStr)
3573 05 Nov 15 olle 940   {
3573 05 Nov 15 olle 941     // Get first letter
3573 05 Nov 15 olle 942     var rowStr = wellStr.substring(0,1);
3573 05 Nov 15 olle 943     var row = jsonRowIndex[rowStr];
3573 05 Nov 15 olle 944     return row;
3573 05 Nov 15 olle 945   }
3573 05 Nov 15 olle 946
3573 05 Nov 15 olle 947   selectdna.wellStrToCol = function(wellStr)
3573 05 Nov 15 olle 948   {
3573 05 Nov 15 olle 949     // Get column string;
3573 05 Nov 15 olle 950     var colStr = wellStr.substring(1,3);
3573 05 Nov 15 olle 951     var col = jsonColIndex[colStr];
3573 05 Nov 15 olle 952     return col;
3573 05 Nov 15 olle 953   }
3573 05 Nov 15 olle 954
3590 11 Nov 15 olle 955   selectdna.wellRowColumnToWellStr = function(row, column)
3590 11 Nov 15 olle 956   {
3590 11 Nov 15 olle 957     // Get well string (row letter + column number, 1-based)
3590 11 Nov 15 olle 958     var wellStr = jsonRowLetter[row] + jsonColNumber[column];
3590 11 Nov 15 olle 959     return wellStr;
3590 11 Nov 15 olle 960   }
3590 11 Nov 15 olle 961
3449 28 Jul 15 olle 962   selectdna.plateNameOnChange = function(event)
3449 28 Jul 15 olle 963   {
3449 28 Jul 15 olle 964     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 965     plateNameIsValid = false;
3449 28 Jul 15 olle 966     
3449 28 Jul 15 olle 967     var name = frm.plateName.value;
3449 28 Jul 15 olle 968     if (!name || name == '')
3449 28 Jul 15 olle 969     {
3449 28 Jul 15 olle 970       Wizard.setInputStatus('plateName', 'invalid', 'Missing name');
3449 28 Jul 15 olle 971       return;
3449 28 Jul 15 olle 972     }
3449 28 Jul 15 olle 973     if (name.indexOf("LP") != 0)
3449 28 Jul 15 olle 974     {
3449 28 Jul 15 olle 975       Wizard.setInputStatus('plateName', 'invalid', 'Plate name must start with prefix "LP"');
3449 28 Jul 15 olle 976       return;
3449 28 Jul 15 olle 977     }
3449 28 Jul 15 olle 978     if (name.length != 7)
3449 28 Jul 15 olle 979     {
3449 28 Jul 15 olle 980       Wizard.setInputStatus('plateName', 'invalid', 'Plate name must consist of "LP" + 5 digits');
3449 28 Jul 15 olle 981       return;
3449 28 Jul 15 olle 982     }
3449 28 Jul 15 olle 983     
3449 28 Jul 15 olle 984     // Check if name exists
3449 28 Jul 15 olle 985     var url = '../Extraction.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 986     url += '&cmd=CheckIfStartPlateNameUsed';
3449 28 Jul 15 olle 987     url += '&startPlateName=' + encodeURIComponent(name);
3449 28 Jul 15 olle 988     
3449 28 Jul 15 olle 989     Wizard.showLoadingAnimation('Loading information about plate...');
3449 28 Jul 15 olle 990     Wizard.asyncJsonRequest(url, selectdna.plateInfoLoaded);
3449 28 Jul 15 olle 991   }
3449 28 Jul 15 olle 992
3449 28 Jul 15 olle 993   selectdna.plateInfoLoaded = function(response)
3449 28 Jul 15 olle 994   {
3449 28 Jul 15 olle 995     var frm = document.forms['meludi'];  
3449 28 Jul 15 olle 996     var plateInfo = response.startplate;
3449 28 Jul 15 olle 997     if (plateInfo)
3449 28 Jul 15 olle 998     {
3449 28 Jul 15 olle 999       var plateName = plateInfo.name;
3449 28 Jul 15 olle 1000       var plateId = plateInfo.id;
3449 28 Jul 15 olle 1001
3449 28 Jul 15 olle 1002       if (plateId)
3449 28 Jul 15 olle 1003       {
3449 28 Jul 15 olle 1004         plateNameIsValid = false;
3449 28 Jul 15 olle 1005         Wizard.setInputStatus('plateName', 'invalid', 'Plate already exists with name "' + plateName + '" (ID = ' + plateId + ')');
3449 28 Jul 15 olle 1006         return;
3449 28 Jul 15 olle 1007       }
3449 28 Jul 15 olle 1008     }
3449 28 Jul 15 olle 1009     plateNameIsValid = true;
3675 18 Dec 15 olle 1010     Plate.name = plateInfo.name;
3449 28 Jul 15 olle 1011     
3449 28 Jul 15 olle 1012     Wizard.setInputStatus('plateName', 'valid');
3449 28 Jul 15 olle 1013   }
3449 28 Jul 15 olle 1014
3449 28 Jul 15 olle 1015   selectdna.quantityOnChange = function(event)
3449 28 Jul 15 olle 1016   {
3449 28 Jul 15 olle 1017     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1018     quantitiesAreValid = false;
3617 23 Nov 15 olle 1019
3617 23 Nov 15 olle 1020 /*    
3449 28 Jul 15 olle 1021     var qRegular = parseFloat(frm.quantity_regular.value);
3449 28 Jul 15 olle 1022     if (!(qRegular > 0))
3449 28 Jul 15 olle 1023     {
3449 28 Jul 15 olle 1024       Wizard.setInputStatus('quantities', 'invalid', 'Amount must be ≥ 0.');
3449 28 Jul 15 olle 1025       return;
3449 28 Jul 15 olle 1026     }
3617 23 Nov 15 olle 1027 */
3596 12 Nov 15 olle 1028 /*
3449 28 Jul 15 olle 1029     var qQc = parseFloat(frm.quantity_qc.value);
3449 28 Jul 15 olle 1030     if (!(qQc > qRegular))
3449 28 Jul 15 olle 1031     {
3449 28 Jul 15 olle 1032       Wizard.setInputStatus('quantities', 'invalid', 'Amount QC must be &gt; ' + qRegular + '.');
3449 28 Jul 15 olle 1033       return;
3449 28 Jul 15 olle 1034     }
3596 12 Nov 15 olle 1035 */
3449 28 Jul 15 olle 1036     
3449 28 Jul 15 olle 1037     quantitiesAreValid = true;
3617 23 Nov 15 olle 1038 /*
3449 28 Jul 15 olle 1039     QUANTITY_REGULAR = qRegular;
3617 23 Nov 15 olle 1040 */
3596 12 Nov 15 olle 1041 /*
3449 28 Jul 15 olle 1042     QUANTITY_QC = qQc;
3596 12 Nov 15 olle 1043 */
3617 23 Nov 15 olle 1044
3617 23 Nov 15 olle 1045 /*    
3449 28 Jul 15 olle 1046     Wizard.setInputStatus('quantities', 'valid');
3617 23 Nov 15 olle 1047 */
3449 28 Jul 15 olle 1048     if (event) Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1049   }
3449 28 Jul 15 olle 1050
3617 23 Nov 15 olle 1051   selectdna.minVolDnaOnChange = function(event)
3617 23 Nov 15 olle 1052   {
3617 23 Nov 15 olle 1053     var frm = document.forms['meludi'];
3617 23 Nov 15 olle 1054     quantitiesAreValid = false;
3617 23 Nov 15 olle 1055     
3617 23 Nov 15 olle 1056     var minVolDna = parseFloat(frm.min_vol_dna.value);
3617 23 Nov 15 olle 1057     if (!(minVolDna > 0))
3617 23 Nov 15 olle 1058     {
3617 23 Nov 15 olle 1059       Wizard.setInputStatus('min_vol_dna', 'invalid', 'Amount must be ≥ 0.');
3617 23 Nov 15 olle 1060       return;
3617 23 Nov 15 olle 1061     }
3617 23 Nov 15 olle 1062     
3617 23 Nov 15 olle 1063     quantitiesAreValid = true;
3617 23 Nov 15 olle 1064     MINIMAL_DNA_VOLUME = minVolDna;
3617 23 Nov 15 olle 1065     
3617 23 Nov 15 olle 1066     Wizard.setInputStatus('min_vol_dna', 'valid');
3617 23 Nov 15 olle 1067     if (event) Plate.paint(Plate.getWells());
3617 23 Nov 15 olle 1068   }
3617 23 Nov 15 olle 1069
3449 28 Jul 15 olle 1070   selectdna.warningLevelOnChange = function(event)
3449 28 Jul 15 olle 1071   {
3449 28 Jul 15 olle 1072     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1073
3449 28 Jul 15 olle 1074 /*
3449 28 Jul 15 olle 1075     var wQuantity = parseFloat(frm.warning_quantity.value);
3449 28 Jul 15 olle 1076     if (!(wQuantity > 0))
3449 28 Jul 15 olle 1077     {
3449 28 Jul 15 olle 1078       Wizard.setInputStatus('warnings', 'invalid', 'Remaining quantity must be ≥ 0.');
3449 28 Jul 15 olle 1079       return;
3449 28 Jul 15 olle 1080     }
3449 28 Jul 15 olle 1081 */
3449 28 Jul 15 olle 1082     var wQualityScore = parseFloat(frm.warning_quality_score.value);
3449 28 Jul 15 olle 1083
3449 28 Jul 15 olle 1084 /*    
3449 28 Jul 15 olle 1085     LOW_QUANTITY_WARNING_LIMIT = wQuantity;
3449 28 Jul 15 olle 1086 */
3449 28 Jul 15 olle 1087     QUALITY_SCORE_WARNING_LIMIT = wQualityScore;
3449 28 Jul 15 olle 1088     
3449 28 Jul 15 olle 1089     Wizard.setInputStatus('warnings', 'valid');
3449 28 Jul 15 olle 1090     if (event) Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1091   }
3449 28 Jul 15 olle 1092   
3449 28 Jul 15 olle 1093   selectdna.poolSchemaOnChange = function()
3449 28 Jul 15 olle 1094   {
3449 28 Jul 15 olle 1095     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1096     var schema = PoolSchema.getById(frm.pool_schema.value);
3449 28 Jul 15 olle 1097     Plate.setPoolSchema(schema);
3449 28 Jul 15 olle 1098     
3449 28 Jul 15 olle 1099     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3449 28 Jul 15 olle 1100     if (isNeoPrep)
3449 28 Jul 15 olle 1101     {
3449 28 Jul 15 olle 1102       PoolSchema.buildPoolTableRow(schema, Plate.columns, true, '<td class="barcode-fill barcode-left"></td>', '<th></th><td class="barcode-fill barcode-right"></td>');
3449 28 Jul 15 olle 1103       PoolSchema.initVariantList(frm.barcode_variant, schema);
3449 28 Jul 15 olle 1104       Events.sendChangeEvent(frm.barcode_variant);
3449 28 Jul 15 olle 1105     }
3449 28 Jul 15 olle 1106     else
3449 28 Jul 15 olle 1107     {
3449 28 Jul 15 olle 1108       PoolSchema.buildPoolTableRow(schema, Plate.columns, true);
3449 28 Jul 15 olle 1109       Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1110     }
3449 28 Jul 15 olle 1111   }
3449 28 Jul 15 olle 1112   
3449 28 Jul 15 olle 1113   selectdna.barcodeVariantOnChange = function()
3449 28 Jul 15 olle 1114   {
3449 28 Jul 15 olle 1115     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1116     var schema = PoolSchema.getById(frm.pool_schema.value);
3449 28 Jul 15 olle 1117     var barcodeVariant = PoolSchema.getBarcodeVariantByName(schema, frm.barcode_variant.value);
3449 28 Jul 15 olle 1118     
3449 28 Jul 15 olle 1119     selectdna.assignSchemaDefinedBarcodeVariant(schema, barcodeVariant);
3449 28 Jul 15 olle 1120     WellPainter.barcodeVariant = barcodeVariant;
3449 28 Jul 15 olle 1121     Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1122   }
3449 28 Jul 15 olle 1123
3449 28 Jul 15 olle 1124   selectdna.assignSchemaDefinedBarcodeVariant = function(schema, barcodeVariant)
3449 28 Jul 15 olle 1125   {
3449 28 Jul 15 olle 1126     var wells = Plate.getWells();
3449 28 Jul 15 olle 1127     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1128     {
3449 28 Jul 15 olle 1129       var well = wells[i];
3449 28 Jul 15 olle 1130
3449 28 Jul 15 olle 1131       var indexSet = barcodeVariant ? barcodeVariant.indexSets[well.column] : null;
3449 28 Jul 15 olle 1132       var barcode = null;
3449 28 Jul 15 olle 1133       if (indexSet)
3449 28 Jul 15 olle 1134       {
3449 28 Jul 15 olle 1135         var barcodeName = indexSet.barcodes[well.row];
3449 28 Jul 15 olle 1136         barcode = barcodesByName[barcodeName];
3449 28 Jul 15 olle 1137       }
3449 28 Jul 15 olle 1138       well.barcode = barcode;
3449 28 Jul 15 olle 1139       well.defaultBarcode = barcode;
3449 28 Jul 15 olle 1140       well.duplicate = false;
3449 28 Jul 15 olle 1141     }
3449 28 Jul 15 olle 1142   }
3449 28 Jul 15 olle 1143
3449 28 Jul 15 olle 1144   var currentWell;
3449 28 Jul 15 olle 1145   var lastSelectedBarcode;
3449 28 Jul 15 olle 1146   selectdna.selectBarcode = function(event)
3449 28 Jul 15 olle 1147   {
3449 28 Jul 15 olle 1148     var row = Data.int(event.currentTarget, 'row');
3449 28 Jul 15 olle 1149     var column = Data.int(event.currentTarget, 'col');
3449 28 Jul 15 olle 1150
3449 28 Jul 15 olle 1151     // Locate the barcode selection div so that the current
3449 28 Jul 15 olle 1152     // barcode is positioned next to the current mouse position
3449 28 Jul 15 olle 1153     // Initially set it to the right of the mouse so that the
3449 28 Jul 15 olle 1154     // center is vertically aligned
3449 28 Jul 15 olle 1155     currentWell = Plate.getWell(row, column);
3449 28 Jul 15 olle 1156     var scroll = 0;
3449 28 Jul 15 olle 1157
3449 28 Jul 15 olle 1158     // Reset 'current' selection
3449 28 Jul 15 olle 1159     var menu = Doc.element('select-barcode');
3449 28 Jul 15 olle 1160     var selectAll = Doc.element('select-barcode-all');
3449 28 Jul 15 olle 1161     for (var i = 0; i <  selectAll.childNodes.length; i++)
3449 28 Jul 15 olle 1162     {
3449 28 Jul 15 olle 1163       Doc.removeClass(selectAll.childNodes[i], 'current');
3449 28 Jul 15 olle 1164     }
3449 28 Jul 15 olle 1165     menu.style.display = 'block';
3449 28 Jul 15 olle 1166
3449 28 Jul 15 olle 1167     var x = event.clientX+1;
3449 28 Jul 15 olle 1168     var halfHeight = Math.floor(selectAll.offsetHeight/2)
3449 28 Jul 15 olle 1169     var y = event.clientY-halfHeight;
3449 28 Jul 15 olle 1170     var scroll = 0;
3449 28 Jul 15 olle 1171     var barcodeDiv;
3449 28 Jul 15 olle 1172     
3449 28 Jul 15 olle 1173     var useBarcode = currentWell.barcode || lastSelectedBarcode;
3449 28 Jul 15 olle 1174     if (useBarcode)
3449 28 Jul 15 olle 1175     {
3449 28 Jul 15 olle 1176       var barcodeDiv = Doc.element('bc-'+useBarcode.id);
3449 28 Jul 15 olle 1177       if (!currentWell.barcode && barcodeDiv.nextSibling) barcodeDiv = barcodeDiv.nextSibling;
3449 28 Jul 15 olle 1178       // Try to scroll the current barcode so that it's baseline is at the center of the div
3449 28 Jul 15 olle 1179       scroll = barcodeDiv.offsetTop + barcodeDiv.offsetHeight - halfHeight;
3449 28 Jul 15 olle 1180       if (scroll < 0) 
3449 28 Jul 15 olle 1181       {
3449 28 Jul 15 olle 1182         // We get a negative scroll for the first few elements, shift the
3449 28 Jul 15 olle 1183         // entire selection div down instead
3449 28 Jul 15 olle 1184         y -= scroll;
3449 28 Jul 15 olle 1185         scroll = 0;
3449 28 Jul 15 olle 1186       }
3449 28 Jul 15 olle 1187       else if (scroll > selectAll.scrollHeight - selectAll.offsetHeight)
3449 28 Jul 15 olle 1188       {
3449 28 Jul 15 olle 1189         // We get a too large scroll value for the last few elements, shift
3449 28 Jul 15 olle 1190         // the entire selection div up instead
3449 28 Jul 15 olle 1191         y -= scroll - (selectAll.scrollHeight - selectAll.offsetHeight);
3449 28 Jul 15 olle 1192         scroll = selectAll.scrollHeight - selectAll.offsetHeight;
3449 28 Jul 15 olle 1193       }
3449 28 Jul 15 olle 1194       if (currentWell.barcode)
3449 28 Jul 15 olle 1195       {
3449 28 Jul 15 olle 1196         Doc.addClass(barcodeDiv, 'current');
3449 28 Jul 15 olle 1197       }
3449 28 Jul 15 olle 1198     }
3449 28 Jul 15 olle 1199     
3449 28 Jul 15 olle 1200     // Default barcode
3449 28 Jul 15 olle 1201     if (currentWell.defaultBarcode && currentWell.defaultBarcode != currentWell.barcode)
3449 28 Jul 15 olle 1202     {
3449 28 Jul 15 olle 1203       var selectDefault = Doc.element('select-barcode-default');
3449 28 Jul 15 olle 1204       Data.set(selectDefault, 'barcode-name', currentWell.defaultBarcode.name);
3449 28 Jul 15 olle 1205       selectDefault.innerHTML = 'Default: ' + Strings.encodeTags(currentWell.defaultBarcode.name);
3449 28 Jul 15 olle 1206       Doc.show('select-barcode-default');
3449 28 Jul 15 olle 1207       Doc.show('select-barcode-default-separator');
3449 28 Jul 15 olle 1208     }
3449 28 Jul 15 olle 1209     else
3449 28 Jul 15 olle 1210     {
3449 28 Jul 15 olle 1211       Doc.hide('select-barcode-default');
3449 28 Jul 15 olle 1212       Doc.hide('select-barcode-default-separator');
3449 28 Jul 15 olle 1213     }
3449 28 Jul 15 olle 1214     
3449 28 Jul 15 olle 1215     // Position the selection div
3449 28 Jul 15 olle 1216     selectAll.scrollTop = scroll;
3449 28 Jul 15 olle 1217     menu.style.left = (x)+'px';
3449 28 Jul 15 olle 1218     menu.style.top = (y)+'px';
3449 28 Jul 15 olle 1219     event.stopPropagation();
3449 28 Jul 15 olle 1220   }
3449 28 Jul 15 olle 1221
3449 28 Jul 15 olle 1222   selectdna.barcodeSelected = function(event)
3449 28 Jul 15 olle 1223   {
3449 28 Jul 15 olle 1224     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1225     var schema = PoolSchema.getById(frm.pool_schema.value);
3449 28 Jul 15 olle 1226     var target = event.target;
3449 28 Jul 15 olle 1227     if (currentWell)
3449 28 Jul 15 olle 1228     {
3449 28 Jul 15 olle 1229       lastSelectedBarcode = barcodesByName[Data.get(target, 'barcode-name')];
3449 28 Jul 15 olle 1230       currentWell.barcode = lastSelectedBarcode;
3449 28 Jul 15 olle 1231       var poolNum = schema.getPoolNumForColumn(currentWell.column);
3449 28 Jul 15 olle 1232       selectdna.checkDuplicateBarcode(poolNum);
3449 28 Jul 15 olle 1233       Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1234     }
3449 28 Jul 15 olle 1235     selectdna.hideBarcodeSelection();
3449 28 Jul 15 olle 1236   }
3449 28 Jul 15 olle 1237
3449 28 Jul 15 olle 1238   selectdna.checkDuplicateBarcode = function(poolNum)
3449 28 Jul 15 olle 1239   {
3449 28 Jul 15 olle 1240     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1241     var schema = PoolSchema.getById(frm.pool_schema.value);
3449 28 Jul 15 olle 1242
3449 28 Jul 15 olle 1243     var wells = schema.getWellsInPool(Plate, poolNum);
3449 28 Jul 15 olle 1244     var wellByBarcodeName = [];
3449 28 Jul 15 olle 1245     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1246     {
3449 28 Jul 15 olle 1247       var well = wells[i];
3449 28 Jul 15 olle 1248       if (well.barcode)
3449 28 Jul 15 olle 1249       {
3449 28 Jul 15 olle 1250         if (wellByBarcodeName[well.barcode.name])
3449 28 Jul 15 olle 1251         {
3449 28 Jul 15 olle 1252           well.duplicate = true;
3449 28 Jul 15 olle 1253           wellByBarcodeName[well.barcode.name].duplicate = true;
3449 28 Jul 15 olle 1254         }
3449 28 Jul 15 olle 1255         else
3449 28 Jul 15 olle 1256         {
3449 28 Jul 15 olle 1257           wellByBarcodeName[well.barcode.name] = well;
3449 28 Jul 15 olle 1258           well.duplicate = false;
3449 28 Jul 15 olle 1259         }
3449 28 Jul 15 olle 1260       }
3449 28 Jul 15 olle 1261     }
3449 28 Jul 15 olle 1262   }
3449 28 Jul 15 olle 1263
3449 28 Jul 15 olle 1264   
3449 28 Jul 15 olle 1265   selectdna.hideBarcodeSelection = function()
3449 28 Jul 15 olle 1266   {
3449 28 Jul 15 olle 1267     Doc.hide('select-barcode');
3449 28 Jul 15 olle 1268   }
3449 28 Jul 15 olle 1269
3449 28 Jul 15 olle 1270   
3449 28 Jul 15 olle 1271   /**
3449 28 Jul 15 olle 1272     Sets default display of info data for plate wells,
3449 28 Jul 15 olle 1273     based on check box values. Assumes the id of the
3449 28 Jul 15 olle 1274     check box in question as input.
3449 28 Jul 15 olle 1275   */
3449 28 Jul 15 olle 1276   selectdna.setDefaultInfo = function(chkbox)
3449 28 Jul 15 olle 1277   {
3449 28 Jul 15 olle 1278     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1279     var show = frm[chkbox].checked;
3449 28 Jul 15 olle 1280     Doc.addOrRemoveClass('plate', 'hide-'+chkbox, !show);
3449 28 Jul 15 olle 1281   }
3449 28 Jul 15 olle 1282
3449 28 Jul 15 olle 1283   selectdna.toggleInfo = function(event)
3449 28 Jul 15 olle 1284   {
3449 28 Jul 15 olle 1285     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1286     var show = event.currentTarget.checked;
3449 28 Jul 15 olle 1287     Doc.addOrRemoveClass('plate', 'hide-'+event.currentTarget.id, !show);
3667 15 Dec 15 olle 1288     if (event.currentTarget.id == 'qubitconc')
3667 15 Dec 15 olle 1289     {
3667 15 Dec 15 olle 1290       Doc.addOrRemoveClass('plate', 'hide-origqubitconc', !show);
3667 15 Dec 15 olle 1291       Doc.addOrRemoveClass('plate', 'hide-calcqubitconc', !show);
3667 15 Dec 15 olle 1292     }
3615 20 Nov 15 olle 1293     // Re-paint well info to show/hide warnings for target class
3615 20 Nov 15 olle 1294     Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1295   }
3449 28 Jul 15 olle 1296
3449 28 Jul 15 olle 1297   /**
3449 28 Jul 15 olle 1298     Open a popup dialog for selecting a data files.
3449 28 Jul 15 olle 1299   */
3449 28 Jul 15 olle 1300   selectdna.selectFile = function()
3449 28 Jul 15 olle 1301   {
3449 28 Jul 15 olle 1302     Dialogs.openPopup('select_file.jsp?ID='+App.getSessionId(), 'SelectFile', 600, 400);  
3449 28 Jul 15 olle 1303   }
3449 28 Jul 15 olle 1304
3449 28 Jul 15 olle 1305   /**
3449 28 Jul 15 olle 1306     Parse a tab-separated data file. The columns must be in the following order:
3449 28 Jul 15 olle 1307     0: DNA name
3449 28 Jul 15 olle 1308     1: Row letter (A-H)
3449 28 Jul 15 olle 1309     2: Column number (1-12)
3449 28 Jul 15 olle 1310     3: QC flag (can be empty)
3449 28 Jul 15 olle 1311   */
3449 28 Jul 15 olle 1312   selectdna.parseDnaFile = function(data)
3449 28 Jul 15 olle 1313   {
3449 28 Jul 15 olle 1314     var lines = data.split(/[\n\r]+/);
3449 28 Jul 15 olle 1315   
3449 28 Jul 15 olle 1316     // Load information about all DNA items in a batch (will improve performance)
3449 28 Jul 15 olle 1317     var names = [];
3449 28 Jul 15 olle 1318     for (var i = 0; i < lines.length; i++)
3449 28 Jul 15 olle 1319     {
3449 28 Jul 15 olle 1320       var line = lines[i];
3449 28 Jul 15 olle 1321       if (line)
3449 28 Jul 15 olle 1322       {
3449 28 Jul 15 olle 1323         var cols = lines[i].split(/\t/);
3449 28 Jul 15 olle 1324         if (cols.length < 3) throw 'On line '+(i+1)+': Too few columns (' + cols.length + ')';
3449 28 Jul 15 olle 1325         names[names.length] = cols[0];
3449 28 Jul 15 olle 1326       }
3449 28 Jul 15 olle 1327     }
3449 28 Jul 15 olle 1328     Dna.loadInfoByNames(names);
3449 28 Jul 15 olle 1329     
3449 28 Jul 15 olle 1330     // Place DNA on the plate
3449 28 Jul 15 olle 1331     var duplicates = [];
3449 28 Jul 15 olle 1332     for (var i = 0; i < lines.length; i++)
3449 28 Jul 15 olle 1333     {
3449 28 Jul 15 olle 1334       var line = lines[i];
3449 28 Jul 15 olle 1335       if (line)
3449 28 Jul 15 olle 1336       {
3449 28 Jul 15 olle 1337         var cols = lines[i].split(/\t/);
3449 28 Jul 15 olle 1338   
3459 30 Jul 15 olle 1339         //var dna = Dna.createByName(cols[0]);
3449 28 Jul 15 olle 1340         var row =  Meludi.alphaToWell(cols[1].toUpperCase());
3449 28 Jul 15 olle 1341         var col =  parseInt(cols[2], 10)-1;
3459 30 Jul 15 olle 1342
3460 30 Jul 15 olle 1343         if (col < 6)
3459 30 Jul 15 olle 1344         {        
3459 30 Jul 15 olle 1345           var well = Plate.getWell(row, col);
3459 30 Jul 15 olle 1346           if (!well) throw 'On line '+(i+1)+': Invalid plate coordinate ['+cols[1]+','+cols[2]+']';
3449 28 Jul 15 olle 1347   
3459 30 Jul 15 olle 1348           var name = cols[0];
3459 30 Jul 15 olle 1349           // Create a new DNA object
3459 30 Jul 15 olle 1350           var dna = Dna.createByName(name);
3459 30 Jul 15 olle 1351           dna.name = name + '.fpa';
3459 30 Jul 15 olle 1352           dna.qc = cols.length >= 4 && (cols[3] && cols[3] != '0');
3459 30 Jul 15 olle 1353           Dna.unflag(dna);
3449 28 Jul 15 olle 1354         
3459 30 Jul 15 olle 1355           // Check for duplicate DNA on same position (which is an error)
3459 30 Jul 15 olle 1356           var pos = 'c'+col+'r'+row;
3459 30 Jul 15 olle 1357           if (duplicates[pos])
3459 30 Jul 15 olle 1358           {
3459 30 Jul 15 olle 1359             well.addDuplicate(dna);
3459 30 Jul 15 olle 1360           }
3459 30 Jul 15 olle 1361           else
3459 30 Jul 15 olle 1362           {
3459 30 Jul 15 olle 1363             duplicates[pos] = dna.name;
3459 30 Jul 15 olle 1364             well.setExtract(dna);
3459 30 Jul 15 olle 1365           }
3459 30 Jul 15 olle 1366
3459 30 Jul 15 olle 1367           // Place FPB sample in corresponding well on right side of plate
3459 30 Jul 15 olle 1368           well = Plate.getWell(row, col + 6);
3459 30 Jul 15 olle 1369           // Create a new DNA object
3459 30 Jul 15 olle 1370           dna = Dna.createByName(name);
3459 30 Jul 15 olle 1371           dna.name = name + '.fpb';
3459 30 Jul 15 olle 1372           dna.qc = cols.length >= 4 && (cols[3] && cols[3] != '0');
3459 30 Jul 15 olle 1373           Dna.unflag(dna);
3449 28 Jul 15 olle 1374           well.setExtract(dna);
3449 28 Jul 15 olle 1375         }
3449 28 Jul 15 olle 1376       }
3449 28 Jul 15 olle 1377     }
3449 28 Jul 15 olle 1378     
3449 28 Jul 15 olle 1379     selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 1380     
3449 28 Jul 15 olle 1381     // Check for replicates on the whole plate and repaint it
3449 28 Jul 15 olle 1382     Plate.checkReplicates(null, true);
3449 28 Jul 15 olle 1383     Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1384   }
3449 28 Jul 15 olle 1385   
3449 28 Jul 15 olle 1386   /**
3449 28 Jul 15 olle 1387     Open a popup dialog for manual selection of DNA.
3449 28 Jul 15 olle 1388   */
3449 28 Jul 15 olle 1389   selectdna.manualSelect = function(event)
3449 28 Jul 15 olle 1390   {
3449 28 Jul 15 olle 1391     currentSelected = Plate.getSelected();
3449 28 Jul 15 olle 1392     if (currentSelected.length == 0)
3449 28 Jul 15 olle 1393     {
3449 28 Jul 15 olle 1394       Forms.showNotification(event.currentTarget, 'Please select one or more wells were DNA should be placed.');
3449 28 Jul 15 olle 1395       return;
3449 28 Jul 15 olle 1396     }
3449 28 Jul 15 olle 1397     
3449 28 Jul 15 olle 1398     if (subtypeDna == null) subtypeDna = Meludi.getSubtypeInfo('DNA');
3449 28 Jul 15 olle 1399 /*
3449 28 Jul 15 olle 1400     if (subtypeDnaNormalized == null) subtypeDnaNormalized = Meludi.getSubtypeInfo('DNA_NORMALIZED_ALIQUOT');
3449 28 Jul 15 olle 1401 */
3449 28 Jul 15 olle 1402   
3449 28 Jul 15 olle 1403     var url = '&resetTemporary=1';
3449 28 Jul 15 olle 1404 /*
3449 28 Jul 15 olle 1405     url += '&tmpfilter:INT:itemSubtype='+subtypeDna.id+'|'+subtypeDnaNormalized.id;
3449 28 Jul 15 olle 1406 */
3449 28 Jul 15 olle 1407     url += '&tmpfilter:INT:itemSubtype='+subtypeDna.id;
3449 28 Jul 15 olle 1408     url += '&tmpfilter:DATE:creationEvent.eventDate='+encodeURIComponent('<>');
3449 28 Jul 15 olle 1409     url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>=1');
3449 28 Jul 15 olle 1410     url += '&'+encodeURIComponent('tmpfilter:STRING:&childCreationEvents(event.bioMaterial.name)')+'='+encodeURIComponent('<>%.m');
3449 28 Jul 15 olle 1411
3449 28 Jul 15 olle 1412     Dialogs.selectItem('EXTRACT', 'plate', 1, url);
3449 28 Jul 15 olle 1413   }
3449 28 Jul 15 olle 1414
3449 28 Jul 15 olle 1415   /**
3449 28 Jul 15 olle 1416     Callback method for manual selection.
3449 28 Jul 15 olle 1417   */
3449 28 Jul 15 olle 1418   selectdna.manuallySelected = function(event)
3449 28 Jul 15 olle 1419   {
3449 28 Jul 15 olle 1420     names[names.length] = event.detail.name;
3449 28 Jul 15 olle 1421     
3449 28 Jul 15 olle 1422     if (event.detail.remaining == 0 && names.length > 0)
3449 28 Jul 15 olle 1423     {
3449 28 Jul 15 olle 1424       Dna.loadInfoByNames(names);
3449 28 Jul 15 olle 1425
3458 30 Jul 15 olle 1426       var wellsArray = [];
3458 30 Jul 15 olle 1427       var numItemsPlaced = names.length;
3458 30 Jul 15 olle 1428       if (currentSelected.length < names.length)
3449 28 Jul 15 olle 1429       {
3458 30 Jul 15 olle 1430         numItemsPlaced = currentSelected.length;
3458 30 Jul 15 olle 1431       }
3458 30 Jul 15 olle 1432       for (var i = 0; i < numItemsPlaced; i++)
3458 30 Jul 15 olle 1433       {
3449 28 Jul 15 olle 1434         var well = currentSelected[i];
3449 28 Jul 15 olle 1435         wellsArray[i] = well;
3449 28 Jul 15 olle 1436         var name = names[i];
3457 29 Jul 15 olle 1437 //alert("select_dna_for_start_plate.js::manuallySelected(): currentSelected.length = " + currentSelected.length + " names.legnth = " + names.length + " i = " + i + " name = \"" + name + "\" well = " + JSON.stringify(well));        
3449 28 Jul 15 olle 1438         // Create a new DNA object
3449 28 Jul 15 olle 1439         var dna = Dna.createByName(name);
3449 28 Jul 15 olle 1440         dna.name = name + '.fpa';
3449 28 Jul 15 olle 1441         Dna.unflag(dna);
3449 28 Jul 15 olle 1442         well.setExtract(dna);
3449 28 Jul 15 olle 1443         well.selected = false;
3449 28 Jul 15 olle 1444         // Place FPB sample in corresponding well on right side of plate
3457 29 Jul 15 olle 1445         var row = well.row;
3457 29 Jul 15 olle 1446         var column = well.column;
3449 28 Jul 15 olle 1447         well = Plate.getWell(row, column + 6);
3458 30 Jul 15 olle 1448         wellsArray[i+numItemsPlaced] = well;
3449 28 Jul 15 olle 1449         // Create a new DNA object
3449 28 Jul 15 olle 1450         dna = Dna.createByName(name);
3449 28 Jul 15 olle 1451         dna.name = name + '.fpb';
3449 28 Jul 15 olle 1452         Dna.unflag(dna);
3449 28 Jul 15 olle 1453         well.setExtract(dna);
3449 28 Jul 15 olle 1454         well.selected = false;
3449 28 Jul 15 olle 1455       }
3449 28 Jul 15 olle 1456       Plate.checkReplicates();
3449 28 Jul 15 olle 1457 /*
3449 28 Jul 15 olle 1458       Plate.paint(currentSelected);
3449 28 Jul 15 olle 1459 */
3449 28 Jul 15 olle 1460       Plate.paint(wellsArray);
3449 28 Jul 15 olle 1461       selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 1462       names = [];
3449 28 Jul 15 olle 1463     }
3449 28 Jul 15 olle 1464   }
3449 28 Jul 15 olle 1465
3449 28 Jul 15 olle 1466   
3449 28 Jul 15 olle 1467   /**
3449 28 Jul 15 olle 1468     Let the wizard automatically select among unprocessed DNA items.
3449 28 Jul 15 olle 1469   */  
3449 28 Jul 15 olle 1470   selectdna.autoSelect = function(event)
3449 28 Jul 15 olle 1471   {
3449 28 Jul 15 olle 1472     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1473     var wells = Plate.getWells();
3449 28 Jul 15 olle 1474     var selected = [];
3449 28 Jul 15 olle 1475     var ignore = [];
3449 28 Jul 15 olle 1476     var notEmpty = 0;
3449 28 Jul 15 olle 1477     
3449 28 Jul 15 olle 1478     // Count selected and non-empty wells and keep track of DNA that is already present
3449 28 Jul 15 olle 1479     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1480     {
3449 28 Jul 15 olle 1481       var well = wells[i];
3449 28 Jul 15 olle 1482       if (well.selected) 
3449 28 Jul 15 olle 1483       {
3449 28 Jul 15 olle 1484         selected[selected.length] = well;
3449 28 Jul 15 olle 1485         if (well.extract && !well.hasError()) notEmpty++;
3449 28 Jul 15 olle 1486       }
3449 28 Jul 15 olle 1487       if (well.extract && well.extract.id)
3449 28 Jul 15 olle 1488       {
3449 28 Jul 15 olle 1489         ignore[ignore.length] = well.extract.id;
3449 28 Jul 15 olle 1490       }
3449 28 Jul 15 olle 1491     }
3449 28 Jul 15 olle 1492     // Ignore DNA already flagged
3449 28 Jul 15 olle 1493     var flagged = Dna.getFlagged();
3449 28 Jul 15 olle 1494     for (var i = 0; i < flagged.length; i++)
3449 28 Jul 15 olle 1495     {
3449 28 Jul 15 olle 1496       var dna = flagged[i];
3449 28 Jul 15 olle 1497       if (dna.id) ignore[ignore.length] = dna.id;
3449 28 Jul 15 olle 1498     }
3449 28 Jul 15 olle 1499     
3449 28 Jul 15 olle 1500     if (selected.length == 0)
3449 28 Jul 15 olle 1501     {
3449 28 Jul 15 olle 1502       Forms.showNotification(event.currentTarget, 'Please select one or more wells were DNA should be placed.');
3449 28 Jul 15 olle 1503       return;
3449 28 Jul 15 olle 1504     }
3449 28 Jul 15 olle 1505       
3449 28 Jul 15 olle 1506     if (notEmpty > 0)
3449 28 Jul 15 olle 1507     {
3449 28 Jul 15 olle 1508       if (!confirm('Replace DNA in ' + notEmpty + ' wells?'))
3449 28 Jul 15 olle 1509       {
3449 28 Jul 15 olle 1510         return;
3449 28 Jul 15 olle 1511       }
3449 28 Jul 15 olle 1512     }
3449 28 Jul 15 olle 1513       
3449 28 Jul 15 olle 1514     var url = 'auto_select_dna.jsp?ID='+App.getSessionId();
3449 28 Jul 15 olle 1515     url += '&numToSelect='+selected.length;
3617 23 Nov 15 olle 1516 /*
3449 28 Jul 15 olle 1517     url += '&quantity='+encodeURIComponent(frm.quantity_regular.value);
3617 23 Nov 15 olle 1518 */
3449 28 Jul 15 olle 1519     url += '&ignore='+ignore.join(',');
3449 28 Jul 15 olle 1520     Dialogs.openPopup(url, 'AutoSelectDNA', 750, 500);
3449 28 Jul 15 olle 1521   }
3449 28 Jul 15 olle 1522
3449 28 Jul 15 olle 1523   /**
3449 28 Jul 15 olle 1524     Callback function for auto-select.
3449 28 Jul 15 olle 1525   */  
3449 28 Jul 15 olle 1526   selectdna.dnaSelected = function(response)
3449 28 Jul 15 olle 1527   {
3449 28 Jul 15 olle 1528     // Cache DNA information
3449 28 Jul 15 olle 1529     Dna.cacheInfo(response.dna);
3449 28 Jul 15 olle 1530     Dna.cacheInfo(response.flagged);
3449 28 Jul 15 olle 1531     
3449 28 Jul 15 olle 1532     selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 1533     var selected = Plate.getSelected();
3449 28 Jul 15 olle 1534
3449 28 Jul 15 olle 1535 /*
3449 28 Jul 15 olle 1536     // Get selected DNA names
3449 28 Jul 15 olle 1537     for (var i = 0; i < response.dna.length; i++)
3449 28 Jul 15 olle 1538     {
3449 28 Jul 15 olle 1539       if (i < selected.length)
3449 28 Jul 15 olle 1540       {
3449 28 Jul 15 olle 1541         names[i] = response.dna[i].name;
3449 28 Jul 15 olle 1542       }
3449 28 Jul 15 olle 1543     }
3449 28 Jul 15 olle 1544     if (names.length > 0)
3449 28 Jul 15 olle 1545     {
3449 28 Jul 15 olle 1546       Dna.loadInfoByNames(names);
3449 28 Jul 15 olle 1547
3449 28 Jul 15 olle 1548       for (var i = 0; i < names.length && i < selected.length; i++)
3449 28 Jul 15 olle 1549       {
3449 28 Jul 15 olle 1550         var well = selected[i];
3449 28 Jul 15 olle 1551         var name = names[i];
3449 28 Jul 15 olle 1552         
3449 28 Jul 15 olle 1553         // Create a new DNA object
3449 28 Jul 15 olle 1554         var dna = Dna.createByName(name);
3449 28 Jul 15 olle 1555         Dna.unflag(dna);
3449 28 Jul 15 olle 1556         well.setExtract(dna);
3449 28 Jul 15 olle 1557         well.selected = false;
3449 28 Jul 15 olle 1558       }
3449 28 Jul 15 olle 1559       
3449 28 Jul 15 olle 1560       Plate.checkReplicates();
3449 28 Jul 15 olle 1561       Plate.paint(selected);
3449 28 Jul 15 olle 1562       selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 1563       names = [];
3449 28 Jul 15 olle 1564     }
3449 28 Jul 15 olle 1565 */
3449 28 Jul 15 olle 1566
3449 28 Jul 15 olle 1567     var wellsArray = [];      
3449 28 Jul 15 olle 1568     for (var i = 0; i < response.dna.length; i++)
3449 28 Jul 15 olle 1569     {
3449 28 Jul 15 olle 1570       if (i < selected.length)
3449 28 Jul 15 olle 1571       {
3449 28 Jul 15 olle 1572         var well = selected[i];
3449 28 Jul 15 olle 1573         wellsArray[i] = well;
3449 28 Jul 15 olle 1574         // Create a new DNA object
3449 28 Jul 15 olle 1575         var name = response.dna[i].name;
3449 28 Jul 15 olle 1576         var dna = Dna.createByName(name);
3449 28 Jul 15 olle 1577         dna.name = name + '.fpa';
3449 28 Jul 15 olle 1578         //Dna.unflag(dna);
3449 28 Jul 15 olle 1579         well.setExtract(dna);
3449 28 Jul 15 olle 1580         well.selected = false;
3449 28 Jul 15 olle 1581         // Place FPB sample in corresponding well on right side of plate
3449 28 Jul 15 olle 1582         var row = well.row;
3449 28 Jul 15 olle 1583         var column = well.column;
3449 28 Jul 15 olle 1584         well = Plate.getWell(row, column + 6);
3449 28 Jul 15 olle 1585         wellsArray[i+selected.length] = well;
3449 28 Jul 15 olle 1586         // Create a new DNA object
3449 28 Jul 15 olle 1587         dna = Dna.createByName(name);
3449 28 Jul 15 olle 1588         dna.name = name + '.fpb';
3449 28 Jul 15 olle 1589         //Dna.unflag(dna);
3449 28 Jul 15 olle 1590         well.setExtract(dna);
3449 28 Jul 15 olle 1591         well.selected = false;
3449 28 Jul 15 olle 1592       }
3449 28 Jul 15 olle 1593     }
3449 28 Jul 15 olle 1594     // Check for replicates on the whole plate and repaint it
3449 28 Jul 15 olle 1595     Plate.checkReplicates(null, true);
3449 28 Jul 15 olle 1596     Plate.paint(Plate.getWells());
3449 28 Jul 15 olle 1597   }
3449 28 Jul 15 olle 1598   
3449 28 Jul 15 olle 1599   // Update the 'Flagged DNA' information
3449 28 Jul 15 olle 1600   selectdna.updateNumFlaggedDna = function()
3449 28 Jul 15 olle 1601   {
3449 28 Jul 15 olle 1602     var numFlagged = Dna.getFlagged().length;
3449 28 Jul 15 olle 1603     if (numFlagged > 0)
3449 28 Jul 15 olle 1604     {
3449 28 Jul 15 olle 1605       Doc.element('flaggedDna').innerHTML = numFlagged + ' flagged DNA items.';
3449 28 Jul 15 olle 1606       Doc.show('flaggedDna');
3449 28 Jul 15 olle 1607     }
3449 28 Jul 15 olle 1608     else
3449 28 Jul 15 olle 1609     {
3449 28 Jul 15 olle 1610       Doc.hide('flaggedDna');
3449 28 Jul 15 olle 1611     }
3449 28 Jul 15 olle 1612   }
3449 28 Jul 15 olle 1613
3449 28 Jul 15 olle 1614   /**
3449 28 Jul 15 olle 1615     Add 'Stratagene' to the selected wells.
3449 28 Jul 15 olle 1616   */
3449 28 Jul 15 olle 1617   selectdna.setToStratagene = function(event)
3449 28 Jul 15 olle 1618   {
3449 28 Jul 15 olle 1619     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 1620     selectdna.setToSpecial(event, frm.stratagene.value, true);
3449 28 Jul 15 olle 1621   }
3449 28 Jul 15 olle 1622
3449 28 Jul 15 olle 1623
3449 28 Jul 15 olle 1624   /**
3449 28 Jul 15 olle 1625     Add 'External DNA' to the selected wells.
3449 28 Jul 15 olle 1626   */
3449 28 Jul 15 olle 1627   selectdna.setToExternal = function(event)
3449 28 Jul 15 olle 1628   {
3449 28 Jul 15 olle 1629     selectdna.setToSpecial(event, EXTERNAL_DNA_NAME, false);  
3449 28 Jul 15 olle 1630   }
3449 28 Jul 15 olle 1631   
3449 28 Jul 15 olle 1632   /**
3449 28 Jul 15 olle 1633     Add special DNA to the selected wells.
3449 28 Jul 15 olle 1634   */
3449 28 Jul 15 olle 1635   selectdna.setToSpecial = function(event, specialName, qc)
3449 28 Jul 15 olle 1636   {
3449 28 Jul 15 olle 1637     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1638     
3449 28 Jul 15 olle 1639     if (wells.length == 0)
3449 28 Jul 15 olle 1640     {
3449 28 Jul 15 olle 1641       Forms.showNotification(event.currentTarget, 'No wells have been selected');
3449 28 Jul 15 olle 1642       return;
3449 28 Jul 15 olle 1643     }
3449 28 Jul 15 olle 1644     
3449 28 Jul 15 olle 1645     // Count non-empty wells
3449 28 Jul 15 olle 1646     var count = 0;
3449 28 Jul 15 olle 1647     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1648     {
3449 28 Jul 15 olle 1649       var well = wells[i];
3449 28 Jul 15 olle 1650       if (well.extract && !well.hasError()) count++;
3449 28 Jul 15 olle 1651     }
3449 28 Jul 15 olle 1652     
3449 28 Jul 15 olle 1653     if (count > 0)
3449 28 Jul 15 olle 1654     {
3449 28 Jul 15 olle 1655       if (!confirm('Replace DNA in ' + count + ' wells with '+specialName+'?'))
3449 28 Jul 15 olle 1656       {
3449 28 Jul 15 olle 1657         return;
3449 28 Jul 15 olle 1658       }
3449 28 Jul 15 olle 1659     }
3449 28 Jul 15 olle 1660     
3449 28 Jul 15 olle 1661     var info = Dna.infoByName(specialName);
3449 28 Jul 15 olle 1662     if (!info.id)
3449 28 Jul 15 olle 1663     {
3449 28 Jul 15 olle 1664       alert('Could not find any DNA with name=\''+specialName+'\'. Please check that it exists on the server.');
3449 28 Jul 15 olle 1665       return;
3449 28 Jul 15 olle 1666     }
3449 28 Jul 15 olle 1667     
3449 28 Jul 15 olle 1668     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1669     {
3449 28 Jul 15 olle 1670       var well = wells[i];
3449 28 Jul 15 olle 1671       var dna = Dna.createByInfo(info);
3449 28 Jul 15 olle 1672       dna.qc = qc;
3449 28 Jul 15 olle 1673       well.setExtract(dna);
3449 28 Jul 15 olle 1674       well.selected = false;
3449 28 Jul 15 olle 1675     }
3449 28 Jul 15 olle 1676     
3449 28 Jul 15 olle 1677     Plate.paint(wells);
3449 28 Jul 15 olle 1678     
3449 28 Jul 15 olle 1679     // Check for replicated DNA if some have been replaced with Stratagene
3449 28 Jul 15 olle 1680     if (count > 0) Plate.checkReplicates();
3449 28 Jul 15 olle 1681   }
3449 28 Jul 15 olle 1682   
3449 28 Jul 15 olle 1683   /**
3449 28 Jul 15 olle 1684     Toggle the QC flag for the selected wells. The first non-empty
3449 28 Jul 15 olle 1685     well is toggled and the rest of the wells will use the same new QC
3449 28 Jul 15 olle 1686     value.
3449 28 Jul 15 olle 1687   */
3449 28 Jul 15 olle 1688   selectdna.toggleQc = function(event)
3449 28 Jul 15 olle 1689   {
3449 28 Jul 15 olle 1690     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1691   
3449 28 Jul 15 olle 1692     if (wells.length == 0) 
3449 28 Jul 15 olle 1693     {
3449 28 Jul 15 olle 1694       Forms.showNotification(event.currentTarget, 'No wells have been selected');
3449 28 Jul 15 olle 1695       return;
3449 28 Jul 15 olle 1696     }
3449 28 Jul 15 olle 1697     
3449 28 Jul 15 olle 1698     var gotQc = false;
3449 28 Jul 15 olle 1699     var newQc;
3449 28 Jul 15 olle 1700     var count = 0;
3449 28 Jul 15 olle 1701     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1702     {
3449 28 Jul 15 olle 1703       var well = wells[i];
3449 28 Jul 15 olle 1704       if (well.extract)
3449 28 Jul 15 olle 1705       {
3449 28 Jul 15 olle 1706         // Toggle QC flag for the first well with DNA, then use the same flag for the rest
3449 28 Jul 15 olle 1707         if (!gotQc)
3449 28 Jul 15 olle 1708         {
3449 28 Jul 15 olle 1709           gotQc = true;
3449 28 Jul 15 olle 1710           newQc = !well.extract.qc;
3449 28 Jul 15 olle 1711         }
3449 28 Jul 15 olle 1712         well.extract.qc = newQc;
3449 28 Jul 15 olle 1713         count++;
3449 28 Jul 15 olle 1714       }
3449 28 Jul 15 olle 1715     }
3449 28 Jul 15 olle 1716     
3449 28 Jul 15 olle 1717     if (count == 0)
3449 28 Jul 15 olle 1718     {
3449 28 Jul 15 olle 1719       Forms.showNotification(event.currentTarget, 'None of the selected wells contain any DNA');
3449 28 Jul 15 olle 1720     }
3449 28 Jul 15 olle 1721     else
3449 28 Jul 15 olle 1722     {
3449 28 Jul 15 olle 1723       Plate.paint(wells);
3449 28 Jul 15 olle 1724     }
3449 28 Jul 15 olle 1725   }
3449 28 Jul 15 olle 1726
3449 28 Jul 15 olle 1727   // Set a comment on the selected wells
3449 28 Jul 15 olle 1728   selectdna.commentSelected = function(event)
3449 28 Jul 15 olle 1729   {
3449 28 Jul 15 olle 1730     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1731     
3449 28 Jul 15 olle 1732     if (wells.length == 0)
3449 28 Jul 15 olle 1733     {
3449 28 Jul 15 olle 1734       Forms.showNotification(event.currentTarget, 'No wells have been selected');
3449 28 Jul 15 olle 1735       return;
3449 28 Jul 15 olle 1736     }
3449 28 Jul 15 olle 1737     
3449 28 Jul 15 olle 1738     var count = 0;
3449 28 Jul 15 olle 1739     var comment = '';
3449 28 Jul 15 olle 1740     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1741     {
3449 28 Jul 15 olle 1742       var well = wells[i];
3449 28 Jul 15 olle 1743       if (well.extract) 
3449 28 Jul 15 olle 1744       {
3449 28 Jul 15 olle 1745         count++;
3449 28 Jul 15 olle 1746         if (well.extract.comment) comment = well.extract.comment;
3449 28 Jul 15 olle 1747       }
3449 28 Jul 15 olle 1748     }
3449 28 Jul 15 olle 1749       
3449 28 Jul 15 olle 1750     if (count == 0)
3449 28 Jul 15 olle 1751     {
3449 28 Jul 15 olle 1752       Forms.showNotification(event.currentTarget, 'None of the selected wells contain any DNA');
3449 28 Jul 15 olle 1753       return;
3449 28 Jul 15 olle 1754     }
3449 28 Jul 15 olle 1755
3449 28 Jul 15 olle 1756     comment = prompt('Comment', comment || '');
3449 28 Jul 15 olle 1757     if (comment == null) return;
3449 28 Jul 15 olle 1758     
3449 28 Jul 15 olle 1759     if (comment == '') comment = null;
3449 28 Jul 15 olle 1760     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1761     {
3449 28 Jul 15 olle 1762       var well = wells[i];
3449 28 Jul 15 olle 1763       if (well.extract) well.extract.comment = comment;
3449 28 Jul 15 olle 1764     }
3449 28 Jul 15 olle 1765     Plate.paint(wells);
3449 28 Jul 15 olle 1766   }
3449 28 Jul 15 olle 1767
3449 28 Jul 15 olle 1768   /**
3449 28 Jul 15 olle 1769     Empty the selected wells from DNA. They can later be pasted again.
3449 28 Jul 15 olle 1770   */
3449 28 Jul 15 olle 1771   selectdna.cutSelected = function(event)
3449 28 Jul 15 olle 1772   {
3449 28 Jul 15 olle 1773     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1774     
3449 28 Jul 15 olle 1775     if (wells.length == 0)
3449 28 Jul 15 olle 1776     {
3449 28 Jul 15 olle 1777       Forms.showNotification(event.currentTarget, 'No wells have been selected');
3449 28 Jul 15 olle 1778       return;
3449 28 Jul 15 olle 1779     }
3449 28 Jul 15 olle 1780     
3449 28 Jul 15 olle 1781     var count = 0;
3449 28 Jul 15 olle 1782     var valid = 0;
3449 28 Jul 15 olle 1783     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1784     {
3449 28 Jul 15 olle 1785       var well = wells[i];
3449 28 Jul 15 olle 1786       if (well.extract) 
3449 28 Jul 15 olle 1787       {
3449 28 Jul 15 olle 1788         count++;
3449 28 Jul 15 olle 1789         if (!well.hasError()) valid++;
3449 28 Jul 15 olle 1790       }
3449 28 Jul 15 olle 1791     }
3449 28 Jul 15 olle 1792     
3449 28 Jul 15 olle 1793     if (count == 0)
3449 28 Jul 15 olle 1794     {
3449 28 Jul 15 olle 1795       Forms.showNotification(event.currentTarget, 'None of the selected wells contain any DNA');
3449 28 Jul 15 olle 1796       return;
3449 28 Jul 15 olle 1797     }
3449 28 Jul 15 olle 1798     
3449 28 Jul 15 olle 1799     // Ask for confirmation before deleting from valid wells
3449 28 Jul 15 olle 1800     if (valid > 0)
3449 28 Jul 15 olle 1801     {
3449 28 Jul 15 olle 1802       if (!confirm('Clear DNA from ' + count + ' of ' + wells.length + ' selected wells?'))
3449 28 Jul 15 olle 1803       {
3449 28 Jul 15 olle 1804         return;
3449 28 Jul 15 olle 1805       }
3449 28 Jul 15 olle 1806     }
3449 28 Jul 15 olle 1807   
3449 28 Jul 15 olle 1808     selectdna.copySelected();
3449 28 Jul 15 olle 1809 /*
3449 28 Jul 15 olle 1810     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1811     {
3449 28 Jul 15 olle 1812       var well = wells[i];
3449 28 Jul 15 olle 1813       well.setExtract(null);
3449 28 Jul 15 olle 1814       well.selected = false;
3449 28 Jul 15 olle 1815     }
3449 28 Jul 15 olle 1816     Plate.paint(wells);
3449 28 Jul 15 olle 1817 */
3449 28 Jul 15 olle 1818     var wellsArray = [];      
3449 28 Jul 15 olle 1819     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1820     {
3449 28 Jul 15 olle 1821       var well = wells[i];
3449 28 Jul 15 olle 1822       well.setExtract(null);
3449 28 Jul 15 olle 1823       well.selected = false;
3449 28 Jul 15 olle 1824       wellsArray[i] = well;
3449 28 Jul 15 olle 1825       // Clear FPB sample in corresponding well on right side of plate
3449 28 Jul 15 olle 1826       var row = well.row;
3449 28 Jul 15 olle 1827       var column = well.column;
3449 28 Jul 15 olle 1828       well = Plate.getWell(row, column + 6);
3449 28 Jul 15 olle 1829       well.setExtract(null);
3449 28 Jul 15 olle 1830       well.selected = false;
3449 28 Jul 15 olle 1831       wellsArray[i+wells.length] = well;
3449 28 Jul 15 olle 1832     }
3449 28 Jul 15 olle 1833     Plate.paint(wellsArray);
3449 28 Jul 15 olle 1834     Plate.checkReplicates();
3449 28 Jul 15 olle 1835   }
3449 28 Jul 15 olle 1836   
3449 28 Jul 15 olle 1837   var copy;
3449 28 Jul 15 olle 1838   /**
3449 28 Jul 15 olle 1839     Copy information about the selected wells. 
3449 28 Jul 15 olle 1840   */
3449 28 Jul 15 olle 1841   selectdna.copySelected = function(event)
3449 28 Jul 15 olle 1842   {
3449 28 Jul 15 olle 1843     // Clear existing wells in the copy
3449 28 Jul 15 olle 1844     var repaint = [];
3449 28 Jul 15 olle 1845     if (copy && copy.length > 0)
3449 28 Jul 15 olle 1846     {
3449 28 Jul 15 olle 1847       for (var i = 0; i < copy.length; i++)
3449 28 Jul 15 olle 1848       {
3449 28 Jul 15 olle 1849         var cp = copy[i];
3449 28 Jul 15 olle 1850         cp.well.doneWithCopy();
3449 28 Jul 15 olle 1851         repaint[repaint.length] = cp.well;
3449 28 Jul 15 olle 1852       }
3449 28 Jul 15 olle 1853     }
3449 28 Jul 15 olle 1854     Plate.paint(repaint);
3449 28 Jul 15 olle 1855     
3449 28 Jul 15 olle 1856     // Place selected wells in the copy
3449 28 Jul 15 olle 1857     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1858     copy = [];
3449 28 Jul 15 olle 1859     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1860     {
3449 28 Jul 15 olle 1861       var well = wells[i];
3449 28 Jul 15 olle 1862       copy[copy.length] = well.makeCopy();
3449 28 Jul 15 olle 1863       well.selected = false;
3449 28 Jul 15 olle 1864     }
3449 28 Jul 15 olle 1865     Plate.paint(wells);
3449 28 Jul 15 olle 1866   }
3449 28 Jul 15 olle 1867   
3449 28 Jul 15 olle 1868   /**
3449 28 Jul 15 olle 1869     Paste information into the selected wells.
3449 28 Jul 15 olle 1870   */
3449 28 Jul 15 olle 1871   selectdna.pasteToSelected = function(event)
3449 28 Jul 15 olle 1872   {
3449 28 Jul 15 olle 1873     if (!copy || copy.length == 0) 
3449 28 Jul 15 olle 1874     {
3449 28 Jul 15 olle 1875       Forms.showNotification(event.currentTarget, 'Nothing to paste. Please cut or copy wells first.');
3449 28 Jul 15 olle 1876       return;
3449 28 Jul 15 olle 1877     }
3449 28 Jul 15 olle 1878     
3449 28 Jul 15 olle 1879     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1880     // Count non-empty and valid wells
3449 28 Jul 15 olle 1881     var count = 0;
3449 28 Jul 15 olle 1882     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 1883     {
3449 28 Jul 15 olle 1884       var well = wells[i];
3449 28 Jul 15 olle 1885       if (well.extract && !well.hasError()) count++;
3449 28 Jul 15 olle 1886     }
3449 28 Jul 15 olle 1887     
3449 28 Jul 15 olle 1888     if (count > 0)
3449 28 Jul 15 olle 1889     {
3449 28 Jul 15 olle 1890       if (!confirm('Replace DNA in ' + count + ' wells with copy?'))
3449 28 Jul 15 olle 1891       {
3449 28 Jul 15 olle 1892         return;
3449 28 Jul 15 olle 1893       }
3449 28 Jul 15 olle 1894     }
3449 28 Jul 15 olle 1895     
3449 28 Jul 15 olle 1896     var wi = 0;
3449 28 Jul 15 olle 1897     var ci = 0;
3449 28 Jul 15 olle 1898     var copyEmpty;
3449 28 Jul 15 olle 1899     var askIfEmpty = true;
3449 28 Jul 15 olle 1900     var repaint = [];
3449 28 Jul 15 olle 1901     
3449 28 Jul 15 olle 1902     while (wi < wells.length && ci < copy.length)
3449 28 Jul 15 olle 1903     {
3449 28 Jul 15 olle 1904       var well = wells[wi];
3449 28 Jul 15 olle 1905       var cp = copy[ci];
3449 28 Jul 15 olle 1906       var dna = null;
3449 28 Jul 15 olle 1907       var name = null;
3449 28 Jul 15 olle 1908       cp.well.doneWithCopy();
3449 28 Jul 15 olle 1909       repaint[repaint.length] = cp.well;
3449 28 Jul 15 olle 1910       if (cp.name)
3449 28 Jul 15 olle 1911       {
3449 28 Jul 15 olle 1912         name = cp.name;
3449 28 Jul 15 olle 1913         var suffixIndex = name.indexOf('.fpa');
3449 28 Jul 15 olle 1914         if (suffixIndex >= 0)
3449 28 Jul 15 olle 1915         {
3449 28 Jul 15 olle 1916           name = name.substring(0, suffixIndex);
3449 28 Jul 15 olle 1917         }
3449 28 Jul 15 olle 1918 /*
3449 28 Jul 15 olle 1919         dna = Dna.createByName(cp.name);
3449 28 Jul 15 olle 1920 */
3449 28 Jul 15 olle 1921         dna = Dna.createByName(name);
3449 28 Jul 15 olle 1922         dna.comment = cp.comment;
3449 28 Jul 15 olle 1923       }
3449 28 Jul 15 olle 1924       else
3449 28 Jul 15 olle 1925       {
3449 28 Jul 15 olle 1926         // The copy is from an empty well
3449 28 Jul 15 olle 1927         if (askIfEmpty)
3449 28 Jul 15 olle 1928         {
3449 28 Jul 15 olle 1929           askIfEmpty = false;
3449 28 Jul 15 olle 1930           copyEmpty = confirm('Do you want to copy empty wells? If not, only non-empty well are copied.');
3449 28 Jul 15 olle 1931         }
3449 28 Jul 15 olle 1932       }
3449 28 Jul 15 olle 1933       if (dna != null || copyEmpty)
3449 28 Jul 15 olle 1934       {
3449 28 Jul 15 olle 1935         // FPA
3449 28 Jul 15 olle 1936         if (dna != null)
3449 28 Jul 15 olle 1937         {
3449 28 Jul 15 olle 1938           dna.name += '.fpa'; 
3449 28 Jul 15 olle 1939         }
3449 28 Jul 15 olle 1940         well.setExtract(dna);
3449 28 Jul 15 olle 1941         well.selected = false;
3449 28 Jul 15 olle 1942         repaint[repaint.length] = well;
3449 28 Jul 15 olle 1943         wi++;
3449 28 Jul 15 olle 1944         // FPB sample in corresponding well on right side of plate
3449 28 Jul 15 olle 1945         var row = well.row;
3449 28 Jul 15 olle 1946         var column = well.column;
3449 28 Jul 15 olle 1947         well = Plate.getWell(row, column + 6);
3449 28 Jul 15 olle 1948         dna = null;
3449 28 Jul 15 olle 1949         if (name)
3449 28 Jul 15 olle 1950         {
3449 28 Jul 15 olle 1951           dna = Dna.createByName(name);
3449 28 Jul 15 olle 1952           dna.comment = cp.comment;
3449 28 Jul 15 olle 1953         }
3449 28 Jul 15 olle 1954         if (dna != null)
3449 28 Jul 15 olle 1955         {
3449 28 Jul 15 olle 1956           dna.name += '.fpb'; 
3449 28 Jul 15 olle 1957         }
3449 28 Jul 15 olle 1958         well.setExtract(dna);
3449 28 Jul 15 olle 1959         well.selected = false;
3449 28 Jul 15 olle 1960         repaint[repaint.length] = well;
3449 28 Jul 15 olle 1961       }
3449 28 Jul 15 olle 1962       ci++;
3449 28 Jul 15 olle 1963     }
3449 28 Jul 15 olle 1964     Plate.paint(repaint);
3449 28 Jul 15 olle 1965     copy.splice(0, ci);
3449 28 Jul 15 olle 1966     Plate.checkReplicates();
3449 28 Jul 15 olle 1967   }
3449 28 Jul 15 olle 1968
3449 28 Jul 15 olle 1969   /*
3449 28 Jul 15 olle 1970     If exactly two wells have been selected, switch the DNA in them.
3449 28 Jul 15 olle 1971   */
3449 28 Jul 15 olle 1972   selectdna.switchSelected = function(event)
3449 28 Jul 15 olle 1973   {
3449 28 Jul 15 olle 1974     var wells = Plate.getSelected();
3449 28 Jul 15 olle 1975   
3449 28 Jul 15 olle 1976     if (wells.length != 2)
3449 28 Jul 15 olle 1977     {
3449 28 Jul 15 olle 1978       Forms.showNotification(event.currentTarget, 'Exactly 2 wells must be selected.');
3449 28 Jul 15 olle 1979       return;
3449 28 Jul 15 olle 1980     }
3449 28 Jul 15 olle 1981
3449 28 Jul 15 olle 1982 /*  
3449 28 Jul 15 olle 1983     var dna0 = wells[0].extract;
3449 28 Jul 15 olle 1984     var dna1 = wells[1].extract;
3449 28 Jul 15 olle 1985     
3449 28 Jul 15 olle 1986     wells[0].setExtract(dna1);
3449 28 Jul 15 olle 1987     wells[1].setExtract(dna0);
3449 28 Jul 15 olle 1988     Plate.paint(wells);
3449 28 Jul 15 olle 1989 */
3449 28 Jul 15 olle 1990     var wellsArray = [];
3449 28 Jul 15 olle 1991     // FPA
3449 28 Jul 15 olle 1992     wellsArray[0] = wells[0];
3449 28 Jul 15 olle 1993     wellsArray[1] = wells[1];
3449 28 Jul 15 olle 1994
3449 28 Jul 15 olle 1995     var dna0 = wells[0].extract;
3449 28 Jul 15 olle 1996     var dna1 = wells[1].extract;
3449 28 Jul 15 olle 1997     
3449 28 Jul 15 olle 1998     wells[0].setExtract(dna1);
3449 28 Jul 15 olle 1999     wells[1].setExtract(dna0);
3449 28 Jul 15 olle 2000     // FPB samples in corresponding wells on right side of plate
3449 28 Jul 15 olle 2001     var wellsFpb = [];
3449 28 Jul 15 olle 2002     for (var i=0; i<2; i++)
3449 28 Jul 15 olle 2003     {  
3449 28 Jul 15 olle 2004       var row = wells[i].row;
3449 28 Jul 15 olle 2005       var column = wells[i].column;
3449 28 Jul 15 olle 2006       wellsFpb[i] = Plate.getWell(row, column + 6);
3449 28 Jul 15 olle 2007     }
3449 28 Jul 15 olle 2008     wellsArray[2] = wellsFpb[0];
3449 28 Jul 15 olle 2009     wellsArray[3] = wellsFpb[1];
3449 28 Jul 15 olle 2010
3449 28 Jul 15 olle 2011     dna0 = wellsFpb[0].extract;
3449 28 Jul 15 olle 2012     dna1 = wellsFpb[1].extract;
3449 28 Jul 15 olle 2013     
3449 28 Jul 15 olle 2014     wellsFpb[0].setExtract(dna1);
3449 28 Jul 15 olle 2015     wellsFpb[1].setExtract(dna0);
3449 28 Jul 15 olle 2016     //
3449 28 Jul 15 olle 2017     Plate.paint(wellsArray);
3449 28 Jul 15 olle 2018   }
3449 28 Jul 15 olle 2019
3449 28 Jul 15 olle 2020   // Toggle the 'special select' menu on and off
3449 28 Jul 15 olle 2021   selectdna.toggleSpecialSelect = function(event)
3449 28 Jul 15 olle 2022   {
3449 28 Jul 15 olle 2023     var pos = Doc.getElementPosition('iconSpecialSelect');
3449 28 Jul 15 olle 2024     Menu.toggleTopMenu('menuSpecialSelect', pos.left+pos.width/4, pos.top+pos.height); 
3449 28 Jul 15 olle 2025     event.stopPropagation();
3449 28 Jul 15 olle 2026   }
3449 28 Jul 15 olle 2027   
3631 27 Nov 15 olle 2028   /**
3631 27 Nov 15 olle 2029     Open a pop-up dialog for manual selection of extracts.
3631 27 Nov 15 olle 2030   */
3631 27 Nov 15 olle 2031   selectdna.manualSelectExtract = function(event)
3631 27 Nov 15 olle 2032   {
3631 27 Nov 15 olle 2033     if (subtypeDna == null) subtypeDna = Meludi.getSubtypeInfo('DNA');
3631 27 Nov 15 olle 2034   
3631 27 Nov 15 olle 2035     var url = '&resetTemporary=1';
3631 27 Nov 15 olle 2036     url += '&tmpfilter:INT:itemSubtype='+subtypeDna.id;
3631 27 Nov 15 olle 2037     url += '&tmpfilter:STRING:name='+encodeURIComponent('%.d');
3631 27 Nov 15 olle 2038     url += '&tmpfilter:DATE:creationEvent.eventDate='+encodeURIComponent('');
3631 27 Nov 15 olle 2039     url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>0');
3631 27 Nov 15 olle 2040     url += '&'+encodeURIComponent('tmpfilter:STRING:&childCreationEvents(event.bioMaterial.name)')+'='+encodeURIComponent('');
3631 27 Nov 15 olle 2041
3631 27 Nov 15 olle 2042     Dialogs.selectItem('EXTRACT', 'plate', 1, url);
3631 27 Nov 15 olle 2043   }
3631 27 Nov 15 olle 2044
3631 27 Nov 15 olle 2045   /**
3631 27 Nov 15 olle 2046     Open a pop-up dialog for manual selection of controls.
3631 27 Nov 15 olle 2047   */
3631 27 Nov 15 olle 2048   selectdna.manualSelectControl = function(event)
3631 27 Nov 15 olle 2049   {
3631 27 Nov 15 olle 2050     if (subtypeDna == null) subtypeDna = Meludi.getSubtypeInfo('DNA');
3631 27 Nov 15 olle 2051   
3631 27 Nov 15 olle 2052     var url = '&resetTemporary=1';
3631 27 Nov 15 olle 2053     url += '&tmpfilter:INT:itemSubtype='+subtypeDna.id;
3631 27 Nov 15 olle 2054     url += '&tmpfilter:STRING:name='+encodeURIComponent('Horizon%.d');
3631 27 Nov 15 olle 2055     url += '&tmpfilter:DATE:creationEvent.eventDate='+encodeURIComponent('');
3631 27 Nov 15 olle 2056     url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>0');
3631 27 Nov 15 olle 2057     url += '&'+encodeURIComponent('tmpfilter:STRING:&childCreationEvents(event.bioMaterial.name)')+'='+encodeURIComponent('');
3631 27 Nov 15 olle 2058
3631 27 Nov 15 olle 2059     Dialogs.selectItem('EXTRACT', 'plate', 1, url);
3631 27 Nov 15 olle 2060   }
3631 27 Nov 15 olle 2061
3631 27 Nov 15 olle 2062   /**
3631 27 Nov 15 olle 2063     Callback method for re-setting manual extract selection.
3631 27 Nov 15 olle 2064   */
3631 27 Nov 15 olle 2065   selectdna.manuallySelectedExtract = function(event)
3631 27 Nov 15 olle 2066   {
3631 27 Nov 15 olle 2067     names[names.length] = event.detail.name;
3631 27 Nov 15 olle 2068 //alert("select_dna_for_start_plate.js::manuallySelectedExtract(): names.length = " + names.length + " names = " + JSON.stringify(names));        
3631 27 Nov 15 olle 2069
3631 27 Nov 15 olle 2070     selectdna.initializeStep3(event);
3631 27 Nov 15 olle 2071   }
3631 27 Nov 15 olle 2072
3631 27 Nov 15 olle 2073   selectdna.manualSelectReset = function()
3631 27 Nov 15 olle 2074   {
3631 27 Nov 15 olle 2075     // Reset JSONArray for names to original    
3631 27 Nov 15 olle 2076     names = [];
3631 27 Nov 15 olle 2077     for (var i = 0; i < originalNames.length; i++)
3631 27 Nov 15 olle 2078     {
3631 27 Nov 15 olle 2079       var name = originalNames[i];
3631 27 Nov 15 olle 2080       names[names.length] = name;
3631 27 Nov 15 olle 2081     }
3631 27 Nov 15 olle 2082     selectdna.initializeStep3();
3631 27 Nov 15 olle 2083   }
3631 27 Nov 15 olle 2084
3449 28 Jul 15 olle 2085   var contextDNA = null;
3449 28 Jul 15 olle 2086   var contextX;
3449 28 Jul 15 olle 2087   var contextY;
3449 28 Jul 15 olle 2088   /**
3449 28 Jul 15 olle 2089     Reacts to 'mouseup' and 'contextmenu' events for the bioplate. 
3449 28 Jul 15 olle 2090     This should bring up the cut/copy/paste context menu depending on which
3449 28 Jul 15 olle 2091     mouse button that was clicked.
3449 28 Jul 15 olle 2092   */
3449 28 Jul 15 olle 2093   selectdna.contextEvent = function(event)
3449 28 Jul 15 olle 2094   {
3449 28 Jul 15 olle 2095     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 2096     // Context menu on 'right' mouse button
3449 28 Jul 15 olle 2097     // Can't just check the button since two events are sent ('mouseup' and 'contextmenu')
3449 28 Jul 15 olle 2098     var showContext = event.type == 'contextmenu' && event.button == 2;
3449 28 Jul 15 olle 2099       
3449 28 Jul 15 olle 2100     if (showContext)
3449 28 Jul 15 olle 2101     {
3449 28 Jul 15 olle 2102       event.preventDefault(); // Prevents the default right-click menu from appearing
3449 28 Jul 15 olle 2103       
3449 28 Jul 15 olle 2104       // Get the well that is right-clicked and the DNA that is in it
3449 28 Jul 15 olle 2105       contextDNA = null;
3449 28 Jul 15 olle 2106       var well = event.target;
3449 28 Jul 15 olle 2107       while (well && (!well.id || well.id.indexOf('well') != 0))
3449 28 Jul 15 olle 2108       {
3449 28 Jul 15 olle 2109         well = well.parentNode;
3449 28 Jul 15 olle 2110       }
3449 28 Jul 15 olle 2111       if (well)
3449 28 Jul 15 olle 2112       {
3449 28 Jul 15 olle 2113         var c = well.id.split(/\./);
3449 28 Jul 15 olle 2114         contextDNA = Plate.getWell(parseInt(c[1]), parseInt(c[2])).extract;
3449 28 Jul 15 olle 2115       }
3449 28 Jul 15 olle 2116       // Update the context meny
3449 28 Jul 15 olle 2117       var caseSummaryMenu = Doc.element('mnuCaseSummary');
3449 28 Jul 15 olle 2118       if (contextDNA)
3449 28 Jul 15 olle 2119       {
3449 28 Jul 15 olle 2120         caseSummaryMenu.title = 'Show case summary for ' + Strings.encodeTags(contextDNA.name);
3449 28 Jul 15 olle 2121         Doc.show('sepCaseSummary');
3449 28 Jul 15 olle 2122         Doc.show('mnuCaseSummary');
3449 28 Jul 15 olle 2123       }
3449 28 Jul 15 olle 2124       else
3449 28 Jul 15 olle 2125       {
3449 28 Jul 15 olle 2126         Doc.hide('sepCaseSummary');
3449 28 Jul 15 olle 2127         Doc.hide('mnuCaseSummary');
3449 28 Jul 15 olle 2128       }
3449 28 Jul 15 olle 2129       
3449 28 Jul 15 olle 2130       var menu = Doc.element('menuContext');
3449 28 Jul 15 olle 2131       // 1 pixel offset to avoid losing well focus outline
3449 28 Jul 15 olle 2132       contextX = event.clientX+1;
3449 28 Jul 15 olle 2133       contextY = event.clientY+1;
3449 28 Jul 15 olle 2134       // Need short delay since 'mouseup' are also sent as 'click' events
3449 28 Jul 15 olle 2135       // to the 'document' object which BASE already have a Menu.hideAll()
3449 28 Jul 15 olle 2136       // call which would hide the menu immediately
3449 28 Jul 15 olle 2137       setTimeout(selectdna.showContextMenu, 100);
3449 28 Jul 15 olle 2138     }
3449 28 Jul 15 olle 2139   }
3449 28 Jul 15 olle 2140   
3449 28 Jul 15 olle 2141   selectdna.showContextMenu = function()
3449 28 Jul 15 olle 2142   {
3449 28 Jul 15 olle 2143     Menu.showTopMenu('menuContext', contextX, contextY);
3449 28 Jul 15 olle 2144   }
3449 28 Jul 15 olle 2145
3449 28 Jul 15 olle 2146   selectdna.showCaseSummary = function()
3449 28 Jul 15 olle 2147   {
3449 28 Jul 15 olle 2148     if (!contextDNA) return;
3449 28 Jul 15 olle 2149     var caseName = contextDNA.name;
3449 28 Jul 15 olle 2150     // Remove suffix starting with dot "."
3449 28 Jul 15 olle 2151     var firstDotIndex = caseName.indexOf(".");
3449 28 Jul 15 olle 2152     if (firstDotIndex >= 0)
3449 28 Jul 15 olle 2153     {
3449 28 Jul 15 olle 2154       caseName = caseName.substring(0, firstDotIndex);
3449 28 Jul 15 olle 2155     }
3449 28 Jul 15 olle 2156     var url = '../reports/case_summary.jsp?ID='+App.getSessionId();
3449 28 Jul 15 olle 2157     url += '&caseName='+encodeURIComponent(caseName);
3449 28 Jul 15 olle 2158     url += '&pageType=popup';
3449 28 Jul 15 olle 2159     Dialogs.openPopup(url, 'CaseSummary'+caseName, 1000, 700);
3449 28 Jul 15 olle 2160   }
3449 28 Jul 15 olle 2161   
3449 28 Jul 15 olle 2162   selectdna.showFlaggedDna = function()
3449 28 Jul 15 olle 2163   {
3449 28 Jul 15 olle 2164     currentSelected = Plate.getSelected();
3449 28 Jul 15 olle 2165     currentIndex = 0;
3449 28 Jul 15 olle 2166
3449 28 Jul 15 olle 2167     var flagged = Dna.getFlagged();
3449 28 Jul 15 olle 2168     var url = 'show_flagged_dna.jsp?ID='+App.getSessionId();
3449 28 Jul 15 olle 2169     url += '&numFlagged='+flagged.length;
3449 28 Jul 15 olle 2170     url += '&numSelected='+currentSelected.length;
3449 28 Jul 15 olle 2171     Dialogs.openPopup(url, 'FlaggedDna', 800, 500);
3449 28 Jul 15 olle 2172   }
3449 28 Jul 15 olle 2173
3449 28 Jul 15 olle 2174   
3449 28 Jul 15 olle 2175   //Flag the selected DNA
3449 28 Jul 15 olle 2176   selectdna.flagSelected = function(event)
3449 28 Jul 15 olle 2177   {
3449 28 Jul 15 olle 2178     var flag = Data.get(event.currentTarget, 'flag');
3449 28 Jul 15 olle 2179     var wells = Plate.getSelected();
3449 28 Jul 15 olle 2180     
3449 28 Jul 15 olle 2181     if (wells.length == 0)
3449 28 Jul 15 olle 2182     {
3449 28 Jul 15 olle 2183       Forms.showNotification(event.currentTarget, 'No wells have been selected.');
3449 28 Jul 15 olle 2184       return;
3449 28 Jul 15 olle 2185     }
3449 28 Jul 15 olle 2186     
3449 28 Jul 15 olle 2187     var comment = null;
3449 28 Jul 15 olle 2188     if (flag == 'ManualFlag')
3449 28 Jul 15 olle 2189     {
3449 28 Jul 15 olle 2190       // Check if a comment has been set on any of the DNA
3449 28 Jul 15 olle 2191       for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 2192       {
3449 28 Jul 15 olle 2193         var well = wells[i];
3449 28 Jul 15 olle 2194         if (well.extract && well.extract.info) 
3449 28 Jul 15 olle 2195         {
3449 28 Jul 15 olle 2196           if (well.extract.info.comment) comment = well.extract.info.comment;
3449 28 Jul 15 olle 2197         }
3449 28 Jul 15 olle 2198       }
3449 28 Jul 15 olle 2199       comment = prompt('Comment', comment || '');
3449 28 Jul 15 olle 2200       if (!comment) return;
3449 28 Jul 15 olle 2201     }
3449 28 Jul 15 olle 2202     
3449 28 Jul 15 olle 2203     var count = 0;
3449 28 Jul 15 olle 2204     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 2205     {
3449 28 Jul 15 olle 2206       var well = wells[i];
3449 28 Jul 15 olle 2207       var dna = well.extract;
3449 28 Jul 15 olle 2208       if (dna && !dna.stratagene && !dna.external)
3449 28 Jul 15 olle 2209       {
3449 28 Jul 15 olle 2210         Dna.flag(dna, flag);
3449 28 Jul 15 olle 2211         dna.info.comment = comment;
3449 28 Jul 15 olle 2212         well.setExtract(null);
3449 28 Jul 15 olle 2213         count++;
3449 28 Jul 15 olle 2214       }
3449 28 Jul 15 olle 2215       well.selected = false;
3449 28 Jul 15 olle 2216     }
3449 28 Jul 15 olle 2217     
3449 28 Jul 15 olle 2218     selectdna.updateNumFlaggedDna();
3449 28 Jul 15 olle 2219     Plate.paint(wells);
3449 28 Jul 15 olle 2220   }
3449 28 Jul 15 olle 2221
3573 05 Nov 15 olle 2222   selectdna.validateStep4 = function(event)
3449 28 Jul 15 olle 2223   {
3449 28 Jul 15 olle 2224     if (!quantitiesAreValid) 
3449 28 Jul 15 olle 2225     {
3449 28 Jul 15 olle 2226       event.preventDefault();
3449 28 Jul 15 olle 2227       return;
3449 28 Jul 15 olle 2228     }
3449 28 Jul 15 olle 2229
3449 28 Jul 15 olle 2230     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 2231     var numErrors = 0;
3449 28 Jul 15 olle 2232     var numWarnings = 0;
3449 28 Jul 15 olle 2233     var numDna = 0;
3449 28 Jul 15 olle 2234     var numStratagene = 0;
3449 28 Jul 15 olle 2235     var numExternal = 0;
3449 28 Jul 15 olle 2236     var wells = Plate.getWells();
3449 28 Jul 15 olle 2237     var schema = PoolSchema.getById(frm.pool_schema.value);
3449 28 Jul 15 olle 2238     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 2239     {
3449 28 Jul 15 olle 2240       var well = wells[i];
3449 28 Jul 15 olle 2241       var dna = well.extract;
3449 28 Jul 15 olle 2242       if (well.hasWarning())
3449 28 Jul 15 olle 2243       {
3449 28 Jul 15 olle 2244         numWarnings++;
3449 28 Jul 15 olle 2245       }
3449 28 Jul 15 olle 2246       if (well.hasError())
3449 28 Jul 15 olle 2247       {
3449 28 Jul 15 olle 2248         numErrors++;
3449 28 Jul 15 olle 2249       }
3449 28 Jul 15 olle 2250       else
3449 28 Jul 15 olle 2251       {
3449 28 Jul 15 olle 2252         if (dna && dna.id) 
3449 28 Jul 15 olle 2253         {
3449 28 Jul 15 olle 2254           numDna++;
3449 28 Jul 15 olle 2255           if (dna.stratagene) numStratagene++;
3449 28 Jul 15 olle 2256           if (dna.external) numExternal++;
3449 28 Jul 15 olle 2257         }
3449 28 Jul 15 olle 2258       }
3449 28 Jul 15 olle 2259     }
3449 28 Jul 15 olle 2260
3449 28 Jul 15 olle 2261     if (numErrors > 0)
3449 28 Jul 15 olle 2262     {
3449 28 Jul 15 olle 2263       event.preventDefault();
3449 28 Jul 15 olle 2264       return;
3449 28 Jul 15 olle 2265     }
3449 28 Jul 15 olle 2266     
3449 28 Jul 15 olle 2267     if (numDna == 0)
3449 28 Jul 15 olle 2268     {
3449 28 Jul 15 olle 2269       alert('There is no DNA in any wells');
3449 28 Jul 15 olle 2270       event.preventDefault();
3449 28 Jul 15 olle 2271       return;
3449 28 Jul 15 olle 2272     }
3449 28 Jul 15 olle 2273     
3449 28 Jul 15 olle 2274     if (numWarnings > 0)
3449 28 Jul 15 olle 2275     {
3449 28 Jul 15 olle 2276       if (!confirm('There are ' + numWarnings + ' wells with a warning. Continue anyway?'))
3449 28 Jul 15 olle 2277       {
3449 28 Jul 15 olle 2278         event.preventDefault();
3449 28 Jul 15 olle 2279         return;
3449 28 Jul 15 olle 2280       }
3449 28 Jul 15 olle 2281     }
3449 28 Jul 15 olle 2282     
3449 28 Jul 15 olle 2283     if (schema)
3449 28 Jul 15 olle 2284     {
3449 28 Jul 15 olle 2285       var numPrimary = schema.numPools * schema.numWellsPerPool;
3449 28 Jul 15 olle 2286       if (numDna < numPrimary)
3449 28 Jul 15 olle 2287       {
3449 28 Jul 15 olle 2288         if (!confirm((numPrimary-numDna)+ ' primary wells are missing DNA. Continue anyway?'))
3449 28 Jul 15 olle 2289         {
3449 28 Jul 15 olle 2290           event.preventDefault();
3449 28 Jul 15 olle 2291           return;
3449 28 Jul 15 olle 2292         }
3449 28 Jul 15 olle 2293       }
3449 28 Jul 15 olle 2294     }
3449 28 Jul 15 olle 2295     
3449 28 Jul 15 olle 2296     if (numDna == numStratagene+numExternal)
3449 28 Jul 15 olle 2297     {
3449 28 Jul 15 olle 2298       if (!confirm('There are only wells with Stratagene or external DNA on this plate. Continue anyway?'))
3449 28 Jul 15 olle 2299       {
3449 28 Jul 15 olle 2300         event.preventDefault();
3449 28 Jul 15 olle 2301         return;
3449 28 Jul 15 olle 2302       }
3449 28 Jul 15 olle 2303     }
3449 28 Jul 15 olle 2304     
3449 28 Jul 15 olle 2305   }
3449 28 Jul 15 olle 2306   
3624 25 Nov 15 olle 2307   selectdna.downloadLibPrepFile = function()
3624 25 Nov 15 olle 2308   {
3624 25 Nov 15 olle 2309     var frm = document.forms['meludi'];
3624 25 Nov 15 olle 2310     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3624 25 Nov 15 olle 2311
3624 25 Nov 15 olle 2312     var submitInfo = {};
3624 25 Nov 15 olle 2313     
3624 25 Nov 15 olle 2314     var libraryPreparationProtocolName = '';
3624 25 Nov 15 olle 2315     var libraryPreparationProtocol = frm.libraryPreparationProtocol.value;
3624 25 Nov 15 olle 2316     if (libraryPreparationProtocol)
3624 25 Nov 15 olle 2317     {
3624 25 Nov 15 olle 2318       libraryPreparationProtocolName = protocolMap[libraryPreparationProtocol];
3624 25 Nov 15 olle 2319     }
3624 25 Nov 15 olle 2320     submitInfo.libraryPreparationProtocol = parseInt(libraryPreparationProtocol, 10);
3624 25 Nov 15 olle 2321     submitInfo.libraryPreparationProtocolName = libraryPreparationProtocolName;
3685 12 Jan 16 olle 2322     submitInfo.bioplate = selectdna.fetchBioplateData();
3685 12 Jan 16 olle 2323
3685 12 Jan 16 olle 2324     var url = '../LibPrep.servlet?ID='+App.getSessionId();
3685 12 Jan 16 olle 2325     url += '&cmd=PrepareDownloadLibPrepFile';
3685 12 Jan 16 olle 2326     url += '&referenceName='+encodeURIComponent(frm.plateName.value);
3685 12 Jan 16 olle 2327
3685 12 Jan 16 olle 2328     // POST
3685 12 Jan 16 olle 2329     Wizard.showLoadingAnimation('Performing registration...');
3685 12 Jan 16 olle 2330     Wizard.asyncJsonRequest(url, selectdna.downloadLibPrepFileResults, 'POST', JSON.stringify(submitInfo));
3685 12 Jan 16 olle 2331   }
3685 12 Jan 16 olle 2332
3685 12 Jan 16 olle 2333   selectdna.fetchBioplateData = function()
3685 12 Jan 16 olle 2334   {
3685 12 Jan 16 olle 2335     var frm = document.forms['meludi'];
3685 12 Jan 16 olle 2336     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3624 25 Nov 15 olle 2337     var schema = PoolSchema.getById(frm.pool_schema.value);
3685 12 Jan 16 olle 2338
3685 12 Jan 16 olle 2339     var plateInfo = {};
3685 12 Jan 16 olle 2340     plateInfo.id = Plate.id;
3624 25 Nov 15 olle 2341     plateInfo.name = Plate.name;
3624 25 Nov 15 olle 2342     plateInfo.comments = frm.comments.value;
3685 12 Jan 16 olle 2343     plateInfo.kitName = frm.tsLibPrepKit.value;
3624 25 Nov 15 olle 2344     plateInfo.kitId = frm.hiddenLibPrepKitId.value;
3624 25 Nov 15 olle 2345     plateInfo.plateType = isNeoPrep ? 'NEOPREP' : 'DNA';
3624 25 Nov 15 olle 2346     plateInfo.poolSchema = schema ? schema.id : null;
3624 25 Nov 15 olle 2347     if (isNeoPrep)
3624 25 Nov 15 olle 2348     {
3624 25 Nov 15 olle 2349       plateInfo.barcodeVariant = frm.barcode_variant.value;
3624 25 Nov 15 olle 2350     }
3624 25 Nov 15 olle 2351     plateInfo.wells = [];
3624 25 Nov 15 olle 2352
3624 25 Nov 15 olle 2353     var wells = Plate.getWells();
3624 25 Nov 15 olle 2354     for (var i = 0; i < wells.length; i++)
3624 25 Nov 15 olle 2355     {
3624 25 Nov 15 olle 2356       var well = wells[i];
3624 25 Nov 15 olle 2357       var dna = well.extract;
3667 15 Dec 15 olle 2358       if (dna && dna.info.origId)
3624 25 Nov 15 olle 2359       {
3624 25 Nov 15 olle 2360         var tmp = {};
3624 25 Nov 15 olle 2361         tmp.row = well.row;
3624 25 Nov 15 olle 2362         tmp.column = well.column;
3624 25 Nov 15 olle 2363         tmp.dna = {};
3667 15 Dec 15 olle 2364         tmp.dna.id = dna.info.origId;
3624 25 Nov 15 olle 2365         tmp.dna.usedQuantity = dna.usedQuantity;
3624 25 Nov 15 olle 2366         tmp.dna.dilutionConc = dna.dilutionConc;
3624 25 Nov 15 olle 2367         tmp.dna.qc = dna.qc;
3624 25 Nov 15 olle 2368         tmp.dna.comment = dna.comment;
3624 25 Nov 15 olle 2369         if (well.barcode)
3624 25 Nov 15 olle 2370         {
3624 25 Nov 15 olle 2371           tmp.dna.barcode = well.barcode;
3624 25 Nov 15 olle 2372         }
3624 25 Nov 15 olle 2373         plateInfo.wells[plateInfo.wells.length] = tmp;
3624 25 Nov 15 olle 2374       }
3624 25 Nov 15 olle 2375     }
3685 12 Jan 16 olle 2376     
3685 12 Jan 16 olle 2377     return plateInfo;
3624 25 Nov 15 olle 2378   }
3624 25 Nov 15 olle 2379
3624 25 Nov 15 olle 2380   selectdna.downloadLibPrepFileResults = function(response)
3624 25 Nov 15 olle 2381   {
3624 25 Nov 15 olle 2382     var tmpFilePath = response;
3624 25 Nov 15 olle 2383     var frm = document.forms['meludi'];
3624 25 Nov 15 olle 2384     var url = '../LibPrep.servlet?ID='+App.getSessionId();
3624 25 Nov 15 olle 2385     url += '&cmd=DownloadLibPrepFile';
3624 25 Nov 15 olle 2386     url += '&referenceName='+encodeURIComponent(frm.plateName.value);
3624 25 Nov 15 olle 2387     url += '&tmpFilePath='+encodeURIComponent(tmpFilePath);
3624 25 Nov 15 olle 2388     window.open(url);
3624 25 Nov 15 olle 2389   }
3624 25 Nov 15 olle 2390
3449 28 Jul 15 olle 2391   selectdna.submit = function()
3449 28 Jul 15 olle 2392   {
3449 28 Jul 15 olle 2393     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 2394     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3449 28 Jul 15 olle 2395
3449 28 Jul 15 olle 2396     var submitInfo = {};
3449 28 Jul 15 olle 2397     var plateInfo = {};
3449 28 Jul 15 olle 2398     var flaggedDnaInfo = [];
3449 28 Jul 15 olle 2399     
3619 23 Nov 15 olle 2400     var libraryPreparationProtocolName = '';
3619 23 Nov 15 olle 2401     var libraryPreparationProtocol = frm.libraryPreparationProtocol.value;
3619 23 Nov 15 olle 2402     if (libraryPreparationProtocol)
3619 23 Nov 15 olle 2403     {
3619 23 Nov 15 olle 2404       libraryPreparationProtocolName = protocolMap[libraryPreparationProtocol];
3619 23 Nov 15 olle 2405     }
3619 23 Nov 15 olle 2406     submitInfo.libraryPreparationProtocol = parseInt(libraryPreparationProtocol, 10);
3619 23 Nov 15 olle 2407     submitInfo.libraryPreparationProtocolName = libraryPreparationProtocolName;
3449 28 Jul 15 olle 2408     submitInfo.bioplate = plateInfo;
3449 28 Jul 15 olle 2409     submitInfo.flagged = flaggedDnaInfo;
3449 28 Jul 15 olle 2410     var schema = PoolSchema.getById(frm.pool_schema.value);
3675 18 Dec 15 olle 2411
3449 28 Jul 15 olle 2412     plateInfo.name = Plate.name;
3449 28 Jul 15 olle 2413     plateInfo.comments = frm.comments.value;
3685 12 Jan 16 olle 2414     plateInfo.kitName = frm.tsLibPrepKit.value;
3621 25 Nov 15 olle 2415     plateInfo.kitId = frm.hiddenLibPrepKitId.value;
3449 28 Jul 15 olle 2416     plateInfo.plateType = isNeoPrep ? 'NEOPREP' : 'DNA';
3449 28 Jul 15 olle 2417     plateInfo.poolSchema = schema ? schema.id : null;
3449 28 Jul 15 olle 2418     if (isNeoPrep)
3449 28 Jul 15 olle 2419     {
3449 28 Jul 15 olle 2420       plateInfo.barcodeVariant = frm.barcode_variant.value;
3449 28 Jul 15 olle 2421     }
3449 28 Jul 15 olle 2422     plateInfo.wells = [];
3449 28 Jul 15 olle 2423
3449 28 Jul 15 olle 2424     var wells = Plate.getWells();
3449 28 Jul 15 olle 2425     for (var i = 0; i < wells.length; i++)
3449 28 Jul 15 olle 2426     {
3449 28 Jul 15 olle 2427       var well = wells[i];
3449 28 Jul 15 olle 2428       var dna = well.extract;
3671 17 Dec 15 olle 2429       if (dna && dna.info.origId)
3449 28 Jul 15 olle 2430       {
3449 28 Jul 15 olle 2431         var tmp = {};
3449 28 Jul 15 olle 2432         tmp.row = well.row;
3449 28 Jul 15 olle 2433         tmp.column = well.column;
3449 28 Jul 15 olle 2434         tmp.dna = {};
3671 17 Dec 15 olle 2435         tmp.dna.id = dna.info.origId;
3449 28 Jul 15 olle 2436         tmp.dna.usedQuantity = dna.usedQuantity;
3449 28 Jul 15 olle 2437         tmp.dna.dilutionConc = dna.dilutionConc;
3449 28 Jul 15 olle 2438         tmp.dna.qc = dna.qc;
3449 28 Jul 15 olle 2439         tmp.dna.comment = dna.comment;
3449 28 Jul 15 olle 2440         if (well.barcode)
3449 28 Jul 15 olle 2441         {
3449 28 Jul 15 olle 2442           tmp.dna.barcode = well.barcode;
3449 28 Jul 15 olle 2443         }
3449 28 Jul 15 olle 2444         plateInfo.wells[plateInfo.wells.length] = tmp;
3449 28 Jul 15 olle 2445       }
3449 28 Jul 15 olle 2446     }
3449 28 Jul 15 olle 2447
3449 28 Jul 15 olle 2448     var flagged = Dna.getFlagged();
3449 28 Jul 15 olle 2449     for (var i = 0; i < flagged.length; i++)
3449 28 Jul 15 olle 2450     {
3449 28 Jul 15 olle 2451       var dna = flagged[i];
3449 28 Jul 15 olle 2452       var tmp = {};
3449 28 Jul 15 olle 2453       tmp.id = dna.id;
3449 28 Jul 15 olle 2454       tmp.flag = dna.flag;
3449 28 Jul 15 olle 2455       tmp.comment = dna.comment;
3449 28 Jul 15 olle 2456       flaggedDnaInfo[flaggedDnaInfo.length] = tmp;
3449 28 Jul 15 olle 2457     }
3449 28 Jul 15 olle 2458
3449 28 Jul 15 olle 2459     var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 2460     url += '&cmd=CreateDnaOrLibPlate';
3619 23 Nov 15 olle 2461     url += '&libraryPreparationProtocol=' + parseInt(frm.libraryPreparationProtocol.value, 10);
3619 23 Nov 15 olle 2462     url += '&libraryPreparationProtocolName=' + libraryPreparationProtocolName;
3449 28 Jul 15 olle 2463     Wizard.showLoadingAnimation('Performing registration...');
3449 28 Jul 15 olle 2464     Wizard.asyncJsonRequest(url, selectdna.submissionResults, 'POST', JSON.stringify(submitInfo));
3449 28 Jul 15 olle 2465   }
3449 28 Jul 15 olle 2466   
3449 28 Jul 15 olle 2467   selectdna.submissionResults = function(response)
3449 28 Jul 15 olle 2468   {
3626 26 Nov 15 olle 2469     var frm = document.forms['meludi'];
3626 26 Nov 15 olle 2470     var isNeoPrep = Data.int('page-data', 'is-neoprep');
3626 26 Nov 15 olle 2471     var schema = PoolSchema.getById(frm.pool_schema.value);
3626 26 Nov 15 olle 2472
3626 26 Nov 15 olle 2473     //Wizard.showFinalMessage(response.messages);
3626 26 Nov 15 olle 2474
3626 26 Nov 15 olle 2475     // Update data for used kit regarding used wells for new plate
3626 26 Nov 15 olle 2476     var submitInfo = {};
3626 26 Nov 15 olle 2477     // Add transferred messages
3626 26 Nov 15 olle 2478     submitInfo.transferredMessages = response.messages;
3626 26 Nov 15 olle 2479
3626 26 Nov 15 olle 2480     var plateInfo = {};
3626 26 Nov 15 olle 2481     submitInfo.bioplate = plateInfo;
3626 26 Nov 15 olle 2482     plateInfo.name = Plate.name;
3626 26 Nov 15 olle 2483     plateInfo.comments = frm.comments.value;
3685 12 Jan 16 olle 2484     plateInfo.kitName = frm.tsLibPrepKit.value;
3626 26 Nov 15 olle 2485     plateInfo.kitId = frm.hiddenLibPrepKitId.value;
3626 26 Nov 15 olle 2486     plateInfo.plateType = isNeoPrep ? 'NEOPREP' : 'DNA';
3626 26 Nov 15 olle 2487     plateInfo.poolSchema = schema ? schema.id : null;
3626 26 Nov 15 olle 2488     plateInfo.wells = [];
3626 26 Nov 15 olle 2489
3626 26 Nov 15 olle 2490     var wells = Plate.getWells();
3626 26 Nov 15 olle 2491     for (var i = 0; i < wells.length; i++)
3626 26 Nov 15 olle 2492     {
3626 26 Nov 15 olle 2493       var well = wells[i];
3626 26 Nov 15 olle 2494       var dna = well.extract;
3671 17 Dec 15 olle 2495       if (dna && dna.info.origId)
3626 26 Nov 15 olle 2496       {
3626 26 Nov 15 olle 2497         var tmp = {};
3626 26 Nov 15 olle 2498         tmp.row = well.row;
3626 26 Nov 15 olle 2499         tmp.column = well.column;
3626 26 Nov 15 olle 2500         tmp.dna = {};
3671 17 Dec 15 olle 2501         tmp.dna.id = dna.info.origId;
3626 26 Nov 15 olle 2502         tmp.dna.usedQuantity = dna.usedQuantity;
3626 26 Nov 15 olle 2503         tmp.dna.dilutionConc = dna.dilutionConc;
3626 26 Nov 15 olle 2504         tmp.dna.qc = dna.qc;
3626 26 Nov 15 olle 2505         tmp.dna.comment = dna.comment;
3626 26 Nov 15 olle 2506         if (well.barcode)
3626 26 Nov 15 olle 2507         {
3626 26 Nov 15 olle 2508           tmp.dna.barcode = well.barcode;
3626 26 Nov 15 olle 2509         }
3626 26 Nov 15 olle 2510         plateInfo.wells[plateInfo.wells.length] = tmp;
3626 26 Nov 15 olle 2511       }
3626 26 Nov 15 olle 2512     }
3626 26 Nov 15 olle 2513     var url = '../LibPrep.servlet?ID='+App.getSessionId();
3627 26 Nov 15 olle 2514     url += '&cmd=RegisterKits';
3685 12 Jan 16 olle 2515     url += '&referenceName='+encodeURIComponent(frm.tsLibPrepKit.value);
3626 26 Nov 15 olle 2516     url += '&overwrite=true';
3626 26 Nov 15 olle 2517     url += '&update=true';
3626 26 Nov 15 olle 2518     Wizard.showLoadingAnimation('Performing registration...');
3626 26 Nov 15 olle 2519     Wizard.asyncJsonRequest(url, selectdna.updateKitDataResults, 'POST', JSON.stringify(submitInfo));
3626 26 Nov 15 olle 2520
3626 26 Nov 15 olle 2521     Doc.show('gorestart');
3626 26 Nov 15 olle 2522   }
3626 26 Nov 15 olle 2523
3626 26 Nov 15 olle 2524   selectdna.updateKitDataResults = function(response)
3626 26 Nov 15 olle 2525   {
3449 28 Jul 15 olle 2526     Wizard.showFinalMessage(response.messages);
3449 28 Jul 15 olle 2527     Doc.show('gorestart');
3449 28 Jul 15 olle 2528   }
3590 11 Nov 15 olle 2529
3685 12 Jan 16 olle 2530   selectdna.viewProtocol = function(event)
3685 12 Jan 16 olle 2531   {
3685 12 Jan 16 olle 2532     var frm = document.forms['meludi2'];
3685 12 Jan 16 olle 2533     var bioplateData = selectdna.fetchBioplateData();
3685 12 Jan 16 olle 2534     var submitInfo = selectdna.fetchSubmitInfo();
3685 12 Jan 16 olle 2535
3685 12 Jan 16 olle 2536     // Save values in hidden input fields for retrieval after HTML request
3685 12 Jan 16 olle 2537     var submitInfoJsonStr = JSON.stringify(submitInfo, selectdna.circular_reference_remover);
3685 12 Jan 16 olle 2538     // Enable garbage collection
3685 12 Jan 16 olle 2539     circular_reference_cache = null;
3685 12 Jan 16 olle 2540     frm.hiddenSubmitInfo.value = submitInfoJsonStr;
3685 12 Jan 16 olle 2541     frm.hiddenNumItems.value = submitInfo.items.length;
3685 12 Jan 16 olle 2542     frm.view.value = Data.get(event.currentTarget, 'protocol-type');
3685 12 Jan 16 olle 2543     frm.bioplateName.value = bioplateData.name;
3685 12 Jan 16 olle 2544     frm.bioplateDescription.value = bioplateData.comments;
3685 12 Jan 16 olle 2545     frm.bioplateKitName.value = bioplateData.kitName;
3685 12 Jan 16 olle 2546
3685 12 Jan 16 olle 2547     // Calling frm.submit() will change jsp file to libprep_plate_protocol2.jsp
3685 12 Jan 16 olle 2548     frm.submit();
3685 12 Jan 16 olle 2549   }
3685 12 Jan 16 olle 2550
3590 11 Nov 15 olle 2551   selectdna.createProtocol = function()
3590 11 Nov 15 olle 2552   {
3590 11 Nov 15 olle 2553     var frm = document.forms['meludi'];
3685 12 Jan 16 olle 2554     var submitInfo = selectdna.fetchSubmitInfo();
3685 12 Jan 16 olle 2555
3685 12 Jan 16 olle 2556     // Save values in hidden input fields for retrieval after HTML request
3685 12 Jan 16 olle 2557     var submitInfoJsonStr = JSON.stringify(submitInfo, selectdna.circular_reference_remover);
3685 12 Jan 16 olle 2558     // Enable garbage collection
3685 12 Jan 16 olle 2559     circular_reference_cache = null;
3685 12 Jan 16 olle 2560     frm.hiddenSubmitInfo.value = submitInfoJsonStr;
3685 12 Jan 16 olle 2561     frm.hiddenNumItems.value = submitInfo.items.length;
3685 12 Jan 16 olle 2562
3685 12 Jan 16 olle 2563     // Calling frm.submit() will change jsp file to libprep_dilution_protocol2.jsp
3685 12 Jan 16 olle 2564     frm.submit();
3685 12 Jan 16 olle 2565   }
3685 12 Jan 16 olle 2566
3685 12 Jan 16 olle 2567   selectdna.fetchSubmitInfo = function()
3685 12 Jan 16 olle 2568   {
3685 12 Jan 16 olle 2569     var frm = document.forms['meludi'];
3590 11 Nov 15 olle 2570     var submitInfo = {};
3590 11 Nov 15 olle 2571     submitInfo.items = [];
3590 11 Nov 15 olle 2572
3652 08 Dec 15 olle 2573     submitInfo.docMode = 'protocol';
3590 11 Nov 15 olle 2574     // Get list of selected extract source items
3590 11 Nov 15 olle 2575     var selItemsList = [];
3590 11 Nov 15 olle 2576     for (var column = 0; column < 6; column++)
3590 11 Nov 15 olle 2577     {
3590 11 Nov 15 olle 2578       for (var row = 0; row < 8; row++)
3590 11 Nov 15 olle 2579       {
3590 11 Nov 15 olle 2580         var well = Plate.getWell(row, column);
3590 11 Nov 15 olle 2581         var dna = well.extract;
3590 11 Nov 15 olle 2582         if (dna != null)
3590 11 Nov 15 olle 2583         {        
3685 12 Jan 16 olle 2584           dna.bioWell = well;
3590 11 Nov 15 olle 2585           dna.fpaPos = selectdna.wellRowColumnToWellStr(row, column); 
3590 11 Nov 15 olle 2586           dna.fpbPos = selectdna.wellRowColumnToWellStr(row, column + 6); 
3590 11 Nov 15 olle 2587           selItemsList[selItemsList.length] = dna;
3590 11 Nov 15 olle 2588         }
3590 11 Nov 15 olle 2589       }
3590 11 Nov 15 olle 2590     }
3590 11 Nov 15 olle 2591     var numItems = selItemsList.length;
3590 11 Nov 15 olle 2592     var totNumItems = numItems;
3590 11 Nov 15 olle 2593     for (var i = 0; i < totNumItems; i++)
3590 11 Nov 15 olle 2594     {
3590 11 Nov 15 olle 2595       var item = null;
3590 11 Nov 15 olle 2596       item = selItemsList[i];
3590 11 Nov 15 olle 2597       submitInfo.items[submitInfo.items.length] = item;
3590 11 Nov 15 olle 2598     }
3590 11 Nov 15 olle 2599
3590 11 Nov 15 olle 2600     // Library preparation dilution
3619 23 Nov 15 olle 2601     var libraryPreparationProtocolName = '';
3619 23 Nov 15 olle 2602     var libraryPreparationProtocol = frm.libraryPreparationProtocol.value;
3619 23 Nov 15 olle 2603     if (libraryPreparationProtocol)
3619 23 Nov 15 olle 2604     {
3619 23 Nov 15 olle 2605       libraryPreparationProtocolName = protocolMap[libraryPreparationProtocol];
3619 23 Nov 15 olle 2606     }
3619 23 Nov 15 olle 2607     submitInfo.libraryPreparationProtocol = parseInt(libraryPreparationProtocol, 10);
3619 23 Nov 15 olle 2608     submitInfo.libraryPreparationProtocolName = libraryPreparationProtocolName;
3590 11 Nov 15 olle 2609     submitInfo.startPlateName = frm.plateName.value;
3590 11 Nov 15 olle 2610     var now = new Date();
3590 11 Nov 15 olle 2611     var dilutionProtocolDate = selectdna.formatDate(now);
3590 11 Nov 15 olle 2612     submitInfo.dilutionProtocolDate = dilutionProtocolDate;
3590 11 Nov 15 olle 2613
3685 12 Jan 16 olle 2614     return submitInfo;
3685 12 Jan 16 olle 2615   }
3685 12 Jan 16 olle 2616   
3685 12 Jan 16 olle 2617 var circular_reference_cache = [];
3590 11 Nov 15 olle 2618
3685 12 Jan 16 olle 2619   selectdna.circular_reference_remover = function(key, value)
3685 12 Jan 16 olle 2620   {
3685 12 Jan 16 olle 2621     if (typeof value === 'object' && value !== null)
3685 12 Jan 16 olle 2622     {
3685 12 Jan 16 olle 2623       if (circular_reference_cache == null)
3685 12 Jan 16 olle 2624       {
3685 12 Jan 16 olle 2625         circular_reference_cache = [];
3685 12 Jan 16 olle 2626       }
3685 12 Jan 16 olle 2627       if (circular_reference_cache.indexOf(value) !== -1)
3685 12 Jan 16 olle 2628       {
3685 12 Jan 16 olle 2629         // Circular reference found, discard key
3685 12 Jan 16 olle 2630         return;
3685 12 Jan 16 olle 2631       }
3685 12 Jan 16 olle 2632       // Store value in collection
3685 12 Jan 16 olle 2633       circular_reference_cache.push(value);
3685 12 Jan 16 olle 2634     }
3685 12 Jan 16 olle 2635     return value;
3590 11 Nov 15 olle 2636   }
3685 12 Jan 16 olle 2637
3449 28 Jul 15 olle 2638   selectdna.initElements = function(element, autoInit)
3449 28 Jul 15 olle 2639   {
3449 28 Jul 15 olle 2640     if (autoInit == 'plate-col')
3449 28 Jul 15 olle 2641     {
3449 28 Jul 15 olle 2642       Events.addEventHandler(element, 'click', selectdna.toggleColumn);
3449 28 Jul 15 olle 2643       Events.addEventHandler(element, 'mouseover', selectdna.highlightColumn);
3449 28 Jul 15 olle 2644       Events.addEventHandler(element, 'mouseout', selectdna.highlightColumn);
3449 28 Jul 15 olle 2645     }
3449 28 Jul 15 olle 2646     else if (autoInit == 'plate-row')
3449 28 Jul 15 olle 2647     {
3449 28 Jul 15 olle 2648       Events.addEventHandler(element, 'click', selectdna.toggleRow);
3449 28 Jul 15 olle 2649       Events.addEventHandler(element, 'mouseover', selectdna.highlightRow);
3449 28 Jul 15 olle 2650       Events.addEventHandler(element, 'mouseout', selectdna.highlightRow);
3449 28 Jul 15 olle 2651     }
3449 28 Jul 15 olle 2652     else if (autoInit == 'plate-well')
3449 28 Jul 15 olle 2653     {
3449 28 Jul 15 olle 2654       Events.addEventHandler(element, 'click', selectdna.toggleWell);
3449 28 Jul 15 olle 2655       Events.addEventHandler(element, 'mouseover', selectdna.highlightReplicated);
3449 28 Jul 15 olle 2656       Events.addEventHandler(element, 'mouseout', selectdna.highlightReplicated);
3449 28 Jul 15 olle 2657     }
3449 28 Jul 15 olle 2658     else if (autoInit == 'special-select')
3449 28 Jul 15 olle 2659     {
3449 28 Jul 15 olle 2660       Events.addEventHandler(element, 'click', selectdna.specialToggle)
3449 28 Jul 15 olle 2661     }
3449 28 Jul 15 olle 2662   }
3449 28 Jul 15 olle 2663
3449 28 Jul 15 olle 2664   // Restrict wells to left side of plate
3449 28 Jul 15 olle 2665   selectdna.restrictWells = function(wellsInput)
3449 28 Jul 15 olle 2666   {
3449 28 Jul 15 olle 2667     var wells = [];
3449 28 Jul 15 olle 2668     for (var i = 0; i < wellsInput.length; i++)
3449 28 Jul 15 olle 2669     {
3449 28 Jul 15 olle 2670       well = wellsInput[i];
3449 28 Jul 15 olle 2671       if (well.column < 6)
3449 28 Jul 15 olle 2672       {
3449 28 Jul 15 olle 2673         wells[wells.length] = well;
3449 28 Jul 15 olle 2674       }
3449 28 Jul 15 olle 2675     }
3449 28 Jul 15 olle 2676     return wells;
3449 28 Jul 15 olle 2677   }
3449 28 Jul 15 olle 2678
3449 28 Jul 15 olle 2679   // Toggle the selected status of a single well
3449 28 Jul 15 olle 2680   selectdna.toggleWell = function(event)
3449 28 Jul 15 olle 2681   {
3449 28 Jul 15 olle 2682     var row = Data.int(event.currentTarget, 'row');
3449 28 Jul 15 olle 2683     var column = Data.int(event.currentTarget, 'col');
3449 28 Jul 15 olle 2684     if (column >= 6)
3449 28 Jul 15 olle 2685     {
3449 28 Jul 15 olle 2686       return;
3449 28 Jul 15 olle 2687     }
3449 28 Jul 15 olle 2688     var well = Plate.getWell(row, column);
3449 28 Jul 15 olle 2689     Plate.toggleSelected([well]);
3449 28 Jul 15 olle 2690   }
3449 28 Jul 15 olle 2691
3449 28 Jul 15 olle 2692   // Toggle the selected status of a complete row
3449 28 Jul 15 olle 2693   selectdna.toggleRow = function(event)
3449 28 Jul 15 olle 2694   {
3449 28 Jul 15 olle 2695     var row = Data.int(event.currentTarget, 'row');
3449 28 Jul 15 olle 2696 /*
3449 28 Jul 15 olle 2697     Plate.toggleSelected(Plate.getRow(row));
3449 28 Jul 15 olle 2698 */
3449 28 Jul 15 olle 2699     var wells = selectdna.restrictWells(Plate.getRow(row));
3449 28 Jul 15 olle 2700     Plate.toggleSelected(wells);
3449 28 Jul 15 olle 2701   }
3449 28 Jul 15 olle 2702
3449 28 Jul 15 olle 2703   // Toggle the selected status of a complete column
3449 28 Jul 15 olle 2704   selectdna.toggleColumn = function(event)
3449 28 Jul 15 olle 2705   {
3449 28 Jul 15 olle 2706     var column = Data.int(event.currentTarget, 'col');
3449 28 Jul 15 olle 2707     if (column >= 6)
3449 28 Jul 15 olle 2708     {
3449 28 Jul 15 olle 2709       return;
3449 28 Jul 15 olle 2710     }
3449 28 Jul 15 olle 2711     Plate.toggleSelected(Plate.getColumn(column));
3449 28 Jul 15 olle 2712   }
3449 28 Jul 15 olle 2713   
3449 28 Jul 15 olle 2714   // Toggle the selected status of a pool
3449 28 Jul 15 olle 2715   selectdna.togglePool = function(event)
3449 28 Jul 15 olle 2716   {
3449 28 Jul 15 olle 2717     var pool = Data.int(event.target, 'pool-num');
3449 28 Jul 15 olle 2718 /*
3449 28 Jul 15 olle 2719     if (!isNaN(pool)) Plate.toggleSelected(Plate.getPool(pool));
3449 28 Jul 15 olle 2720 */
3449 28 Jul 15 olle 2721     if (!isNaN(pool) && pool < 1)
3449 28 Jul 15 olle 2722     {
3449 28 Jul 15 olle 2723       Plate.toggleSelected(Plate.getPool(pool));
3449 28 Jul 15 olle 2724     }
3449 28 Jul 15 olle 2725   }
3449 28 Jul 15 olle 2726   
3449 28 Jul 15 olle 2727   // Highlight enable/disable all wells in a column
3449 28 Jul 15 olle 2728   selectdna.highlightColumn = function(event)
3449 28 Jul 15 olle 2729   {
3449 28 Jul 15 olle 2730     var column = Data.int(event.currentTarget, 'col');
3449 28 Jul 15 olle 2731     if (column >= 6)
3449 28 Jul 15 olle 2732     {
3449 28 Jul 15 olle 2733       return;
3449 28 Jul 15 olle 2734     }
3449 28 Jul 15 olle 2735     var on = event.type == 'mouseover';
3449 28 Jul 15 olle 2736     
3449 28 Jul 15 olle 2737     Doc.addOrRemoveClass(event.currentTarget, 'highlight-column', on);
3449 28 Jul 15 olle 2738     var wells = Plate.getColumn(column);
3449 28 Jul 15 olle 2739     Plate.setHighlight(wells, 'highlight-column', on);
3449 28 Jul 15 olle 2740   }
3449 28 Jul 15 olle 2741
3449 28 Jul 15 olle 2742   // Highlight enable/disable all wells in a row
3449 28 Jul 15 olle 2743   selectdna.highlightRow = function(event)
3449 28 Jul 15 olle 2744   {
3449 28 Jul 15 olle 2745     var row = Data.int(event.currentTarget, 'row');
3449 28 Jul 15 olle 2746     var on = event.type == 'mouseover';
3449 28 Jul 15 olle 2747     
3449 28 Jul 15 olle 2748     Doc.addOrRemoveClass(event.currentTarget, 'highlight-row', on);
3449 28 Jul 15 olle 2749 /*
3449 28 Jul 15 olle 2750     var wells = Plate.getRow(row);
3449 28 Jul 15 olle 2751 */
3449 28 Jul 15 olle 2752     var wells = selectdna.restrictWells(Plate.getRow(row));
3449 28 Jul 15 olle 2753     Plate.setHighlight(wells, 'highlight-row', on);
3449 28 Jul 15 olle 2754   }
3449 28 Jul 15 olle 2755   
3449 28 Jul 15 olle 2756   // Highligt enable/disable all wells in a pool
3449 28 Jul 15 olle 2757   selectdna.highlightPool = function(event)
3449 28 Jul 15 olle 2758   {
3449 28 Jul 15 olle 2759     var pool = Data.int(event.target, 'pool-num');
3449 28 Jul 15 olle 2760     var on = event.type == 'mouseover';
3449 28 Jul 15 olle 2761 /*
3449 28 Jul 15 olle 2762     if (!isNaN(pool))
3449 28 Jul 15 olle 2763 */
3449 28 Jul 15 olle 2764     if (!isNaN(pool) && pool < 1)
3449 28 Jul 15 olle 2765     {
3449 28 Jul 15 olle 2766       Doc.addOrRemoveClass(event.target, 'highlight-pool', on);
3449 28 Jul 15 olle 2767       var wells = Plate.getPool(pool);
3449 28 Jul 15 olle 2768       Plate.setHighlight(wells, 'highlight-pool', on);
3449 28 Jul 15 olle 2769     }
3449 28 Jul 15 olle 2770   }
3449 28 Jul 15 olle 2771
3449 28 Jul 15 olle 2772   /**
3449 28 Jul 15 olle 2773     Highlight all replicated wells with the same DNA as the given well.
3449 28 Jul 15 olle 2774   */
3449 28 Jul 15 olle 2775   selectdna.highlightReplicated = function(event)
3449 28 Jul 15 olle 2776   {
3449 28 Jul 15 olle 2777     var column = Data.int(event.currentTarget, 'col');
3449 28 Jul 15 olle 2778     if (column >= 6)
3449 28 Jul 15 olle 2779     {
3449 28 Jul 15 olle 2780       return;
3449 28 Jul 15 olle 2781     }
3449 28 Jul 15 olle 2782     var row = Data.int(event.currentTarget, 'row');
3449 28 Jul 15 olle 2783     var on = event.type == 'mouseover';
3449 28 Jul 15 olle 2784     
3449 28 Jul 15 olle 2785     var well = Plate.getWell(row, column);
3449 28 Jul 15 olle 2786     if (well.extract && well.replicate)
3449 28 Jul 15 olle 2787     {
3449 28 Jul 15 olle 2788       // Get center coordinates for the current well
3449 28 Jul 15 olle 2789       var pos = Doc.getElementPosition(well.tag);
3449 28 Jul 15 olle 2790       var jsPos = new jsPoint(pos.left+pos.width/2, pos.top+pos.height/2);
3449 28 Jul 15 olle 2791   
3449 28 Jul 15 olle 2792       var replicated = Plate.getWellsByName(well.extract.name);
3449 28 Jul 15 olle 2793       for (var i = 0; i < replicated.length; i++)
3449 28 Jul 15 olle 2794       {
3449 28 Jul 15 olle 2795         var rep = replicated[i];
3449 28 Jul 15 olle 2796         if (rep != well)
3449 28 Jul 15 olle 2797         {
3449 28 Jul 15 olle 2798           Doc.addOrRemoveClass(rep.tag, 'highlight-replicated', on);
3449 28 Jul 15 olle 2799           if (rep.line)
3449 28 Jul 15 olle 2800           {
3449 28 Jul 15 olle 2801             // Clear any recent lines
3449 28 Jul 15 olle 2802             graphics.clearDrawing(rep.line);
3449 28 Jul 15 olle 2803             rep.line = null;
3449 28 Jul 15 olle 2804           }
3449 28 Jul 15 olle 2805           if (on)
3449 28 Jul 15 olle 2806           {
3449 28 Jul 15 olle 2807             // We draw a line between the current and replicated well
3449 28 Jul 15 olle 2808             var rPos = Doc.getElementPosition(rep.tag);
3449 28 Jul 15 olle 2809             rep.line = graphics.drawLine(pen, jsPos, new jsPoint(rPos.left+rPos.width/2, rPos.top+rPos.height/2));
3449 28 Jul 15 olle 2810           }
3449 28 Jul 15 olle 2811         }
3449 28 Jul 15 olle 2812       }
3449 28 Jul 15 olle 2813     }
3449 28 Jul 15 olle 2814   }
3449 28 Jul 15 olle 2815
3449 28 Jul 15 olle 2816   // Some special toogle operations
3449 28 Jul 15 olle 2817   selectdna.specialToggle = function(event)
3449 28 Jul 15 olle 2818   {
3449 28 Jul 15 olle 2819     var what = Data.get(event.currentTarget, 'special');
3449 28 Jul 15 olle 2820     var wells = [];
3449 28 Jul 15 olle 2821     if (what == 'all' || what == 'empty' || what == 'none')
3449 28 Jul 15 olle 2822     {
3449 28 Jul 15 olle 2823       // All wells or all empty (will be filtered later)
3449 28 Jul 15 olle 2824       wells = Plate.getWells();
3449 28 Jul 15 olle 2825     }
3449 28 Jul 15 olle 2826     else if (what == 'pools' || what == 'empty-pools')
3449 28 Jul 15 olle 2827     {
3449 28 Jul 15 olle 2828       // All primary pools or all empty in the primary pools (will be filtered later)
3449 28 Jul 15 olle 2829       for (var i = 0; i < Plate.poolSchema.numPools; i++)
3449 28 Jul 15 olle 2830       {
3449 28 Jul 15 olle 2831         wells = wells.concat(Plate.getPool(i));
3449 28 Jul 15 olle 2832       }
3449 28 Jul 15 olle 2833     }
3449 28 Jul 15 olle 2834     else if (what == 'stratagene')
3449 28 Jul 15 olle 2835     {
3449 28 Jul 15 olle 2836       // All wells with 'Stratagene'
3449 28 Jul 15 olle 2837       var tmp = Plate.getWells();
3449 28 Jul 15 olle 2838       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2839       {
3449 28 Jul 15 olle 2840         var well = tmp[i];
3449 28 Jul 15 olle 2841         if (well.extract && well.extract.stratagene) wells[wells.length] = well;
3449 28 Jul 15 olle 2842       }
3449 28 Jul 15 olle 2843     }
3449 28 Jul 15 olle 2844     else if (what == 'external')
3449 28 Jul 15 olle 2845     {
3449 28 Jul 15 olle 2846       // All wells with 'External DNA'
3449 28 Jul 15 olle 2847       var tmp = Plate.getWells();
3449 28 Jul 15 olle 2848       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2849       {
3449 28 Jul 15 olle 2850         var well = tmp[i];
3449 28 Jul 15 olle 2851         if (well.extract && well.extract.external) wells[wells.length] = well;
3449 28 Jul 15 olle 2852       }
3449 28 Jul 15 olle 2853     }
3449 28 Jul 15 olle 2854     else if (what == 'replicates')
3449 28 Jul 15 olle 2855     {
3449 28 Jul 15 olle 2856       // All wells with replicated DNA
3449 28 Jul 15 olle 2857       var tmp = Plate.getWells();
3449 28 Jul 15 olle 2858       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2859       {
3449 28 Jul 15 olle 2860         var well = tmp[i];
3449 28 Jul 15 olle 2861         if (well.extract && well.replicate) wells[wells.length] = well;
3449 28 Jul 15 olle 2862       }
3449 28 Jul 15 olle 2863     }
3449 28 Jul 15 olle 2864     else if (what == 'error')
3449 28 Jul 15 olle 2865     {
3449 28 Jul 15 olle 2866       // All wells with an error
3449 28 Jul 15 olle 2867       var tmp = Plate.getWells();
3449 28 Jul 15 olle 2868       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2869       {
3449 28 Jul 15 olle 2870         var well = tmp[i];
3449 28 Jul 15 olle 2871         if (well.hasError()) wells[wells.length] = well;
3449 28 Jul 15 olle 2872       }
3449 28 Jul 15 olle 2873     }
3449 28 Jul 15 olle 2874     else if (what == 'warning')
3449 28 Jul 15 olle 2875     {
3449 28 Jul 15 olle 2876       // All wells with a warning
3449 28 Jul 15 olle 2877       var tmp = Plate.getWells();
3449 28 Jul 15 olle 2878       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2879       {
3449 28 Jul 15 olle 2880         var well = tmp[i];
3449 28 Jul 15 olle 2881         if (well.warning) wells[wells.length] = well;
3449 28 Jul 15 olle 2882       }
3449 28 Jul 15 olle 2883     }
3449 28 Jul 15 olle 2884     
3449 28 Jul 15 olle 2885     // Extra filter for empty wells only
3449 28 Jul 15 olle 2886     if (what.indexOf('empty') != -1)
3449 28 Jul 15 olle 2887     {
3449 28 Jul 15 olle 2888       var tmp = wells;
3449 28 Jul 15 olle 2889       wells = [];
3449 28 Jul 15 olle 2890       for (var i = 0; i < tmp.length; i++)
3449 28 Jul 15 olle 2891       {
3449 28 Jul 15 olle 2892         if (!tmp[i].extract) wells[wells.length] = tmp[i];
3449 28 Jul 15 olle 2893       }
3449 28 Jul 15 olle 2894     }
3449 28 Jul 15 olle 2895     
3449 28 Jul 15 olle 2896     if (what == 'none')
3449 28 Jul 15 olle 2897     {
3449 28 Jul 15 olle 2898       Plate.setSelected(wells, false);
3449 28 Jul 15 olle 2899     }
3449 28 Jul 15 olle 2900     else
3449 28 Jul 15 olle 2901     {
3449 28 Jul 15 olle 2902       Plate.toggleSelected(wells);
3449 28 Jul 15 olle 2903     }
3449 28 Jul 15 olle 2904   }
3449 28 Jul 15 olle 2905
3449 28 Jul 15 olle 2906   // Format value as a date in format yyyy-mm-dd
3449 28 Jul 15 olle 2907   selectdna.asDate = function(value)
3449 28 Jul 15 olle 2908   {
3449 28 Jul 15 olle 2909     if (!value) return '';
3449 28 Jul 15 olle 2910     if (value.length == 8)
3449 28 Jul 15 olle 2911     {
3449 28 Jul 15 olle 2912       value = value.substr(0, 4) + '-' + value.substr(4, 2) + '-' + value.substr(6, 2);
3449 28 Jul 15 olle 2913     }
3449 28 Jul 15 olle 2914     return value;
3449 28 Jul 15 olle 2915   }
3449 28 Jul 15 olle 2916
3590 11 Nov 15 olle 2917   // Format date value in format yyyy-mm-dd
3590 11 Nov 15 olle 2918   selectdna.formatDate = function(date)
3590 11 Nov 15 olle 2919   {
3590 11 Nov 15 olle 2920     if (!date) return '';
3590 11 Nov 15 olle 2921     var year = date.getFullYear();
3590 11 Nov 15 olle 2922     var month = (date.getMonth() + 1);
3590 11 Nov 15 olle 2923     var day = date.getDate();
3648 04 Dec 15 olle 2924     var monthStr = '' + month;
3648 04 Dec 15 olle 2925     if (month < 10)
3648 04 Dec 15 olle 2926     {
3648 04 Dec 15 olle 2927       monthStr = '0' + month;
3648 04 Dec 15 olle 2928     }
3648 04 Dec 15 olle 2929     var dayStr = '' + day;
3648 04 Dec 15 olle 2930     if (day < 10)
3648 04 Dec 15 olle 2931     {
3648 04 Dec 15 olle 2932       dayStr = '0' + day;
3648 04 Dec 15 olle 2933     }
3648 04 Dec 15 olle 2934     var dateStr = '' + year + '-' + monthStr + '-' + dayStr;
3590 11 Nov 15 olle 2935     return dateStr;
3590 11 Nov 15 olle 2936   }
3590 11 Nov 15 olle 2937
3573 05 Nov 15 olle 2938   selectdna.buildKitInfoPlate = function(plate)
3573 05 Nov 15 olle 2939   {
3573 05 Nov 15 olle 2940     var html = '';
3573 05 Nov 15 olle 2941     // Table row with kit data
3573 05 Nov 15 olle 2942     html += '<tr class="align-top">';
3573 05 Nov 15 olle 2943     // Added data for kit
3573 05 Nov 15 olle 2944     var kitName = plate.kitName;
3573 05 Nov 15 olle 2945     var expirationDate = plate.expirationDate;
3573 05 Nov 15 olle 2946     var timesUsed = plate.timesUsed;
3573 05 Nov 15 olle 2947     //
3573 05 Nov 15 olle 2948     var unusedWellsJsonArr = plate.unusedWells;
3573 05 Nov 15 olle 2949     var effUnusedWellsJsonArr = plate.effUnusedWells;
3573 05 Nov 15 olle 2950     var reservedWellsJsonArr = plate.reservedWells;
3582 06 Nov 15 olle 2951
3582 06 Nov 15 olle 2952 /*    
3573 05 Nov 15 olle 2953     html += '<td class="prompt"><b>Kit name: ' + kitName + '</b></td><br>';
3573 05 Nov 15 olle 2954     html += '<td class="prompt"><b>Expiration date: ' + expirationDate + '</b></td><br>';
3573 05 Nov 15 olle 2955     html += '<td class="prompt"><b>#Times used: ' + timesUsed + '</b></td><br>';
3573 05 Nov 15 olle 2956     html += '<td class="prompt"><b>#Available wells: ' + unusedWellsJsonArr.length + '</b></td><br>';
3573 05 Nov 15 olle 2957     html += '<td class="prompt"><b>#Eff. available wells: ' + effUnusedWellsJsonArr.length + '</b></td><br>';
3582 06 Nov 15 olle 2958 */
3573 05 Nov 15 olle 2959     // Kit as plate
3573 05 Nov 15 olle 2960     // Only show FPA columns, i.e. columns 0-5
3573 05 Nov 15 olle 2961     var colNoEnd = 5;
3573 05 Nov 15 olle 2962     if (plate.geometry.columns < colNoEnd)
3573 05 Nov 15 olle 2963     {
3573 05 Nov 15 olle 2964       colNoEnd = plate.geometry.columns;
3573 05 Nov 15 olle 2965     }
3573 05 Nov 15 olle 2966     html += '<td>';
3573 05 Nov 15 olle 2967     html += '<table class="plate">';
3573 05 Nov 15 olle 2968     html += '<tr class="header"><th></th>';
3573 05 Nov 15 olle 2969     for (var colNo = 0; colNo <= colNoEnd; colNo++)
3573 05 Nov 15 olle 2970     {
3573 05 Nov 15 olle 2971       html += '<th>'+(colNo+1)+'</th>';
3573 05 Nov 15 olle 2972     }
3573 05 Nov 15 olle 2973     html += '</tr>';
3573 05 Nov 15 olle 2974     var wells = plate.bioWells;
3573 05 Nov 15 olle 2975     var wellNo = 0;
3573 05 Nov 15 olle 2976     for (var rowNo = 0; rowNo < plate.geometry.rows; rowNo++)
3573 05 Nov 15 olle 2977     {
3573 05 Nov 15 olle 2978       html += '<tr class="row-'+rowNo+'">';
3573 05 Nov 15 olle 2979       html += '<th>'+Meludi.wellToAlpha(rowNo)+'</th>';
3573 05 Nov 15 olle 2980       for (var colNo = 0; colNo <= colNoEnd; colNo++)
3573 05 Nov 15 olle 2981       {
3573 05 Nov 15 olle 2982         var well = wells[wellNo];
3573 05 Nov 15 olle 2983         well.extraVolume = 0;
3573 05 Nov 15 olle 2984         well.comment = '';
3573 05 Nov 15 olle 2985         
3573 05 Nov 15 olle 2986         if (well.bioMaterial)
3573 05 Nov 15 olle 2987         {
3573 05 Nov 15 olle 2988           html += '<td id="well-'+well.id+'"';
3573 05 Nov 15 olle 2989           html += ' class="well selectable col-'+colNo+'"';
3573 05 Nov 15 olle 2990           html += ' title="'+Strings.encodeTags(well.bioMaterial.name)+'" data-well-id="'+well.id+'"';
3573 05 Nov 15 olle 2991           html += '>0'+THIN_SPACE+'µl</td>';
3573 05 Nov 15 olle 2992         }
3573 05 Nov 15 olle 2993         else
3573 05 Nov 15 olle 2994         {
3573 05 Nov 15 olle 2995           var wellName = Meludi.wellToAlpha(rowNo) + (colNo+1);
3573 05 Nov 15 olle 2996           // Check if kit is used for current well
3573 05 Nov 15 olle 2997           var usedWell = true;
3573 05 Nov 15 olle 2998           for (var i = 0; i < unusedWellsJsonArr.length; i++)
3573 05 Nov 15 olle 2999           {
3573 05 Nov 15 olle 3000             var nameOfUnusedWell = unusedWellsJsonArr[i];
3573 05 Nov 15 olle 3001             if (wellName == nameOfUnusedWell)
3573 05 Nov 15 olle 3002             {
3573 05 Nov 15 olle 3003               usedWell = false;
3573 05 Nov 15 olle 3004             }
3573 05 Nov 15 olle 3005           }
3573 05 Nov 15 olle 3006           var effUsedWell = true;
3573 05 Nov 15 olle 3007           for (var i = 0; i < effUnusedWellsJsonArr.length; i++)
3573 05 Nov 15 olle 3008           {
3573 05 Nov 15 olle 3009             var nameOfUnusedWell = effUnusedWellsJsonArr[i];
3573 05 Nov 15 olle 3010             if (wellName == nameOfUnusedWell)
3573 05 Nov 15 olle 3011             {
3573 05 Nov 15 olle 3012               effUsedWell = false;
3573 05 Nov 15 olle 3013             }
3573 05 Nov 15 olle 3014           }
3573 05 Nov 15 olle 3015           var reservedWell = false;
3573 05 Nov 15 olle 3016           for (var i = 0; i < reservedWellsJsonArr.length; i++)
3573 05 Nov 15 olle 3017           {
3573 05 Nov 15 olle 3018             var nameOfReservedWell = reservedWellsJsonArr[i];
3573 05 Nov 15 olle 3019             if (wellName == nameOfReservedWell)
3573 05 Nov 15 olle 3020             {
3573 05 Nov 15 olle 3021               reservedWell = true;
3573 05 Nov 15 olle 3022             }
3573 05 Nov 15 olle 3023           }
3573 05 Nov 15 olle 3024           if (usedWell)
3573 05 Nov 15 olle 3025           {
3573 05 Nov 15 olle 3026             // Empty cell
3573 05 Nov 15 olle 3027             html += '<td class="kitwell empty col-'+colNo+'">';
3573 05 Nov 15 olle 3028           }
3573 05 Nov 15 olle 3029           else
3573 05 Nov 15 olle 3030           {
3573 05 Nov 15 olle 3031             // Unused cell
3573 05 Nov 15 olle 3032             //html += '<td class="kitwell unused col-'+colNo+'">';
3573 05 Nov 15 olle 3033             var new_html = '';
3573 05 Nov 15 olle 3034             if (effUsedWell)
3573 05 Nov 15 olle 3035             {
3573 05 Nov 15 olle 3036               new_html = '<td class="kitwell unused col-'+colNo+'">';
3573 05 Nov 15 olle 3037             }
3573 05 Nov 15 olle 3038             else
3573 05 Nov 15 olle 3039             {
3573 05 Nov 15 olle 3040               new_html = '<td class="kitwell effunused col-'+colNo+'">';
3573 05 Nov 15 olle 3041               if (reservedWell)
3573 05 Nov 15 olle 3042               {
3573 05 Nov 15 olle 3043                 new_html = '<td class="kitwell reserved col-'+colNo+'">';
3573 05 Nov 15 olle 3044               }
3573 05 Nov 15 olle 3045             }
3573 05 Nov 15 olle 3046             html += new_html;
3573 05 Nov 15 olle 3047           }
3573 05 Nov 15 olle 3048           html += '<div class="name">' + wellName + '</div>';
3573 05 Nov 15 olle 3049           html += '</td>';
3573 05 Nov 15 olle 3050         }
3573 05 Nov 15 olle 3051         wellNo++;
3573 05 Nov 15 olle 3052       }
3573 05 Nov 15 olle 3053       html += '</tr>';
3573 05 Nov 15 olle 3054     }
3573 05 Nov 15 olle 3055     html += '</table>';
3573 05 Nov 15 olle 3056     html += '</td>';
3573 05 Nov 15 olle 3057     // Kit status
3573 05 Nov 15 olle 3058     html += '<td class="status" id="libPrepKitAsPlate.status"></td>';
3573 05 Nov 15 olle 3059     // Kit message
3573 05 Nov 15 olle 3060     //var kitMessage = 'Highlighted cells are unused.';
3573 05 Nov 15 olle 3061     var kitMessage = '';
3573 05 Nov 15 olle 3062     html += '<td class="help">';
3573 05 Nov 15 olle 3063     html += '<span id="libPrepKitAsPlate.message" class="message" ></span>';
3573 05 Nov 15 olle 3064     html += kitMessage;
3573 05 Nov 15 olle 3065     html += '</td>';
3573 05 Nov 15 olle 3066     // End of table row with kit data
3573 05 Nov 15 olle 3067     html += '</tr>';
3573 05 Nov 15 olle 3068
3573 05 Nov 15 olle 3069     return html;
3573 05 Nov 15 olle 3070   }
3573 05 Nov 15 olle 3071
3449 28 Jul 15 olle 3072   return selectdna;
3449 28 Jul 15 olle 3073 }();
3449 28 Jul 15 olle 3074
3449 28 Jul 15 olle 3075 Doc.onLoad(SelectDna.initPage);
3449 28 Jul 15 olle 3076 Doc.addElementInitializer(SelectDna.initElements);
3449 28 Jul 15 olle 3077
3449 28 Jul 15 olle 3078
3449 28 Jul 15 olle 3079 var Dna = function()
3449 28 Jul 15 olle 3080 {
3449 28 Jul 15 olle 3081   var dna = {};
3449 28 Jul 15 olle 3082   var flagged = [];
3449 28 Jul 15 olle 3083   var info = [];
3449 28 Jul 15 olle 3084   
3449 28 Jul 15 olle 3085   /**
3449 28 Jul 15 olle 3086     Create a new DNA object by name. More information
3449 28 Jul 15 olle 3087     about the DNA is automatically loaded from the database.
3449 28 Jul 15 olle 3088   */
3449 28 Jul 15 olle 3089   dna.createByName = function(name)
3449 28 Jul 15 olle 3090   {
3449 28 Jul 15 olle 3091     var tmp = {};
3449 28 Jul 15 olle 3092     tmp.name = name;
3449 28 Jul 15 olle 3093     tmp.stratagene = Meludi.isStratagene(name)
3449 28 Jul 15 olle 3094     tmp.external = Meludi.isExternal(name);
3449 28 Jul 15 olle 3095     tmp.info = dna.infoByName(name);
3667 15 Dec 15 olle 3096 //alert("select_dna_for_start_plate.js::dna.createByName(name): name = " + name + " info = " + JSON.stringify(tmp.info));
3449 28 Jul 15 olle 3097     tmp.id = tmp.info.id;
3449 28 Jul 15 olle 3098     return tmp;
3449 28 Jul 15 olle 3099   }
3449 28 Jul 15 olle 3100   
3449 28 Jul 15 olle 3101   /**
3667 15 Dec 15 olle 3102     Create a new DNA object by parent name. More information
3667 15 Dec 15 olle 3103     about the DNA is automatically loaded from the database.
3667 15 Dec 15 olle 3104   */
3667 15 Dec 15 olle 3105   dna.createByParentName = function(parentName, name)
3667 15 Dec 15 olle 3106   {
3667 15 Dec 15 olle 3107     var tmp = {};
3667 15 Dec 15 olle 3108     tmp.name = name;
3667 15 Dec 15 olle 3109     tmp.stratagene = Meludi.isStratagene(parentName)
3667 15 Dec 15 olle 3110     tmp.external = Meludi.isExternal(parentName);
3667 15 Dec 15 olle 3111     var parentDna = dna.infoByName(parentName);
3667 15 Dec 15 olle 3112     // Copy some info to original info
3667 15 Dec 15 olle 3113     var info = {};
3667 15 Dec 15 olle 3114     info.origBioWell = parentDna.bioWell;
3667 15 Dec 15 olle 3115     info.origQubitConc = parentDna.QubitConc;
3667 15 Dec 15 olle 3116     info.origDeltaCt = parentDna.deltaCt;
3667 15 Dec 15 olle 3117     info.origId = parentDna.id;
3667 15 Dec 15 olle 3118     info.origName = parentDna.name;
3679 18 Dec 15 olle 3119     info.origDescription = parentDna.comment;
3667 15 Dec 15 olle 3120     // Reset info for created item
3667 15 Dec 15 olle 3121     info.bioWell = null;
3667 15 Dec 15 olle 3122     info.QubitConc = null;
3667 15 Dec 15 olle 3123     info.deltaCt = null;
3667 15 Dec 15 olle 3124     info.id = null;
3667 15 Dec 15 olle 3125     // Set tmp.info to new JSONObject info
3667 15 Dec 15 olle 3126     tmp.info = info;
3667 15 Dec 15 olle 3127     tmp.id = null;
3667 15 Dec 15 olle 3128     return tmp;
3667 15 Dec 15 olle 3129   }
3667 15 Dec 15 olle 3130   
3667 15 Dec 15 olle 3131   /**
3449 28 Jul 15 olle 3132     Create a new DNA object by info object.
3449 28 Jul 15 olle 3133   */
3449 28 Jul 15 olle 3134   dna.createByInfo = function(info)
3449 28 Jul 15 olle 3135   {
3449 28 Jul 15 olle 3136     var tmp = {};
3449 28 Jul 15 olle 3137     tmp.name = info.name;
3449 28 Jul 15 olle 3138     tmp.stratagene = Meludi.isStratagene(tmp.name);
3449 28 Jul 15 olle 3139     tmp.external = Meludi.isExternal(tmp.name);
3449 28 Jul 15 olle 3140     tmp.id = info.id;
3449 28 Jul 15 olle 3141     tmp.info = info;
3449 28 Jul 15 olle 3142     return tmp;
3449 28 Jul 15 olle 3143   }
3449 28 Jul 15 olle 3144   
3449 28 Jul 15 olle 3145   /**
3449 28 Jul 15 olle 3146     Get information about a DNA item with a given name.
3449 28 Jul 15 olle 3147   */
3449 28 Jul 15 olle 3148   dna.infoByName = function(name)
3449 28 Jul 15 olle 3149   {
3449 28 Jul 15 olle 3150     var key = 'N'+name;
3449 28 Jul 15 olle 3151     if (!info[key])
3449 28 Jul 15 olle 3152     {
3449 28 Jul 15 olle 3153       dna.loadInfoByNames([name]);
3449 28 Jul 15 olle 3154       if (!info[key]) info[key] = {};
3449 28 Jul 15 olle 3155     }
3449 28 Jul 15 olle 3156     return info[key];
3449 28 Jul 15 olle 3157   }
3449 28 Jul 15 olle 3158
3449 28 Jul 15 olle 3159   /**
3449 28 Jul 15 olle 3160     Load and cache DNA information for all DNA items with a name in the
3449 28 Jul 15 olle 3161     given list.
3449 28 Jul 15 olle 3162   */
3449 28 Jul 15 olle 3163   dna.loadInfoByNames = function(names)
3449 28 Jul 15 olle 3164   {
3449 28 Jul 15 olle 3165     var newNames = [];
3449 28 Jul 15 olle 3166     for (var i = 0; i < names.length; i++)
3449 28 Jul 15 olle 3167     {
3449 28 Jul 15 olle 3168       if (!info['N'+names[i]]) newNames[newNames.length] = names[i];
3449 28 Jul 15 olle 3169     }
3449 28 Jul 15 olle 3170     
3449 28 Jul 15 olle 3171     var submitInfo = {};
3449 28 Jul 15 olle 3172     submitInfo.names = newNames;
3449 28 Jul 15 olle 3173     
3449 28 Jul 15 olle 3174     if (newNames.length > 0)
3449 28 Jul 15 olle 3175     {
3449 28 Jul 15 olle 3176       var url = '../Dna.servlet?ID='+App.getSessionId();
3449 28 Jul 15 olle 3177       url += '&cmd=GetDnaInfoFromNames';  
3449 28 Jul 15 olle 3178       var response = Wizard.syncJsonRequest(url, 'POST', JSON.stringify(submitInfo));
3449 28 Jul 15 olle 3179       dna.cacheInfo(response.dna);
3449 28 Jul 15 olle 3180     }
3449 28 Jul 15 olle 3181   }
3449 28 Jul 15 olle 3182   
3449 28 Jul 15 olle 3183   dna.cacheInfo = function(dnaList)
3449 28 Jul 15 olle 3184   {
3449 28 Jul 15 olle 3185     for (var i = 0; i < dnaList.length; i++)
3449 28 Jul 15 olle 3186     {
3449 28 Jul 15 olle 3187       var r = dnaList[i];
3449 28 Jul 15 olle 3188       info['N'+r.name] = r;
3449 28 Jul 15 olle 3189       info['I'+r.id] = r;
3449 28 Jul 15 olle 3190       if (r.flag) flagged[flagged.length] = r;
3449 28 Jul 15 olle 3191     }
3449 28 Jul 15 olle 3192   }
3449 28 Jul 15 olle 3193
3449 28 Jul 15 olle 3194   dna.unflag = function(r)
3449 28 Jul 15 olle 3195   {
3449 28 Jul 15 olle 3196     if (!r.info || !r.info.flag) return false;
3449 28 Jul 15 olle 3197
3449 28 Jul 15 olle 3198     r.info.flag = null;
3449 28 Jul 15 olle 3199     for (var i = 0; i < flagged.length; i++)
3449 28 Jul 15 olle 3200     {
3449 28 Jul 15 olle 3201       if (r.id == flagged[i].id)
3449 28 Jul 15 olle 3202       {
3449 28 Jul 15 olle 3203         flagged.splice(i, 1);
3449 28 Jul 15 olle 3204         break;
3449 28 Jul 15 olle 3205       }
3449 28 Jul 15 olle 3206     }
3449 28 Jul 15 olle 3207     return true;
3449 28 Jul 15 olle 3208   }
3449 28 Jul 15 olle 3209   
3449 28 Jul 15 olle 3210   dna.flag = function(r, flag)
3449 28 Jul 15 olle 3211   {
3449 28 Jul 15 olle 3212     if (!r.info || r.info.flag) return false;
3449 28 Jul 15 olle 3213     r.info.flag = flag;
3449 28 Jul 15 olle 3214     flagged[flagged.length] = r.info;
3449 28 Jul 15 olle 3215   }
3449 28 Jul 15 olle 3216   
3449 28 Jul 15 olle 3217   dna.getFlagged = function()
3449 28 Jul 15 olle 3218   {
3449 28 Jul 15 olle 3219     return flagged;
3449 28 Jul 15 olle 3220   }
3449 28 Jul 15 olle 3221   
3449 28 Jul 15 olle 3222   return dna;
3449 28 Jul 15 olle 3223 }();
3449 28 Jul 15 olle 3224
3449 28 Jul 15 olle 3225
3449 28 Jul 15 olle 3226
3449 28 Jul 15 olle 3227 var WellPainter = function()
3449 28 Jul 15 olle 3228 {
3449 28 Jul 15 olle 3229   var painter = {};
3449 28 Jul 15 olle 3230   
3449 28 Jul 15 olle 3231   // Add class indicators for replicates and QC assigned wells
3449 28 Jul 15 olle 3232   painter.getClassNameForWell = function(well)
3449 28 Jul 15 olle 3233   {
3449 28 Jul 15 olle 3234     var cls = '';
3449 28 Jul 15 olle 3235     if (well.extract)
3449 28 Jul 15 olle 3236     {
3449 28 Jul 15 olle 3237       if (well.replicate) cls += ' replicate';
3449 28 Jul 15 olle 3238       if (well.extract.qc) cls += ' qc';
3449 28 Jul 15 olle 3239     }
3449 28 Jul 15 olle 3240     if (well.column == Plate.columns-1) cls += ' last-child';
3449 28 Jul 15 olle 3241     
3449 28 Jul 15 olle 3242     return cls;
3449 28 Jul 15 olle 3243   }
3449 28 Jul 15 olle 3244   
3449 28 Jul 15 olle 3245   painter.getWellText = function(well)
3449 28 Jul 15 olle 3246   {
3617 23 Nov 15 olle 3247     var frm = document.forms['meludi'];
3449 28 Jul 15 olle 3248     var text = '';
3449 28 Jul 15 olle 3249     if (well.duplicates)
3449 28 Jul 15 olle 3250     {
3449 28 Jul 15 olle 3251       well.setError('Duplicate DNA in this location');
3449 28 Jul 15 olle 3252       text += '<div class="name">'+Strings.encodeTags(well.duplicates.join(', '))+'</div>';
3449 28 Jul 15 olle 3253     }
3449 28 Jul 15 olle 3254     else if (well.extract)
3449 28 Jul 15 olle 3255     {
3449 28 Jul 15 olle 3256       // The well contains DNA
3449 28 Jul 15 olle 3257       var dna = well.extract;
3449 28 Jul 15 olle 3258       var info = dna.info;
3449 28 Jul 15 olle 3259       // --- DNA aliquot name
3449 28 Jul 15 olle 3260       text += '<div class="name">'+Strings.encodeTags(dna.name)+'</div>';
3667 15 Dec 15 olle 3261 //alert("select_dna_for_start_plate.js::getWellText(): dna.name = " + dna.name + " info = " + JSON.stringify(info));
3449 28 Jul 15 olle 3262       
3449 28 Jul 15 olle 3263       var warningMsg = [];
3449 28 Jul 15 olle 3264       // --- Bioplate location
3667 15 Dec 15 olle 3265       if (info.origBioWell)
3449 28 Jul 15 olle 3266       {
3667 15 Dec 15 olle 3267         var origDnaWell = info.origBioWell;
3667 15 Dec 15 olle 3268         text += '<div class="location">'+Strings.encodeTags(origDnaWell.bioPlate.name+'['+origDnaWell.location)+']</div>';
3449 28 Jul 15 olle 3269       }
3449 28 Jul 15 olle 3270       else if (info.preNormalized)
3449 28 Jul 15 olle 3271       {
3449 28 Jul 15 olle 3272         text += '<div class="location">PreNormalized</div>';
3449 28 Jul 15 olle 3273       }
3449 28 Jul 15 olle 3274       else if (!dna.stratagene && !dna.external)
3449 28 Jul 15 olle 3275       {
3615 20 Nov 15 olle 3276         if (!painter.hasClass('plate', 'hide-location'))
3615 20 Nov 15 olle 3277         {
3615 20 Nov 15 olle 3278           warningMsg[warningMsg.length] = 'No location';
3615 20 Nov 15 olle 3279         }
3449 28 Jul 15 olle 3280       }
3449 28 Jul 15 olle 3281
3667 15 Dec 15 olle 3282       if (info && info.origId && !dna.stratagene && !dna.external)
3449 28 Jul 15 olle 3283       {
3449 28 Jul 15 olle 3284         // Calculations for each aliquot
3667 15 Dec 15 olle 3285         var origDeltaCt = info.origDeltaCt;
3667 15 Dec 15 olle 3286         var dilutionFactor = painter.fetchDilutionFactor(origDeltaCt);
3590 11 Nov 15 olle 3287         var VOL_ALIQUOT = 10.0; // µl
3449 28 Jul 15 olle 3288         var volDNA = VOL_ALIQUOT/dilutionFactor;
3449 28 Jul 15 olle 3289         var water = VOL_ALIQUOT - volDNA;
3592 12 Nov 15 olle 3290         // Prepare for future modification of solution volume depending on other parameters
3592 12 Nov 15 olle 3291         var volAliquotSolution = VOL_ALIQUOT;
3590 11 Nov 15 olle 3292         var volDnaInSolution = volAliquotSolution/dilutionFactor;
3590 11 Nov 15 olle 3293         var waterInSolution = volAliquotSolution - volDnaInSolution;
3590 11 Nov 15 olle 3294         var removedVolume = 2 * volDnaInSolution; // µl
3667 15 Dec 15 olle 3295         var origConc = info.origQubitConc; // ng/µl
3667 15 Dec 15 olle 3296         var calcConc = origConc/dilutionFactor;
3449 28 Jul 15 olle 3297         //var usedQuantityPerAliquout = Math.ceil(VOL_ALIQUOT*origConc/dilutionFactor/1000); // µg
3449 28 Jul 15 olle 3298         //var usedQuantityPerAliquout = VOL_ALIQUOT*origConc/dilutionFactor/1000; // µg
3592 12 Nov 15 olle 3299         //var usedQuantity = volDNA*origConc; // ng
3590 11 Nov 15 olle 3300         var usedQuantity = volDnaInSolution*origConc; // ng
3449 28 Jul 15 olle 3301         dna.usedQuantity = dna.qc ? QUANTITY_QC : usedQuantity/1000; // µg
3449 28 Jul 15 olle 3302 //alert("select_dna.js::painter.getWellText(): name = " + dna.name + " removedVolume = " + removedVolume + " deltaCt = " + deltaCt + " dilutionFactor = " + dilutionFactor + " origConc = " + origConc + " usedQuantity = " + usedQuantity + " ng");
3449 28 Jul 15 olle 3303
3449 28 Jul 15 olle 3304 /*        
3449 28 Jul 15 olle 3305         dna.usedQuantity = dna.qc ? QUANTITY_QC : QUANTITY_REGULAR; // µg
3449 28 Jul 15 olle 3306         dna.dilutionConc = 1000 * dna.usedQuantity / TOTAL_VOLUME; // ng/µl
3449 28 Jul 15 olle 3307
3667 15 Dec 15 olle 3308         var volDNA = Math.ceil(10000*dna.usedQuantity/info.origQubitConc) / 10; // µl, rounded to 1 decimal
3449 28 Jul 15 olle 3309         var water = TOTAL_VOLUME - volDNA;
3449 28 Jul 15 olle 3310 */        
3449 28 Jul 15 olle 3311
3617 23 Nov 15 olle 3312         var MINIMAL_DNA_VOLUME = frm.min_vol_dna.value;
3682 04 Jan 16 olle 3313         if (volDnaInSolution < MINIMAL_DNA_VOLUME)
3449 28 Jul 15 olle 3314         {
3449 28 Jul 15 olle 3315 /*
3449 28 Jul 15 olle 3316           // Large mix since we do not want to take less than 1µl
3449 28 Jul 15 olle 3317           volDNA = MINIMAL_DNA_VOLUME;
3667 15 Dec 15 olle 3318           dna.usedQuantity = volDNA * info.origQubitConc / 1000; // µg
3449 28 Jul 15 olle 3319           var totalVolume = 1000 * dna.usedQuantity / dna.dilutionConc; // µl
3449 28 Jul 15 olle 3320           water = totalVolume - volDNA;
3449 28 Jul 15 olle 3321           warningMsg[warningMsg.length] = 'Large mix';
3449 28 Jul 15 olle 3322 */
3682 04 Jan 16 olle 3323           warningMsg[warningMsg.length] = 'DNA vol ' + Numbers.formatNumber(volDnaInSolution, 2) + 'µl < ' + MINIMAL_DNA_VOLUME + 'µl';
3449 28 Jul 15 olle 3324         }
3449 28 Jul 15 olle 3325
3590 11 Nov 15 olle 3326         // Store dilution data
3590 11 Nov 15 olle 3327         info.dilutionFactor = dilutionFactor;
3590 11 Nov 15 olle 3328         info.volAliquotSolution = volAliquotSolution;
3590 11 Nov 15 olle 3329         info.volDnaInSolution = volDnaInSolution;
3590 11 Nov 15 olle 3330         info.waterInSolution = waterInSolution;
3449 28 Jul 15 olle 3331 /*        
3449 28 Jul 15 olle 3332         if (info.remainingQuantity != null)
3449 28 Jul 15 olle 3333         {
3449 28 Jul 15 olle 3334           //text += '<div class="quantity">'+Numbers.formatNumber(info.remainingQuantity, 2) + 'µg</div>';
3449 28 Jul 15 olle 3335           var quantityLeft = 1000.0*info.remainingQuantity - 2*usedQuantity; // ng
3449 28 Jul 15 olle 3336 //alert("select_dna.js::painter.getWellText(): name = " + dna.name + " info.remainingQuantity = " + info.remainingQuantity + " µg usedQuantity = " + usedQuantity + " ng quantityLeft = " + quantityLeft + " ng");
3449 28 Jul 15 olle 3337           //text += '<div class="quantity">'+Numbers.formatNumber(quantityLeft, 2) + 'µg '+Numbers.formatNumber(volDNA, 1)+'µl</div>';
3449 28 Jul 15 olle 3338           text += '<div class="quantity">'+Numbers.formatNumber(usedQuantity, 2) + 'ng '+Numbers.formatNumber(volDNA, 1)+'µl</div>';
3449 28 Jul 15 olle 3339
3449 28 Jul 15 olle 3340           // Must have at least 1.1µg or 1.22µg (if default values are used)
3449 28 Jul 15 olle 3341           var remainLimit = dna.qc ? QUANTITY_QC : QUANTITY_REGULAR;
3449 28 Jul 15 olle 3342 */
3449 28 Jul 15 olle 3343 /*
3449 28 Jul 15 olle 3344           if (info.remainingQuantity < remainLimit)
3449 28 Jul 15 olle 3345           {
3449 28 Jul 15 olle 3346             well.setError('Not enough DNA');
3449 28 Jul 15 olle 3347           }
3449 28 Jul 15 olle 3348           // Warning if near the limit
3449 28 Jul 15 olle 3349           if (info.remainingQuantity < LOW_QUANTITY_WARNING_LIMIT && !info.preNormalized)
3449 28 Jul 15 olle 3350           {
3449 28 Jul 15 olle 3351             warningMsg[warningMsg.length] = 'Low quantity';
3449 28 Jul 15 olle 3352           }
3449 28 Jul 15 olle 3353 */
3449 28 Jul 15 olle 3354 /*
3449 28 Jul 15 olle 3355           if (quantityLeft < 1000.0*remainLimit)
3449 28 Jul 15 olle 3356           {
3449 28 Jul 15 olle 3357             well.setError('Not enough DNA');
3449 28 Jul 15 olle 3358           }
3449 28 Jul 15 olle 3359           // Warning if near the limit
3449 28 Jul 15 olle 3360           if (quantityLeft < 1000.0*LOW_QUANTITY_WARNING_LIMIT && !info.preNormalized)
3449 28 Jul 15 olle 3361           {
3449 28 Jul 15 olle 3362             warningMsg[warningMsg.length] = 'Low quantity';
3449 28 Jul 15 olle 3363           }
3449 28 Jul 15 olle 3364 */
3449 28 Jul 15 olle 3365 /*
3449 28 Jul 15 olle 3366         }
3449 28 Jul 15 olle 3367         else
3449 28 Jul 15 olle 3368         {
3449 28 Jul 15 olle 3369           warningMsg[warningMsg.length] = 'No quantity';
3449 28 Jul 15 olle 3370         }
3449 28 Jul 15 olle 3371 */
3449 28 Jul 15 olle 3372         // --- Used volume+water
3667 15 Dec 15 olle 3373         if (info.origQubitConc != null)
3449 28 Jul 15 olle 3374         {
3519 01 Oct 15 olle 3375           text += '<div class="volumes"><span class="volume">'+Numbers.formatNumber(volDNA, 2)+'</span> + <span class="water">'+Numbers.formatNumber(water, 2)+'µl</span></div>';
3449 28 Jul 15 olle 3376         }
3449 28 Jul 15 olle 3377         // --- ΔCt
3667 15 Dec 15 olle 3378         if (info.origDeltaCt != null)
3449 28 Jul 15 olle 3379         {
3667 15 Dec 15 olle 3380           text += '<div class="quality-score">ΔCt='+Numbers.formatNumber(info.origDeltaCt, 2) + '</div>';
3667 15 Dec 15 olle 3381           if (info.origDeltaCt > QUALITY_SCORE_WARNING_LIMIT)
3615 20 Nov 15 olle 3382           {
3615 20 Nov 15 olle 3383             if (!painter.hasClass('plate', 'hide-quality-score'))
3615 20 Nov 15 olle 3384             {
3615 20 Nov 15 olle 3385               warningMsg[warningMsg.length] = 'High ΔCt value';
3615 20 Nov 15 olle 3386             }
3615 20 Nov 15 olle 3387           }
3449 28 Jul 15 olle 3388         }
3449 28 Jul 15 olle 3389         else
3449 28 Jul 15 olle 3390         {
3615 20 Nov 15 olle 3391           if (!painter.hasClass('plate', 'hide-quality-score'))
3615 20 Nov 15 olle 3392           {
3615 20 Nov 15 olle 3393             warningMsg[warningMsg.length] = 'No ΔCt value';
3615 20 Nov 15 olle 3394           }
3449 28 Jul 15 olle 3395         }
3449 28 Jul 15 olle 3396         // --- QubitConc
3667 15 Dec 15 olle 3397         if (info.origQubitConc)
3449 28 Jul 15 olle 3398         {
3667 15 Dec 15 olle 3399           text += '<div class="origqubitconc">'+Numbers.formatNumber(info.origQubitConc, 2) + 'ng/µl (orig.)</div>';
3667 15 Dec 15 olle 3400           text += '<div class="calcqubitconc">'+Numbers.formatNumber(calcConc, 2) + 'ng/µl (calc.)</div>';
3449 28 Jul 15 olle 3401         }
3449 28 Jul 15 olle 3402         else
3449 28 Jul 15 olle 3403         {
3667 15 Dec 15 olle 3404           if (!painter.hasClass('plate', 'hide-origqubitconc'))
3615 20 Nov 15 olle 3405           {
3615 20 Nov 15 olle 3406             warningMsg[warningMsg.length] = 'No QubitConc value';
3615 20 Nov 15 olle 3407           }
3449 28 Jul 15 olle 3408         }
3449 28 Jul 15 olle 3409 /*
3449 28 Jul 15 olle 3410         if (info.QiacubeDate)
3449 28 Jul 15 olle 3411         {
3449 28 Jul 15 olle 3412           text += '<div class="qiacube-date">'+info.QiacubeDate+'</div>';
3449 28 Jul 15 olle 3413         }
3449 28 Jul 15 olle 3414         else if (info.DilutionDate)
3449 28 Jul 15 olle 3415         {
3449 28 Jul 15 olle 3416           text += '<div class="dilution-date">'+info.DilutionDate+'</div>';
3449 28 Jul 15 olle 3417         }
3449 28 Jul 15 olle 3418         else
3449 28 Jul 15 olle 3419         {
3449 28 Jul 15 olle 3420           warningMsg[warningMsg.length] = info.preNormalized ? 'No DilutionDate value' : 'No QiacubeDate value';
3449 28 Jul 15 olle 3421         }
3449 28 Jul 15 olle 3422 */
3449 28 Jul 15 olle 3423         if (info.AutoProcessing)
3449 28 Jul 15 olle 3424         {
3449 28 Jul 15 olle 3425           warningMsg[warningMsg.length] = info.AutoProcessing;
3449 28 Jul 15 olle 3426         }
3449 28 Jul 15 olle 3427 /*
3449 28 Jul 15 olle 3428         dna.usedQuantity = dna.qc ? QUANTITY_QC : QUANTITY_REGULAR; // µg
3449 28 Jul 15 olle 3429         dna.dilutionConc = 1000 * dna.usedQuantity / TOTAL_VOLUME; // ng/µl
3449 28 Jul 15 olle 3430
3667 15 Dec 15 olle 3431         var volDNA = Math.ceil(10000*dna.usedQuantity/info.origQubitConc) / 10; // µl, rounded to 1 decimal
3449 28 Jul 15 olle 3432         var water = TOTAL_VOLUME - volDNA;
3449 28 Jul 15 olle 3433         
3449 28 Jul 15 olle 3434         if (volDNA < MINIMAL_DNA_VOLUME)
3449 28 Jul 15 olle 3435         {
3449 28 Jul 15 olle 3436           // Large mix since we do not want to take less than 1µl
3449 28 Jul 15 olle 3437           volDNA = MINIMAL_DNA_VOLUME;
3667 15 Dec 15 olle 3438           dna.usedQuantity = volDNA * info.origQubitConc / 1000; // µg
3449 28 Jul 15 olle 3439           var totalVolume = 1000 * dna.usedQuantity / dna.dilutionConc; // µl
3449 28 Jul 15 olle 3440           water = totalVolume - volDNA;
3449 28 Jul 15 olle 3441           warningMsg[warningMsg.length] = 'Large mix';
3449 28 Jul 15 olle 3442         }
3449 28 Jul 15 olle 3443         
3449 28 Jul 15 olle 3444         if (info.remainingQuantity)
3449 28 Jul 15 olle 3445         {
3449 28 Jul 15 olle 3446           //text += '<div class="quantity">'+Numbers.formatNumber(info.remainingQuantity, 2) + 'µg</div>';
3449 28 Jul 15 olle 3447           text += '<div class="quantity">'+Numbers.formatNumber(info.remainingQuantity, 2) + 'µg '+Numbers.formatNumber(volDNA, 1)+'µl</div>';
3449 28 Jul 15 olle 3448           // Must have at least 1.1µg or 1.22µg (if default values are used)
3449 28 Jul 15 olle 3449           var remainLimit = dna.qc ? QUANTITY_QC : QUANTITY_REGULAR;
3449 28 Jul 15 olle 3450           if (info.remainingQuantity < remainLimit)
3449 28 Jul 15 olle 3451           {
3449 28 Jul 15 olle 3452             well.setError('Not enough DNA');
3449 28 Jul 15 olle 3453           }
3449 28 Jul 15 olle 3454           // Warning if near the limit
3449 28 Jul 15 olle 3455           if (info.remainingQuantity < LOW_QUANTITY_WARNING_LIMIT && !info.preNormalized)
3449 28 Jul 15 olle 3456           {
3449 28 Jul 15 olle 3457             warningMsg[warningMsg.length] = 'Low quantity';
3449 28 Jul 15 olle 3458           }
3449 28 Jul 15 olle 3459         }
3449 28 Jul 15 olle 3460         else
3449 28 Jul 15 olle 3461         {
3449 28 Jul 15 olle 3462           warningMsg[warningMsg.length] = 'No quantity';
3449 28 Jul 15 olle 3463         }
3449 28 Jul 15 olle 3464         if (info.deltaCt)
3449 28 Jul 15 olle 3465         {
3449 28 Jul 15 olle 3466           text += '<div class="quality-score">ΔCt='+Numbers.formatNumber(info.deltaCt, 1) + '</div>';
3449 28 Jul 15 olle 3467           if (info.deltaCt > QUALITY_SCORE_WARNING_LIMIT) warningMsg[warningMsg.length] = 'High ΔCt value';
3449 28 Jul 15 olle 3468         }
3449 28 Jul 15 olle 3469         else
3449 28 Jul 15 olle 3470         {
3449 28 Jul 15 olle 3471           warningMsg[warningMsg.length] = 'No ΔCt value';
3449 28 Jul 15 olle 3472         }
3667 15 Dec 15 olle 3473         if (info.origQubitConc)
3449 28 Jul 15 olle 3474         {
3667 15 Dec 15 olle 3475           text += '<div class="origqubitconc">'+Numbers.formatNumber(info.origQubitConc, 2) + 'ng/µl</div>';
3449 28 Jul 15 olle 3476           text += '<div class="volumes"><span class="volume">'+Numbers.formatNumber(volDNA, 1)+'</span> + <span class="water">'+Numbers.formatNumber(water, 1)+'µl</span></div>';
3449 28 Jul 15 olle 3477         }
3449 28 Jul 15 olle 3478         else
3449 28 Jul 15 olle 3479         {
3449 28 Jul 15 olle 3480           warningMsg[warningMsg.length] = 'No QubitConc value';
3449 28 Jul 15 olle 3481         }
3449 28 Jul 15 olle 3482         if (info.QiacubeDate)
3449 28 Jul 15 olle 3483         {
3449 28 Jul 15 olle 3484           text += '<div class="qiacube-date">'+info.QiacubeDate+'</div>';
3449 28 Jul 15 olle 3485         }
3449 28 Jul 15 olle 3486         else if (info.DilutionDate)
3449 28 Jul 15 olle 3487         {
3449 28 Jul 15 olle 3488           text += '<div class="dilution-date">'+info.DilutionDate+'</div>';
3449 28 Jul 15 olle 3489         }
3449 28 Jul 15 olle 3490         else
3449 28 Jul 15 olle 3491         {
3449 28 Jul 15 olle 3492           warningMsg[warningMsg.length] = info.preNormalized ? 'No DilutionDate value' : 'No QiacubeDate value';
3449 28 Jul 15 olle 3493         }
3449 28 Jul 15 olle 3494         if (info.AutoProcessing)
3449 28 Jul 15 olle 3495         {
3449 28 Jul 15 olle 3496           warningMsg[warningMsg.length] = info.AutoProcessing;
3449 28 Jul 15 olle 3497         }
3449 28 Jul 15 olle 3498 */
3449 28 Jul 15 olle 3499       }
3667 15 Dec 15 olle 3500       else if (!dna.origId)
3449 28 Jul 15 olle 3501       {
3449 28 Jul 15 olle 3502         well.setError('DNA not found');
3449 28 Jul 15 olle 3503       }
3449 28 Jul 15 olle 3504       if (dna.comment)
3449 28 Jul 15 olle 3505       {
3449 28 Jul 15 olle 3506         text += '<div class="comment">'+Strings.encodeTags(dna.comment)+'</div>';
3449 28 Jul 15 olle 3507       }
3449 28 Jul 15 olle 3508       if (info && info.comment)
3449 28 Jul 15 olle 3509       {
3449 28 Jul 15 olle 3510         text += '<div class="comment">'+Strings.encodeTags(info.comment)+'</div>';
3449 28 Jul 15 olle 3511       }
3449 28 Jul 15 olle 3512       if (warningMsg.length > 0)
3449 28 Jul 15 olle 3513       {
3449 28 Jul 15 olle 3514         well.setWarning(warningMsg.join('; '));
3449 28 Jul 15 olle 3515       }
3614 20 Nov 15 olle 3516       // Index 1 & 2 primers
3614 20 Nov 15 olle 3517       var row = well.row + 1;
3614 20 Nov 15 olle 3518       var column = well.column + 1;
3614 20 Nov 15 olle 3519       var index2 = 'A50' + row;
3614 20 Nov 15 olle 3520       var index1 = 'A70' + column;
3614 20 Nov 15 olle 3521       if (column > 9)
3614 20 Nov 15 olle 3522       {
3614 20 Nov 15 olle 3523         index1 = 'A7' + column;
3614 20 Nov 15 olle 3524       }
3614 20 Nov 15 olle 3525       text += '<div class="indexprimer">'+index2+'</div>';
3614 20 Nov 15 olle 3526       text += '<div class="indexprimer">'+index1+'</div>';
3449 28 Jul 15 olle 3527     }
3449 28 Jul 15 olle 3528     else if (well.copyText)
3449 28 Jul 15 olle 3529     {
3449 28 Jul 15 olle 3530       text = '<div class="copy-text">'+well.copyText+'</div>';
3449 28 Jul 15 olle 3531     }
3449 28 Jul 15 olle 3532     else
3449 28 Jul 15 olle 3533     {
3449 28 Jul 15 olle 3534       text = 'empty';
3449 28 Jul 15 olle 3535     }
3449 28 Jul 15 olle 3536     if (well.duplicate)
3449 28 Jul 15 olle 3537     {
3449 28 Jul 15 olle 3538       well.setError('Duplicate barcode');
3449 28 Jul 15 olle 3539     }
3449 28 Jul 15 olle 3540
3449 28 Jul 15 olle 3541     var bc = Doc.element('barcode.'+well.row+'.'+well.column);
3449 28 Jul 15 olle 3542     if (bc)
3449 28 Jul 15 olle 3543     {
3449 28 Jul 15 olle 3544       var cls = 'barcode-well'
3449 28 Jul 15 olle 3545       cls += well.column == 0 ? ' barcode-left' : ' barcode-right';
3449 28 Jul 15 olle 3546
3449 28 Jul 15 olle 3547       if (well.barcode)
3449 28 Jul 15 olle 3548       {
3449 28 Jul 15 olle 3549         bc.innerHTML = well.barcode.name;
3449 28 Jul 15 olle 3550         var indexSet = painter.barcodeVariant ? painter.barcodeVariant.indexSets[well.column] : null;
3449 28 Jul 15 olle 3551         if (indexSet)
3449 28 Jul 15 olle 3552         {
3449 28 Jul 15 olle 3553           cls += ' ' + indexSet.color;
3449 28 Jul 15 olle 3554         }
3449 28 Jul 15 olle 3555         if (well.defaultBarcode && well.barcode != well.defaultBarcode)
3449 28 Jul 15 olle 3556         {
3449 28 Jul 15 olle 3557           cls += ' bg-modified';
3449 28 Jul 15 olle 3558         }
3449 28 Jul 15 olle 3559         if (well.duplicate)
3449 28 Jul 15 olle 3560         {
3449 28 Jul 15 olle 3561           cls += ' duplicate';
3449 28 Jul 15 olle 3562         }
3449 28 Jul 15 olle 3563       }
3449 28 Jul 15 olle 3564       bc.className = cls;
3449 28 Jul 15 olle 3565     }
3449 28 Jul 15 olle 3566     return text;
3449 28 Jul 15 olle 3567   }
3449 28 Jul 15 olle 3568
3615 20 Nov 15 olle 3569   /**
3615 20 Nov 15 olle 3570    * Returns `true` if HTML element with id 'elementId' has
3615 20 Nov 15 olle 3571    * class 'cls', else `false`.
3615 20 Nov 15 olle 3572    */
3615 20 Nov 15 olle 3573   painter.hasClass = function(elementId, cls)
3615 20 Nov 15 olle 3574   {
3615 20 Nov 15 olle 3575     var element = document.getElementById(elementId);
3615 20 Nov 15 olle 3576     return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
3615 20 Nov 15 olle 3577   }
3615 20 Nov 15 olle 3578
3449 28 Jul 15 olle 3579   painter.fetchDilutionFactor = function(deltaCt)
3449 28 Jul 15 olle 3580   {
3449 28 Jul 15 olle 3581     var dilutionFactor = 1.0;
3519 01 Oct 15 olle 3582 /*
3519 01 Oct 15 olle 3583     // Illumina ladder dilution chart
3449 28 Jul 15 olle 3584     if (deltaCt > 0.5 && deltaCt <= 1.5)
3449 28 Jul 15 olle 3585     {
3449 28 Jul 15 olle 3586       dilutionFactor = 2.0;
3449 28 Jul 15 olle 3587     }
3449 28 Jul 15 olle 3588     if (deltaCt > -0.5 && deltaCt <= 0.5)
3449 28 Jul 15 olle 3589     {
3449 28 Jul 15 olle 3590       dilutionFactor = 4.0;
3449 28 Jul 15 olle 3591     }
3449 28 Jul 15 olle 3592     if (deltaCt > -1.5 && deltaCt <= -0.5)
3449 28 Jul 15 olle 3593     {
3449 28 Jul 15 olle 3594       dilutionFactor = 8.0;
3449 28 Jul 15 olle 3595     }
3449 28 Jul 15 olle 3596     if (deltaCt <=- 1.5)
3449 28 Jul 15 olle 3597     {
3449 28 Jul 15 olle 3598       dilutionFactor = 16.0;
3449 28 Jul 15 olle 3599     }
3519 01 Oct 15 olle 3600 */
3519 01 Oct 15 olle 3601     // Dilution curve fitted to centers of ladder steps in Illumina ladder dilution chart (Mats Jönsson 2015-09-28)
3519 01 Oct 15 olle 3602     var fact = 2.8284271247;
3519 01 Oct 15 olle 3603     var expFact = 0.6931471806;
3519 01 Oct 15 olle 3604     dilutionFactor = fact * Math.exp(-expFact*deltaCt);
3592 12 Nov 15 olle 3605     // Apply cut-offs restricting the dilution factor to [1.0, 16.0]
3519 01 Oct 15 olle 3606     if (dilutionFactor < 1.0)
3519 01 Oct 15 olle 3607     {
3519 01 Oct 15 olle 3608       dilutionFactor = 1.0;
3519 01 Oct 15 olle 3609     }
3592 12 Nov 15 olle 3610     if (dilutionFactor > 16.0)
3592 12 Nov 15 olle 3611     {
3592 12 Nov 15 olle 3612       dilutionFactor = 16.0;
3592 12 Nov 15 olle 3613     }
3449 28 Jul 15 olle 3614     return dilutionFactor;
3449 28 Jul 15 olle 3615   }
3449 28 Jul 15 olle 3616   
3449 28 Jul 15 olle 3617   return painter;
3449 28 Jul 15 olle 3618 }();