Changeset 6312


Ignore:
Timestamp:
Aug 28, 2013, 1:48:06 PM (9 years ago)
Author:
Nicklas Nordborg
Message:

References #1729 and #1730. Edit dialogs for the Biomaterial and Array LIMS.

Location:
trunk/www
Files:
2 added
28 edited

Legend:

Unmodified
Added
Removed
  • trunk/www/biomaterials/extracts/edit_extract.jsp

    r6297 r6312  
    6464  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
    6565  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     66  import="net.sf.basedb.util.json.JsonUtil"
     67  import="net.sf.basedb.util.json.JsonConverter"
     68  import="net.sf.basedb.util.json.NameableConverter"
     69  import="org.json.simple.JSONObject"
     70  import="org.json.simple.JSONArray"
    6671  import="java.util.List"
    6772  import="java.util.Set"
     
    276281  subtypesQuery.include(Include.ALL);
    277282
    278  
     283  JSONObject jsonBioWell = null;
     284  if (currentBioWell != null)
     285  {
     286    jsonBioWell = new JSONObject();
     287    jsonBioWell.put("id", currentBioWell.getId());
     288    jsonBioWell.put("location", currentBioWell.getCoordinate());
     289  }
     290
     291  JSONObject jsonExtracts = new JSONObject();
     292  jsonExtracts.put("itemType", "EXTRACTS");
     293  if (extractsQuery != null)
     294  {
     295    final BioMaterialEvent event = creationEvent;
     296    jsonExtracts.put("items", JsonUtil.toArray(extractsQuery.iterate(dc), new NameableConverter<Extract>()
     297    {
     298      protected void setMore(JSONObject json, Extract e)
     299      {
     300        Float usedQuantity = event == null ? null : event.getUsedQuantity(e);
     301        json.put("name", e.getName() + (usedQuantity == null ? " [-]" : " [" +  usedQuantity + " µg]"));
     302        json.put("value", usedQuantity);
     303      }
     304    }));
     305  }
    279306 
    280307  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
     
    285312  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    286313  %>
    287   <base:page type="popup" title="<%=title%>">
    288   <base:head scripts="tabcontrol.js,linkitems.js,subtypes.js" styles="tabcontrol.css">
     314  <base:page type="popup" title="<%=title%>" id="edit-page">
     315  <base:head scripts="tabcontrol-2.js,linkitems-2.js,subtypes.js,~extracts.js" styles="tabcontrol.css">
    289316    <ext:scripts context="<%=jspContext%>" />
    290317    <ext:stylesheets context="<%=jspContext%>" />
    291     <script>
    292     // Validate the "Extract" tab
    293     function validateExtract()
    294     {
    295       var frm = document.forms['extract'];
    296       if (Main.trimString(frm.name.value) == '')
    297       {
    298         Forms.showNotification(frm.name, 'You must enter a name');
    299         return false;
    300       }
    301       if (Main.trimString(frm.bioplate_id.value) != 0 && Main.trimString(frm.biowell_id.value) == 0)
    302       {
    303         Forms.showNotification('biowell_id.select', 'You must choose a biowell from the bioplate');
    304         return false;
    305       }
    306       return true;
    307     }
    308 
    309     // Submit the form
    310     function saveSettings()
    311     {
    312       var frm = document.forms['extract'];
    313       if (TabControl.validateActiveTab('settings'))
    314       {
    315         Annotations.saveModifiedAnnotationsToForm(frm);
    316         Annotations.saveInheritedAnnotationsToForm(frm);
    317         frm.modifiedExtracts.value = Link.exportModified(frm, 'E', true).join(',');
    318         frm.removedExtracts.value = Link.getActionIds(-1, 'E').join(',');
    319         frm.submit();
    320       }
    321     }
    322  
    323     function loadAnnotationsFrame()
    324     {
    325       Annotations.autoLoadEditFrame(getProtocolId(), ItemSubtype.getSubtypeId('subtype_id'));
    326     }
    327    
    328     function loadInheritedAnnotationsFrame()
    329     {
    330       Annotations.autoLoadInheritFrame(getParents());
    331     }
    332    
    333     function getProtocolId()
    334     {
    335       var frm = document.forms['extract'];
    336       var protocolId = 0;
    337       if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
    338       {
    339         protocolId = Math.abs(parseInt(frm.protocol_id[frm.protocol_id.selectedIndex].value));       
    340       }
    341       return protocolId;
    342     }
    343 
    344     function getParents()
    345     {
    346       var frm = document.forms['extract'];
    347       var parents = new Array();
    348       if (frm.parentType[0].checked)
    349       {
    350         var sampleId = Math.abs(parseInt(frm.sample_id[frm.sample_id.selectedIndex].value));
    351         if (sampleId > 0) parents[parents.length] = 'SAMPLE:'+sampleId;
    352       }
    353       else
    354       {
    355         var ids = Link.getListIds(frm.extracts, 'E');
    356         if (ids.length > 0)
    357         {
    358           parents[parents.length] = 'EXTRACT:'+ids.join(':');
    359         }
    360       }
    361       return parents;
    362     }
    363    
    364     function subtypeOnChange()
    365     {
    366       var frm = document.forms['extract'];
    367       var subtypeId = ItemSubtype.getSubtypeId('subtype_id');
    368       var recentInfo = ItemSubtype.getRelatedProjectDefaultAndRecentItems('EXTRACT', subtypeId, ['PROTOCOL', 'BIOPLATE', 'TAG', 'SAMPLE', 'EXTRACT']);
    369       ItemSubtype.updateSelectionList(frm.protocol_id, recentInfo.PROTOCOL['recent'], recentInfo.PROTOCOL['default']);
    370       ItemSubtype.updateSelectionList(frm.tag_id, recentInfo.TAG['recent']);
    371       ItemSubtype.updateSelectionList(frm.bioplate_id, recentInfo.BIOPLATE['recent']);
    372     }
    373    
    374     function selectProtocolOnClick()
    375     {
    376       var frm = document.forms['extract'];
    377       var url = '../../admin/protocols/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    378       url += '&callback=setProtocolCallback&resetTemporary=1';
    379       url += ItemSubtype.createRelatedFilter('subtype_id', 'PROTOCOL', <%=SystemItems.getId(Protocol.EXTRACTION)%>);
    380       if (frm.protocol_id.length > 1)
    381       {
    382         var id = Math.abs(parseInt(frm.protocol_id[1].value));       
    383         url += '&item_id='+id;
    384       }
    385       Main.openPopup(url, 'SelectProtocol', 1050, 700);
    386     }
    387     function setProtocolCallback(id, name)
    388     {
    389       var frm = document.forms['extract'];
    390       var list = frm.protocol_id;
    391       if (list.length < 2 || list[1].value == '0') // >
    392       {
    393         Forms.addListOption(list, 1, new Option());
    394       }
    395       list[1].value = id;
    396       list[1].text = name;
    397       list.selectedIndex = 1;
    398     }
    399     function selectTagOnClick()
    400     {
    401       var frm = document.forms['extract'];
    402       var url = '../tags/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    403       url += '&callback=setTagCallback&resetTemporary=1';
    404       url += ItemSubtype.createRelatedFilter('subtype_id', 'TAG');
    405       if (frm.tag_id.length > 1)
    406       {
    407         var id = Math.abs(parseInt(frm.tag_id[1].value));       
    408         url += '&item_id='+id;
    409       }
    410       Main.openPopup(url, 'SelectTag', 1050, 700);
    411     }
    412     function setTagCallback(id, name)
    413     {
    414       var frm = document.forms['extract'];
    415       var list = frm.tag_id;
    416       if (list.length < 2 || list[1].value == '0') // >
    417       {
    418         Forms.addListOption(list, 1, new Option());
    419       }
    420       list[1].value = id;
    421       list[1].text = name;
    422       list.selectedIndex = 1;
    423     }
    424     function selectBioPlateOnClick()
    425     {
    426       var frm = document.forms['extract'];
    427       var url = '../bioplates/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setBioPlateCallback';
    428       if (frm.bioplate_id.length > 1)
    429       {
    430         var id = Math.abs(parseInt(frm.bioplate_id[1].value));       
    431         url += '&item_id='+id;
    432       }
    433       url += '&resetTemporary=1&tmpfilter:INT:bioPlateType.lockMode=<><%=BioWell.LockMode.LOCKED_AFTER_CREATE.getValue()%>';
    434       // Restrict to plates that can holds extracts
    435       url += '&tmpfilter:INT:bioPlateType.bioMaterialType=|<%=itemType.getValue()%>';
    436       var subtypeId = ItemSubtype.getSubtypeId('subtype_id');
    437       // Restrict to plates with the given subtype
    438       url += '&tmpfilter:INT:bioPlateType.itemSubtype='+(subtypeId ? '|' + subtypeId : '=');
    439       url += '&tmpfilter:BOOLEAN:destroyed=false';
    440       Main.openPopup(url, 'SelectBioplate', 1050, 700);
    441     }
    442     function setBioPlateCallback(id, name)
    443     {
    444       var frm = document.forms['extract'];
    445       var list = frm.bioplate_id;
    446       if (list.length < 2 || list[1].value == '0') // >
    447       {
    448         Forms.addListOption(list, 1, new Option());
    449       }
    450       list[1].value = id;
    451       list[1].text = name;
    452       list.selectedIndex = 1;
    453       frm.biowell_id.remove(1);
    454       frm.biowell_id.disabled = false;
    455     }
    456     function bioPlateOnChange()
    457     {
    458       var frm = document.forms['extract'];
    459       var list = frm.bioplate_id;
    460       frm.biowell_id.selectedIndex=0;
    461       frm.biowell_id.remove(1);     
    462     }
    463 
    464     function initBioWell()
    465     {
    466       var frm = document.forms['extract'];
    467       <%
    468       if (currentBioWell != null)
    469       {
    470         %>
    471         var list = frm.biowell_id;
    472         var wellId = <%=currentBioWell.getId()%>;
    473         Forms.addListOption(list, 1, new Option());
    474         list[1].value = '<%=currentBioWell.getId()*(extract == null ? 1 : -1)%>';
    475         list[1].text = '<%=rowFormatter.format(currentBioWell.getRow())%><%=columnFormatter.format(currentBioWell.getColumn())%>';
    476         list.selectedIndex = 1;
    477       <%
    478       }
    479       %>
    480     }         
    481     function selectBioWellOnClick()
    482     {
    483       var frm = document.forms['extract'];
    484       var bioplate_list = frm.bioplate_id;     
    485       var bioplateId = Math.abs(parseInt(bioplate_list[bioplate_list.selectedIndex].value))
    486       if (Main.trimString(frm.bioplate_id.value) == 0)
    487       {
    488         Forms.showNotification('bioplate_id.select', 'You must first select a bioplate', null, 'pointer-below');
    489         return;
    490       }     
    491        
    492       var url = '../bioplates/wells/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setBioWellCallback';
    493       if (frm.biowell_id.length > 1)
    494       {
    495         var id = Math.abs(parseInt(frm.biowell_id[1].value));       
    496         url += '&item_id='+id;
    497       }
    498       url += '&bioplate_id='+bioplateId;
    499       url += '&resetTemporary=1&tmpfilter:STRING:$mbm.name='+escape('=');
    500       url += '&tmpfilter:STRING:originalBioMaterial.name='+escape('=');
    501       url += '&columns=row,column';
    502       Main.openPopup(url, 'SelectBiowell', 750, 500);
    503     }
    504     function setBioWellCallback(id, name)
    505     {
    506       var frm = document.forms['extract'];
    507       var list = frm.biowell_id;
    508       if (list.length < 2 || list[1].value == '0') // >
    509       {
    510         Forms.addListOption(list, 1, new Option());
    511       }
    512       list[1].value = id;
    513       list[1].text = name;
    514       list.selectedIndex = 1;
    515     }
    516    
    517     function parentTypeOnClick()
    518     {
    519       var frm = document.forms['extract'];
    520       var useExtracts = frm.parentType[1].checked;
    521       frm.sample_id.disabled = useExtracts;
    522       frm.used_from_sample.disabled = useExtracts;
    523       frm.extracts.disabled = !useExtracts;
    524       frm.used_quantity.disabled = !useExtracts;
    525     }
    526    
    527     function selectSampleOnClick()
    528     {
    529       var frm = document.forms['extract'];
    530       var url = '../samples/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    531       url += '&callback=setSampleCallback&resetTemporary=1';
    532       url += ItemSubtype.createRelatedFilter('subtype_id', 'SAMPLE');
    533       if (frm.sample_id.length > 1)
    534       {
    535         var id = Math.abs(parseInt(frm.sample_id[1].value));       
    536         url += '&item_id='+id;
    537       }
    538       Main.openPopup(url, 'SelectSample', 1050, 700);
    539     }
    540     function setSampleCallback(id, name)
    541     {
    542       var frm = document.forms['extract'];
    543       var list = frm.sample_id;
    544       if (list.length < 2 || list[1].value == '0') // >
    545       {
    546         Forms.addListOption(list, 1, new Option());
    547       }
    548       list[1].value = id;
    549       list[1].text = name;
    550       list.selectedIndex = 1;
    551       frm.parentType[0].checked = true;
    552       frm.parentType[1].checked = false;
    553       parentTypeOnClick();
    554     }
    555    
    556     function addExtractsOnClick()
    557     {
    558       var frm = document.forms['extract'];
    559       var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
    560       url += '&callback=addExtractCallback&resetTemporary=1';
    561       url += ItemSubtype.createRelatedFilter('subtype_id', 'EXTRACT');
    562       Main.openPopup(url, 'AddExtracts', 1050, 700);
    563     }
    564    
    565     function addExtractCallback(extractId, name)
    566     {
    567       var frm = document.forms['extract'];
    568       var item = Link.getItem('E', extractId);
    569       if (!item) item = new Item('E', extractId, name+' [-]', '', '');
    570       Link.addItem(frm.extracts, item);
    571       frm.parentType[0].checked = false;
    572       frm.parentType[1].checked = true;
    573       parentTypeOnClick();
    574     }
    575     function extractsOnChange()
    576     {
    577       var frm = document.forms['extract'];
    578       var item = frm.extracts[frm.extracts.selectedIndex].item;
    579       if (item && item.id)
    580       {
    581         frm.used_quantity.value = item.value;
    582         frm.used_quantity.focus();
    583       }
    584       else
    585       {
    586         frm.used_quantity.value = '';
    587       }
    588     }
    589     function usedQuantityOnBlur()
    590     {
    591       var frm = document.forms['extract'];
    592       var usedQuantity = frm.used_quantity.value;
    593       var displayQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
    594       for (var i = 0; i < frm.extracts.length; i++) // >
    595       {
    596         var option = frm.extracts[i];
    597         if (option.selected && option.item.id)
    598         {
    599           option.item.value = usedQuantity;
    600           var text = option.text.replace(/\[.*\]/, '['+displayQuantity+']');
    601           option.text = text;
    602         }
    603       }
    604     }
    605     function usedFromSampleOnBlur()
    606     {
    607       var frm = document.forms['extract'];
    608      
    609       var sampleId = parseInt(frm.sample_id[frm.sample_id.selectedIndex].value);
    610       if (sampleId < 0)
    611       {
    612         frm.sample_id[frm.sample_id.selectedIndex].value = -sampleId;
    613       }
    614     }
    615    
    616 
    617     function removeOnClick()
    618     {
    619       Link.removeSelected(document.forms['extract'].extracts);
    620     }
    621 
    622     function init()
    623     {
    624       <%
    625       if (extract == null)
    626       {
    627         %>
    628         var frm = document.forms['extract'];
    629         frm.name.focus();
    630         frm.name.select();
    631         <%
    632       }
    633       %>
    634       initBioWell();     
    635       initExtracts();
    636       parentTypeOnClick();
    637     }
    638     function initExtracts()
    639     {
    640       var extracts = document.forms['extract'].extracts;
    641       <%
    642       if (extractsQuery != null)
    643       {
    644         extractsQuery.include(Include.ALL);
    645         extractsQuery.order(Orders.asc(Hql.property("name")));
    646         ItemResultList<Extract> extracts = extractsQuery.list(dc);
    647         for (Extract e : extracts)
    648         {
    649           if (extract != null)
    650           {
    651             String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(e), -1);
    652             %>
    653             Link.addNewItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
    654             <%
    655           }
    656           else
    657           {
    658             %>
    659             Link.addItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [-]', '', ''));
    660             <%
    661            
    662           }
    663         }
    664       }
    665       %>
    666     }
    667     </script>
    668318  </base:head>
    669   <base:body onload="init()">
     319  <base:body>
    670320    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    671321    <form action="index.jsp?ID=<%=ID%>" method="post" name="extract">
    672322    <input type="hidden" name="cmd" value="UpdateItem">
    673323
     324    <div id="page-data" class="datacontainer"
     325      data-extraction-protocoltype-id="<%=SystemItems.getId(Protocol.EXTRACTION)%>"
     326      data-sample-type="<%=Item.EXTRACT.getValue()%>"
     327      <%
     328      if (jsonBioWell != null)
     329      {
     330        %>
     331        data-biowell="<%=HTML.encodeTags(jsonBioWell.toJSONString()) %>"
     332        <%
     333      }
     334      %>
     335    ></div>
     336
    674337    <t:tabcontrol id="settings"
    675338      subclass="content dialogtabcontrol"
    676       position="bottom"  remember="<%=extract != null%>"
     339      position="bottom" remember="<%=extract != null%>"
    677340      extensions="<%=invoker%>">
    678     <t:tab id="info" title="Extract" validate="validateExtract()" helpid="extract.edit">
     341    <t:tab id="info" title="Extract" helpid="extract.edit">
    679342      <table class="fullform input100">
    680343      <tr>
    681344        <th>Name</th>
    682         <td><input class="text required" type="text" name="name"
     345        <td><input class="text required auto-init"
     346          data-auto-init="<%=extract == null ? "focus-select" : "focus" %>" type="text" name="name"
    683347          value="<%=HTML.encodeTags(name)%>"
    684348          maxlength="<%=Extract.MAX_NAME_LENGTH%>"></td>
     
    689353        <td>
    690354          <select name="subtype_id" id="subtype_id"
    691             <%=!readCurrentSubtype ? "disabled readonly class=\"disabled selectionlist\"" : "class=\"selectionlist\""%>
    692             onchange="subtypeOnChange()"
    693             >
     355            <%=!readCurrentSubtype ? "disabled readonly class=\"disabled selectionlist\"" : "class=\"selectionlist\""%>>
    694356          <%
    695357          if (!readCurrentSubtype)
     
    733395            recent="<%=recentTags%>"
    734396            newitem="<%=extract == null%>"
    735             onselect="selectTagOnClick()"
    736397          />
    737398        </td>
     
    747408      <tr>
    748409        <th>Original quantity</th>
    749         <td><input class="text" type="text" name="original_quantity" style="width: 15em;"
     410        <td><input class="text" type="text" name="original_quantity" id="original_quantity" style="width: 15em;"
    750411          value="<%=Values.formatNumber(extract == null ? Values.getFloat(cc.getPropertyValue("originalQuantity"), null): extract.getOriginalQuantity(), -1)%>"
    751           maxlength="10" onkeypress="return Numbers.numberOnly(event)"> (µg)</td>
     412          maxlength="10"> (µg)</td>
    752413        <td></td>
    753414      </tr>
     
    790451            defaultitems="<%=defaultProtocols%>"
    791452            newitem="<%=extract == null%>"
    792             onselect="selectProtocolOnClick()"
    793453            disabled="<%=lockEventProperties%>"
    794454          />
     
    807467            recent="<%=recentBioPlates%>"
    808468            newitem="<%=extract == null%>"
    809             onselect="selectBioPlateOnClick()"
    810             onchange="bioPlateOnChange()"
    811469            disabled="<%=lockedWell%>"
    812470          />
     
    824482            denied="<%=!readCurrentBioWell%>"
    825483            newitem="<%=extract == null%>"
    826             onselect="selectBioWellOnClick()"
    827             onchange="bioWellOnChange()"
    828484            disabled="<%=lockedWell%>"
    829485          />
     
    850506        <td>
    851507          <input type="radio" name="parentType" id="parentType.sample"
    852             value="SAMPLE" onclick="parentTypeOnClick()"
    853             <%=parentType != Item.EXTRACT ? "checked" : ""%>
     508            value="SAMPLE" <%=parentType != Item.EXTRACT ? "checked" : ""%>
    854509            ><label for="parentType.sample">Sample</label>
    855510          <input type="radio" name="parentType" id="parentType.extract"
    856             value="EXTRACT" onclick="parentTypeOnClick()"
    857             <%=parentType == Item.EXTRACT ? "checked" : ""%>
     511            value="EXTRACT" <%=parentType == Item.EXTRACT ? "checked" : ""%>
    858512            ><label for="parentType.extract">Extract</label>
    859513        </td>
     
    875529            selectrecent="false"
    876530            newitem="<%=extract == null%>"
    877             onselect="selectSampleOnClick()"
    878531          />
    879532        </td>
     
    882535        <th class="subprompt">used quantity</th>
    883536        <td>
    884           <input class="text" style="width: 15em;" type="text" name="used_from_sample"
     537          <input class="text" style="width: 15em;" type="text" name="used_from_sample"
     538            id="used_from_sample"
    885539            value="<%=Values.formatNumber(usedFromSample, -1)%>"
    886             maxlength="10" onkeypress="return Numbers.numberOnly(event)"
    887             onblur="usedFromSampleOnBlur()"> (µg)
     540            maxlength="10"> (µg)
    888541        </td>
    889542      </tr>
     
    895548          <tr>
    896549          <td>
    897             <select name="extracts" size="12" multiple onchange="extractsOnChange()">
     550            <select name="extracts" id="extracts"
     551              class="auto-init"
     552              data-auto-init="link-container"
     553              data-initial-items="[<%=HTML.encodeTags(jsonExtracts.toJSONString()) %>]"
     554              data-initial-action="<%=extract == null ? 1 : 0 %>"
     555              size="15" multiple>
    898556            </select>
    899557          </td>
     
    902560            <base:buttongroup vertical="true">
    903561              <base:button
     562                id="btnAddExtracts"
    904563                subclass="leftaligned"
    905564                style="width: 12em;"
    906                 onclick="addExtractsOnClick()"
    907565                title="Add&nbsp;extracts&hellip;"
    908566                tooltip="Add extracts"
    909567              />
    910568              <base:button
    911                 subclass="leftaligned"
     569                subclass="leftaligned auto-init"
     570                data-auto-init="remove-link"
     571                data-list-id="extracts"
    912572                style="width: 12em;"
    913                 onclick="removeOnClick()"
    914573                title="Remove"
    915574                tooltip="Remove the selected extracts"
    916575              />
    917576            </base:buttongroup>
    918             <input type="hidden" name="modifiedExtracts" value="">
    919             <input type="hidden" name="removedExtracts" value="">
    920577          </td>
    921578          </tr>
     
    928585        <td>
    929586          <input class="text" style="width: 15em;" type="text" name="used_quantity"
    930               value=""
    931               maxlength="10" onkeypress="return Numbers.numberOnly(event)"
    932               onkeyup="usedQuantityOnBlur();"
    933             > (µg)
     587            id="used_quantity" value="" maxlength="10" > (µg)
    934588        </td>
    935589      </tr>         
     
    941595    </t:tab>
    942596
    943     <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     597    <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit">
    944598      <jsp:include page="../../common/annotations/annotate_frameset.jsp">
    945599        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    950604   
    951605    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    952       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     606      helpid="annotations.edit.inherited">
    953607      <jsp:include page="../../common/annotations/inherit_frameset.jsp">
    954608        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    965619
    966620    <base:buttongroup subclass="dialogbuttons">
    967       <base:button onclick="saveSettings()" title="Save" />
    968       <base:button onclick="window.close()" title="Cancel" />
     621      <base:button id="btnSave" title="Save" />
     622      <base:button id="close" title="Cancel" />
    969623    </base:buttongroup>
    970624  </base:body>
  • trunk/www/biomaterials/extracts/extracts.js

    r6261 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', extracts.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', extracts.loadAnnotationsFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', extracts.loadInheritedAnnotationsFrame);
     44      TabControl.addTabValidator('settings.info', extracts.validateExtract);
     45
     46      // Quantity
     47      Events.addEventHandler('original_quantity', 'keypress', Events.numberOnly);
     48
     49      // Tag
     50      Buttons.addClickHandler('tag_id.select', extracts.selectTag);
     51      Events.addEventHandler('tag_id', 'base-selected', extracts.setTagCallback);
     52
     53      // Protocol
     54      Buttons.addClickHandler('protocol_id.select', extracts.selectProtocol);
     55      Events.addEventHandler('protocol_id', 'base-selected', extracts.setProtocolCallback);
     56      // Subtype
     57      Events.addEventHandler('subtype_id', 'change', extracts.subtypeOnChange);
     58
     59      // Bioplate and biowell
     60      Buttons.addClickHandler('bioplate_id.select', extracts.selectBioPlate);
     61      Events.addEventHandler('bioplate_id', 'base-selected', extracts.setBioPlateCallback);
     62      Events.addEventHandler('bioplate_id', 'change', extracts.bioPlateOnChange);
     63      Buttons.addClickHandler('biowell_id.select', extracts.selectBioWell);
     64      Events.addEventHandler('biowell_id', 'base-selected', extracts.setBioWellCallback);
     65      extracts.initBioWell();
     66
     67      // Parent items
     68      Events.addEventHandler('parentType.sample', 'click', extracts.parentTypeOnClick);
     69      Events.addEventHandler('parentType.extract', 'click', extracts.parentTypeOnClick);
     70      Buttons.addClickHandler('sample_id.select', extracts.selectSample);
     71      Events.addEventHandler('sample_id', 'base-selected', extracts.setSampleCallback);
     72      Events.addEventHandler('used_from_sample', 'keypress', Events.numberOnly);
     73      Events.addEventHandler('used_from_sample', 'blur', extracts.usedFromSampleOnBlur);
     74
     75      Events.addEventHandler('extracts', 'change', extracts.extractsOnChange);
     76      Buttons.addClickHandler('btnAddExtracts', extracts.addExtractsOnClick);
     77      Events.addEventHandler('btnAddExtracts', 'base-selected', extracts.addExtractCallback);
     78     
     79      Events.addEventHandler('used_quantity', 'keypress', Events.numberOnly);
     80      Events.addEventHandler('used_quantity', 'keyup', extracts.usedQuantityOnChange);
     81
     82      extracts.parentTypeOnClick();
     83
    3884    }
    3985    else if (pageId == 'view-page')
     
    162208    location.replace(url);
    163209  }
     210 
     211  extracts.validateExtract = function()
     212  {
     213    var frm = document.forms['extract'];
     214    if (Main.trimString(frm.name.value) == '')
     215    {
     216      Forms.showNotification(frm.name, 'You must enter a name');
     217      return false;
     218    }
     219    if (Main.trimString(frm.bioplate_id.value) != 0 && Main.trimString(frm.biowell_id.value) == 0)
     220    {
     221      Forms.showNotification('biowell_id.select', 'You must choose a biowell from the bioplate');
     222      return false;
     223    }
     224    return true;
     225  }
     226
     227  extracts.save = function()
     228  {
     229    var frm = document.forms['extract'];
     230    if (TabControl.validateActiveTab('settings'))
     231    {
     232      Annotations.saveModifiedAnnotationsToForm(frm);
     233      Annotations.saveInheritedAnnotationsToForm(frm);
     234      Link.exportActions('extracts');
     235      frm.submit();
     236    }
     237  }
     238
     239
     240  extracts.loadAnnotationsFrame = function()
     241  {
     242    var frm = document.forms['extract'];
     243    var protocolId = 0;
     244    if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
     245    {
     246      protocolId = Math.abs(parseInt(frm.protocol_id.value));       
     247    }
     248    Annotations.autoLoadEditFrame(protocolId, ItemSubtype.getSubtypeId('subtype_id'));
     249  }
     250
     251  extracts.loadInheritedAnnotationsFrame = function()
     252  {
     253    Annotations.autoLoadInheritFrame(extracts.getParents());
     254  }
     255
     256 
     257  extracts.getParents = function()
     258  {
     259    var frm = document.forms['extract'];
     260    var parents = [];
     261    if (frm.parentType[0].checked)
     262    {
     263      var sampleId = Math.abs(parseInt(frm.sample_id.value));
     264      if (sampleId > 0) parents[parents.length] = 'SAMPLE:'+sampleId;
     265    }
     266    else
     267    {
     268      var ids = Link.getIdsInList(frm.extracts, 'EXTRACT');
     269      if (ids.length > 0)
     270      {
     271        parents[parents.length] = 'EXTRACT:'+ids.join(':');
     272      }
     273    }
     274    return parents;
     275  }
     276
     277  extracts.subtypeOnChange = function()
     278  {
     279    var frm = document.forms['extract'];
     280    var subtypeId = ItemSubtype.getSubtypeId('subtype_id');
     281    var recentInfo = ItemSubtype.getRelatedProjectDefaultAndRecentItems('EXTRACT', subtypeId, ['PROTOCOL', 'BIOPLATE', 'TAG', 'SAMPLE', 'EXTRACT']);
     282    ItemSubtype.updateSelectionList(frm.protocol_id, recentInfo.PROTOCOL['recent'], recentInfo.PROTOCOL['default']);
     283    ItemSubtype.updateSelectionList(frm.tag_id, recentInfo.TAG['recent']);
     284    ItemSubtype.updateSelectionList(frm.bioplate_id, recentInfo.BIOPLATE['recent']);
     285  }
     286 
     287  extracts.selectTag = function()
     288  {
     289    var frm = document.forms['extract'];
     290    var url = '../tags/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
     291    var url = '&resetTemporary=1';
     292    url += ItemSubtype.createRelatedFilter('subtype_id', 'TAG');
     293    if (frm.tag_id.length > 1)
     294    {
     295      var id = Math.abs(parseInt(frm.tag_id[1].value));       
     296      url += '&item_id='+id;
     297    }
     298    Dialogs.selectItem('TAG', 'tag_id', 0, url);
     299  }
     300 
     301  extracts.setTagCallback = function(event)
     302  {
     303    var frm = document.forms['extract'];
     304    var list = frm.tag_id;
     305    if (list.length < 2 || list[1].value == '0')
     306    {
     307      Forms.addListOption(list, 1, new Option());
     308    }
     309    list[1].value = event.detail.id;
     310    list[1].text = event.detail.name;
     311    list.selectedIndex = 1;
     312  }
     313
     314 
     315  extracts.selectProtocol = function()
     316  {
     317    var frm = document.forms['extract'];
     318    var url = '&resetTemporary=1';
     319    url += ItemSubtype.createRelatedFilter('subtype_id', 'PROTOCOL', Data.int('page-data', 'extraction-protocoltype-id'));
     320    if (frm.protocol_id.length > 1)
     321    {
     322      var id = Math.abs(parseInt(frm.protocol_id[1].value));       
     323      url += '&item_id='+id;
     324    }
     325    Dialogs.selectItem('PROTOCOL', 'protocol_id', 0, url);
     326  }
     327 
     328  extracts.setProtocolCallback = function(event)
     329  {
     330    var frm = document.forms['extract'];
     331    var list = frm.protocol_id;
     332    if (list.length < 2 || list[1].value == '0')
     333    {
     334      Forms.addListOption(list, 1, new Option());
     335    }
     336    list[1].value = event.detail.id;
     337    list[1].text = event.detail.name;
     338    list.selectedIndex = 1;
     339  }
     340
     341  extracts.selectBioPlate = function()
     342  {
     343    var frm = document.forms['extract'];
     344    var url = '&resetTemporary=1';
     345    url += '&tmpfilter:INT:bioPlateType.bioMaterialType=|'+Data.get('page-data', 'extract-type');
     346    var subtypeId = ItemSubtype.getSubtypeId('subtype_id');
     347    // Restrict to plates with the given subtype
     348    url += '&tmpfilter:INT:bioPlateType.itemSubtype='+(subtypeId ? '|' + subtypeId : '=');
     349    url += '&tmpfilter:BOOLEAN:destroyed=false';
     350    Dialogs.selectItem('BIOPLATE', 'bioplate_id', 0, url);
     351  }
     352 
     353  extracts.setBioPlateCallback = function(event)
     354  {
     355    var frm = document.forms['extract'];
     356    var list = frm.bioplate_id;
     357    if (list.length < 2 || list[1].value == '0')
     358    {
     359      Forms.addListOption(list, 1, new Option());
     360    }
     361    list[1].value = event.detail.id;
     362    list[1].text = event.detail.name;
     363    list.selectedIndex = 1;
     364    extracts.bioPlateOnChange();
     365  }
     366
     367  extracts.bioPlateOnChange = function()
     368  {
     369    var frm = document.forms['extract'];
     370    var list = frm.bioplate_id;
     371    frm.biowell_id.selectedIndex=0;
     372    frm.biowell_id.remove(1);     
     373  }
     374 
     375  extracts.initBioWell = function()
     376  {
     377    var biowell = JSON.parse(Data.get('page-data', 'biowell'));
     378    if (biowell)
     379    {
     380      var frm = document.forms['extract'];
     381      var option = new Option(biowell.location, -biowell.id, true);
     382      frm.biowell_id[1] = option;
     383    }
     384  }
     385 
     386  extracts.selectBioWell = function()
     387  {
     388    var frm = document.forms['extract'];
     389    var bioplateId = Math.abs(parseInt(frm.bioplate_id.value))
     390    if (bioplateId == 0)
     391    {
     392      Forms.showNotification('bioplate_id.select', 'You must first select a bioplate', null, 'pointer-below');
     393      return;
     394    }
     395   
     396    var url = '&bioplate_id='+bioplateId;
     397    url += '&resetTemporary=1&tmpfilter:STRING:$mbm.name='+escape('=');
     398    url += '&tmpfilter:STRING:originalBioMaterial.name='+escape('=');
     399    url += '&columns=row,column';
     400
     401    Dialogs.selectItem('BIOWELL', 'biowell_id', 0, url);
     402  }
     403 
     404  extracts.setBioWellCallback = function(event)
     405  {
     406    var frm = document.forms['extract'];
     407    var list = frm.biowell_id;
     408    if (list.length < 2 || list[1].value == '0')
     409    {
     410      Forms.addListOption(list, 1, new Option());
     411    }
     412    list[1].value = event.detail.id;
     413    list[1].text = event.detail.name;
     414    list.selectedIndex = 1;
     415  }
     416
     417  extracts.parentTypeOnClick = function()
     418  {
     419    var frm = document.forms['extract'];
     420    var useExtracts = frm.parentType[1].checked;
     421    frm.sample_id.disabled = useExtracts;
     422    frm.used_from_sample.disabled = useExtracts;
     423    frm.extracts.disabled = !useExtracts;
     424    frm.used_quantity.disabled = !useExtracts;
     425  }
     426
     427  extracts.selectSample = function()
     428  {
     429    var frm = document.forms['extract'];
     430    var url = '&resetTemporary=1';
     431    url += ItemSubtype.createRelatedFilter('subtype_id', 'SAMPLE');
     432    if (frm.sample_id.length > 1)
     433    {
     434      var id = Math.abs(parseInt(frm.sample_id[1].value));       
     435      url += '&item_id='+id;
     436    }
     437    Dialogs.selectItem('SAMPLE', 'sample_id', 0, url);
     438  }
     439 
     440  extracts.setSampleCallback = function(event)
     441  {
     442    var frm = document.forms['extract'];
     443    var list = frm.sample_id;
     444    if (list.length < 2 || list[1].value == '0')
     445    {
     446      Forms.addListOption(list, 1, new Option());
     447    }
     448    list[1].value = event.detail.id;
     449    list[1].text = event.detail.name;
     450    list.selectedIndex = 1;
     451
     452    frm.parentType[0].checked = true;
     453    frm.parentType[1].checked = false;
     454    extracts.parentTypeOnClick();
     455  }
     456
     457  extracts.usedFromSampleOnBlur = function()
     458  {
     459    var frm = document.forms['extract'];
     460    var sampleId = parseInt(frm.sample_id.value);
     461    if (sampleId < 0)
     462    {
     463      frm.sample_id[frm.sample_id.selectedIndex].value = -sampleId;
     464    }
     465  }
     466 
     467  extracts.addExtractsOnClick = function(event)
     468  {
     469    var frm = document.forms['extract'];
     470    var currentExtracts = Link.getIdsInList(frm.extracts, 'EXTRACT');
     471    var url = '&resetTemporary=1&exclude='+currentExtracts.join(',');
     472    url += ItemSubtype.createRelatedFilter('subtype_id', 'EXTRACT');
     473    Dialogs.selectItem('EXTRACT', event.currentTarget.id, 1, url);
     474  }
     475
     476  extracts.addExtractCallback = function(event)
     477  {
     478    var frm = document.forms['extract'];
     479    event.detail.name += ' [-]';
     480    Link.addItem('extracts', 'EXTRACT', event.detail);
     481    frm.parentType[0].checked = false;
     482    frm.parentType[1].checked = true;
     483    extracts.parentTypeOnClick();
     484  }
     485
     486  extracts.usedQuantityOnChange = function()
     487  {
     488    var frm = document.forms['extract'];
     489    var usedQuantity = frm.used_quantity.value;
     490    var displayQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
     491    for (var i = 0; i < frm.extracts.length; i++)
     492    {
     493      var option = frm.extracts[i];
     494      if (option.selected && option.item.id)
     495      {
     496        option.item.value = usedQuantity;
     497        var text = option.text.replace(/\[.*\]/, '['+displayQuantity+']');
     498        option.text = text;
     499      }
     500    }
     501  }
     502 
     503  extracts.extractsOnChange = function()
     504  {
     505    var frm = document.forms['extract'];
     506    var item = frm.extracts[frm.extracts.selectedIndex].item;
     507    if (item && item.id && item.value != undefined)
     508    {
     509      frm.used_quantity.value = item.value;
     510    }
     511    else
     512    {
     513      frm.used_quantity.value = '';
     514    }
     515    frm.used_quantity.focus();
     516  }
    164517
    165518  return extracts;
  • trunk/www/biomaterials/extracts/index.jsp

    r6192 r6312  
    307307          creationEvent.clearSources();
    308308        }
    309         String[] modifiedExtracts = Values.getString(request.getParameter("modifiedExtracts")).split(",");
     309        String[] modifiedExtracts = Values.getString(request.getParameter("+EXTRACT")).split(",");
    310310        for (int i = 0; i < modifiedExtracts.length; ++i)
    311311        {
     
    314314          {
    315315            Extract e = Extract.getById(dc, eId);
    316             creationEvent.addSource(e).setUsedQuantity(Values.getFloat(request.getParameter("E"+eId), null));
     316            creationEvent.addSource(e).setUsedQuantity(Values.getFloat(request.getParameter("EXTRACT."+eId), null));
    317317          }
    318318        }
    319         String[] removedExtracts = Values.getString(request.getParameter("removedExtracts")).split(",");
     319        String[] removedExtracts = Values.getString(request.getParameter("-EXTRACT")).split(",");
    320320        for (int i = 0; i < removedExtracts.length; ++i)
    321321        {
  • trunk/www/biomaterials/samples/edit_sample.jsp

    r6297 r6312  
    6363  import="net.sf.basedb.clients.web.extensions.edit.EditUtil"
    6464  import="net.sf.basedb.util.extensions.ExtensionsInvoker"
     65  import="net.sf.basedb.util.json.JsonUtil"
     66  import="net.sf.basedb.util.json.JsonConverter"
     67  import="net.sf.basedb.util.json.NameableConverter"
     68  import="org.json.simple.JSONObject"
     69  import="org.json.simple.JSONArray"
    6570  import="java.util.List"
    6671  import="java.util.Set"
     
    254259  subtypesQuery.include(Include.ALL);
    255260 
    256  
     261  JSONObject jsonBioWell = null;
     262  if (currentBioWell != null)
     263  {
     264    jsonBioWell = new JSONObject();
     265    jsonBioWell.put("id", currentBioWell.getId());
     266    jsonBioWell.put("location", currentBioWell.getCoordinate());
     267  }
     268 
     269  JSONObject jsonSamples = new JSONObject();
     270  jsonSamples.put("itemType", "SAMPLE");
     271  if (samplesQuery != null)
     272  {
     273    final BioMaterialEvent event = creationEvent;
     274    jsonSamples.put("items", JsonUtil.toArray(samplesQuery.iterate(dc), new NameableConverter<Sample>()
     275    {
     276      protected void setMore(JSONObject json, Sample s)
     277      {
     278        Float usedQuantity = event == null ? null : event.getUsedQuantity(s);
     279        json.put("name", s.getName() + (usedQuantity == null ? " [-]" : " [" +  usedQuantity + " µg]"));
     280        json.put("value", usedQuantity);
     281      }
     282    }));
     283  }
     284
    257285 
    258286  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
     
    264292  %>
    265293  <base:page type="popup" title="<%=title%>" id="edit-page">
    266   <base:head scripts="tabcontrol-2.js,linkitems.js,subtypes.js,~samples.js" styles="tabcontrol.css">
     294  <base:head scripts="tabcontrol-2.js,linkitems-2.js,subtypes.js,~samples.js" styles="tabcontrol.css">
    267295    <ext:scripts context="<%=jspContext%>" />
    268296    <ext:stylesheets context="<%=jspContext%>" />
    269     <script>
    270    
    271    
    272     function getParents()
    273     {
    274       var frm = document.forms['sample'];
    275       var parents = new Array();
    276       if (frm.parentType[0].checked)
    277       {
    278         var bioSourceId = Math.abs(parseInt(frm.biosource_id[frm.biosource_id.selectedIndex].value));
    279         if (bioSourceId > 0) parents[parents.length] = 'BIOSOURCE:'+bioSourceId;
    280       }
    281       else
    282       {
    283         var ids = Link.getListIds(frm.samples, 'S');
    284         if (ids.length > 0)
    285         {
    286           parents[parents.length] = 'SAMPLE:'+ids.join(':');
    287         }
    288       }
    289       return parents;
    290     }
    291    
    292 
    293     function bioPlateOnChange()
    294     {
    295       var frm = document.forms['sample'];
    296       var list = frm.bioplate_id;
    297       frm.biowell_id.selectedIndex=0;
    298       frm.biowell_id.remove(1);     
    299     }
    300 
    301     function initBioWell()
    302     {
    303       var frm = document.forms['sample'];
    304       <%
    305       if (currentBioWell != null)
    306       {
    307         %>
    308         var list = frm.biowell_id;
    309         var wellId = <%=currentBioWell.getId()%>;
    310         Forms.addListOption(list, 1, new Option());
    311         list[1].value = '<%=currentBioWell.getId()*(sample == null ? 1 : -1)%>';
    312         list[1].text = '<%=rowFormatter.format(currentBioWell.getRow())%><%=columnFormatter.format(currentBioWell.getColumn())%>';
    313         list.selectedIndex = 1;
    314       <%
    315       }
    316       %>
    317     }         
    318     function selectBioWellOnClick()
    319     {
    320       var frm = document.forms['sample'];
    321       var bioplate_list = frm.bioplate_id;     
    322       var bioplateId = Math.abs(parseInt(bioplate_list[bioplate_list.selectedIndex].value))
    323       if (Main.trimString(frm.bioplate_id.value) == 0)
    324       {
    325         Forms.showNotification('bioplate_id.select', 'You must first select a bioplate', null, 'pointer-below');
    326         return;
    327       }     
    328        
    329       var url = '../bioplates/wells/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setBioWellCallback';
    330       if (frm.biowell_id.length > 1)
    331       {
    332         var id = Math.abs(parseInt(frm.biowell_id[1].value));       
    333         url += '&item_id='+id;
    334       }
    335       url += '&bioplate_id='+bioplateId;
    336       url += '&resetTemporary=1&tmpfilter:STRING:$mbm.name='+escape('=');
    337       url += '&tmpfilter:STRING:originalBioMaterial.name='+escape('=');
    338       url += '&columns=row,column';
    339       Main.openPopup(url, 'SelectBiowell', 750, 500);
    340     }
    341     function setBioWellCallback(id, name)
    342     {
    343       var frm = document.forms['sample'];
    344       var list = frm.biowell_id;
    345       if (list.length < 2 || list[1].value == '0') // >
    346       {
    347         Forms.addListOption(list, 1, new Option());
    348       }
    349       list[1].value = id;
    350       list[1].text = name;
    351       list.selectedIndex = 1;
    352     }
    353    
    354     function parentTypeOnClick()
    355     {
    356       var frm = document.forms['sample'];
    357       var useSamples = frm.parentType[1].checked;
    358       frm.biosource_id.disabled = useSamples;
    359       frm.samples.disabled = !useSamples;
    360       frm.used_quantity.disabled = !useSamples;
    361     }
    362     function selectBioSourceOnClick()
    363     {
    364       var frm = document.forms['sample'];
    365       var url = '../biosources/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    366       url += '&callback=setBioSourceCallback&resetTemporary=1';
    367       url += ItemSubtype.createRelatedFilter('subtype_id', 'BIOSOURCE');
    368       if (frm.biosource_id.length > 1)
    369       {
    370         var id = Math.abs(parseInt(frm.biosource_id[1].value));       
    371         url += '&item_id='+id;
    372       }
    373       Main.openPopup(url, 'SelectBioSource', 1050, 700);
    374     }
    375     function setBioSourceCallback(id, name)
    376     {
    377       var frm = document.forms['sample'];
    378       var list = frm.biosource_id;
    379       if (list.length < 2 || list[1].value == '0') // >
    380       {
    381         Forms.addListOption(list, 1, new Option());
    382       }
    383       list[1].value = id;
    384       list[1].text = name;
    385       list.selectedIndex = 1;
    386 
    387       frm.parentType[0].checked = true;
    388       frm.parentType[1].checked = false;
    389       parentTypeOnClick();
    390     }
    391    
    392     function addSamplesOnClick()
    393     {
    394       var frm = document.forms['sample'];
    395       var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
    396       url += '&callback=addSampleCallback&resetTemporary=1';
    397       url += ItemSubtype.createRelatedFilter('subtype_id', 'SAMPLE');
    398       Main.openPopup(url, 'AddSamples', 1050, 700);
    399     }
    400     function addSampleCallback(sampleId, name)
    401     {
    402       var frm = document.forms['sample'];
    403       var item = Link.getItem('S', sampleId);
    404       if (!item) item = new Item('S', sampleId, name+' [-]', '', '');
    405       Link.addItem(frm.samples, item);
    406       frm.parentType[0].checked = false;
    407       frm.parentType[1].checked = true;
    408       parentTypeOnClick();
    409     }
    410     function samplesOnChange()
    411     {
    412       var frm = document.forms['sample'];
    413       var item = frm.samples[frm.samples.selectedIndex].item;
    414       if (item && item.id)
    415       {
    416         frm.used_quantity.value = item.value;
    417         frm.used_quantity.focus();
    418       }
    419       else
    420       {
    421         frm.used_quantity.value = '';
    422       }
    423     }
    424     function usedQuantityOnBlur()
    425     {
    426       var frm = document.forms['sample'];
    427       var usedQuantity = frm.used_quantity.value;
    428       var displayQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
    429       for (var i = 0; i < frm.samples.length; i++)  // >
    430       {
    431         var option = frm.samples[i];
    432         if (option.selected && option.item.id)
    433         {
    434           option.item.value = usedQuantity;
    435           var text = option.text.replace(/\[.*\]/, '['+displayQuantity+']');
    436           option.text = text;
    437         }
    438       }
    439     }
    440 
    441     function removeOnClick()
    442     {
    443       Link.removeSelected(document.forms['sample'].samples);
    444     }
    445 
    446     function init()
    447     {
    448       <%
    449       if (sample == null)
    450       {
    451         %>
    452         var frm = document.forms['sample'];
    453         frm.name.focus();
    454         frm.name.select();
    455         <%
    456       }
    457       %>
    458       initBioWell();
    459       initSamples();
    460       parentTypeOnClick();   
    461     }
    462     function initSamples()
    463     {
    464       var samples = document.forms['sample'].samples;
    465       <%
    466       if (samplesQuery != null)
    467       {
    468         samplesQuery.include(Include.ALL);
    469         samplesQuery.order(Orders.asc(Hql.property("name")));
    470         ItemResultList<Sample> samples = samplesQuery.list(dc);
    471         for (Sample s : samples)
    472         {
    473           if (sample != null)
    474           {
    475             String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(s), -1);
    476             %>
    477             Link.addNewItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
    478             <%
    479           }
    480           else
    481           {
    482             %>
    483             Link.addItem(samples, new Item('S', <%=s.getId()%>, '<%=HTML.javaScriptEncode(s.getName())%> [-]', '', ''));
    484             <%
    485           }
    486         }
    487       }
    488       %>
    489     }
    490     </script>
    491297  </base:head>
    492   <base:body onload="init()">
     298  <base:body>
    493299    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    494300    <form action="index.jsp?ID=<%=ID%>" method="post" name="sample">
     
    497303    <div id="page-data" class="datacontainer"
    498304      data-sampling-protocoltype-id="<%=SystemItems.getId(Protocol.SAMPLING)%>"
     305      data-sample-type="<%=Item.SAMPLE.getValue()%>"
     306      <%
     307      if (jsonBioWell != null)
     308      {
     309        %>
     310        data-biowell="<%=HTML.encodeTags(jsonBioWell.toJSONString()) %>"
     311        <%
     312      }
     313      %>
    499314    ></div>
    500315
    501316    <t:tabcontrol id="settings"
    502317      subclass="content dialogtabcontrol"
    503       position="bottom"  remember="<%=sample != null%>"
     318      position="bottom" remember="<%=sample != null%>"
    504319      extensions="<%=invoker%>">
    505320    <t:tab id="info" title="Sample" helpid="sample.edit">
     
    558373      <tr>
    559374        <th>Original quantity</th>
    560         <td><input class="text" type="text" name="original_quantity" style="width: 15em;"
     375        <td><input class="text" type="text" name="original_quantity" id="original_quantity" style="width: 15em;"
    561376          value="<%=Values.formatNumber(sample == null ? Values.getFloat(cc.getPropertyValue("originalQuantity"), null): sample.getOriginalQuantity(), -1)%>" size="12"
    562           maxlength="10" onkeypress="return Numbers.numberOnly(event)"> (µg)</td>
     377          maxlength="10"> (µg)</td>
    563378        <td></td>
    564379      </tr>
     
    617432            recent="<%=recentBioPlates%>"
    618433            newitem="<%=sample == null%>"
    619             onchange="bioPlateOnChange()"
    620434            disabled="<%=lockedWell%>"
    621435          />
     
    633447            denied="<%=!readCurrentBioWell%>"
    634448            newitem="<%=sample == null%>"
    635             onselect="selectBioWellOnClick()"
    636             onchange="bioWellOnChange()"
    637449            disabled="<%=lockedWell%>"
    638450          />
     
    659471        <td>
    660472          <input type="radio" name="parentType" id="parentType.biosource"
    661             value="BIOSOURCE" onclick="parentTypeOnClick()"
    662             <%=parentType != Item.SAMPLE ? "checked" : ""%>
     473            value="BIOSOURCE" <%=parentType != Item.SAMPLE ? "checked" : ""%>
    663474            ><label for="parentType.biosource">Biosource</label>
    664475          <input type="radio" name="parentType" id="parentType.sample"
    665             value="SAMPLE" onclick="parentTypeOnClick()"
    666             <%=parentType == Item.SAMPLE ? "checked" : ""%>
     476            value="SAMPLE" <%=parentType == Item.SAMPLE ? "checked" : ""%>
    667477            ><label for="parentType.sample">Sample</label>
    668478        </td>
     
    684494            selectrecent="false"
    685495            newitem="<%=sample == null%>"
    686             onselect="selectBioSourceOnClick()"
    687496          />
    688497        </td>
     
    695504          <tr>
    696505            <td>
    697             <select name="samples" size="12" multiple onchange="samplesOnChange()">
     506            <select name="samples" id="samples"
     507              class="auto-init"
     508              data-auto-init="link-container"
     509              data-initial-items="[<%=HTML.encodeTags(jsonSamples.toJSONString()) %>]"
     510              data-initial-action="<%=sample == null ? 1 : 0 %>"
     511              size="15" multiple>
    698512            </select>
    699513          </td>
     
    701515            <base:buttongroup vertical="true">
    702516              <base:button
     517                id="btnAddSamples"
    703518                subclass="leftaligned"
    704519                style="width: 12em;"
    705                 onclick="addSamplesOnClick()"
    706520                title="Add&nbsp;samples&hellip;"
    707521                tooltip="Add samples"
    708                 />
     522              />
    709523              <base:button
    710                 subclass="leftaligned"
     524                subclass="leftaligned auto-init"
     525                data-auto-init="remove-link"
     526                data-list-id="samples"
    711527                style="width: 12em;"
    712                 onclick="removeOnClick()"
    713528                title="Remove"
    714529                tooltip="Remove the selected samples"
    715530              />
    716531            </base:buttongroup>
    717             <input type="hidden" name="modifiedSamples" value="">
    718             <input type="hidden" name="removedSamples" value="">
    719532          </td>
    720533          </tr>
     
    726539        <th class="subprompt">- used quantity</th>
    727540        <td>
    728           <input class="text" style="width: 15em;" type="text" name="used_quantity" value=""
    729                maxlength="10" onkeypress="return Numbers.numberOnly(event)"
    730               onkeyup="usedQuantityOnBlur();"
    731             > (µg)
     541          <input class="text" style="width: 15em;" type="text"
     542            name="used_quantity" id="used_quantity" value=""
     543             maxlength="10"> (µg)
    732544        </td>
    733545      </tr>
  • trunk/www/biomaterials/samples/index.jsp

    r6192 r6312  
    281281          creationEvent.clearSources();
    282282        }
    283         String[] modifiedSamples = Values.getString(request.getParameter("modifiedSamples")).split(",");
     283        String[] modifiedSamples = Values.getString(request.getParameter("+SAMPLE")).split(",");
    284284        for (int i = 0; i < modifiedSamples.length; ++i)
    285285        {
     
    288288          {
    289289            Sample s = Sample.getById(dc, sId);
    290             creationEvent.addSource(s).setUsedQuantity(Values.getFloat(request.getParameter("S"+sId), null));
     290            creationEvent.addSource(s).setUsedQuantity(Values.getFloat(request.getParameter("SAMPLE."+sId), null));
    291291          }
    292292        }
    293         String[] removedSamples = Values.getString(request.getParameter("removedSamples")).split(",");
     293        String[] removedSamples = Values.getString(request.getParameter("-SAMPLE")).split(",");
    294294        for (int i = 0; i < removedSamples.length; ++i)
    295295        {
  • trunk/www/biomaterials/samples/samples.js

    r6297 r6312  
    4444      TabControl.addTabValidator('settings.info', samples.validateSample);
    4545
     46      // Quantity
     47      Events.addEventHandler('original_quantity', 'keypress', Events.numberOnly);
     48     
    4649      // Protocol
    4750      Buttons.addClickHandler('protocol_id.select', samples.selectProtocol);
    4851      Events.addEventHandler('protocol_id', 'base-selected', samples.setProtocolCallback);
    49      
    5052      // Subtype
    5153      Events.addEventHandler('subtype_id', 'change', samples.subtypeOnChange);
     
    5456      Buttons.addClickHandler('bioplate_id.select', samples.selectBioPlate);
    5557      Events.addEventHandler('bioplate_id', 'base-selected', samples.setBioPlateCallback);
     58      Events.addEventHandler('bioplate_id', 'change', samples.bioPlateOnChange);
     59      Buttons.addClickHandler('biowell_id.select', samples.selectBioWell);
     60      Events.addEventHandler('biowell_id', 'base-selected', samples.setBioWellCallback);
     61      samples.initBioWell();
     62     
     63      // Parent items
     64      Events.addEventHandler('parentType.biosource', 'click', samples.parentTypeOnClick);
     65      Events.addEventHandler('parentType.sample', 'click', samples.parentTypeOnClick);
     66      Buttons.addClickHandler('biosource_id.select', samples.selectBioSource);
     67      Events.addEventHandler('biosource_id', 'base-selected', samples.setBioSourceCallback);
     68
     69      Events.addEventHandler('samples', 'change', samples.samplesOnChange);
     70      Buttons.addClickHandler('btnAddSamples', samples.addSamplesOnClick);
     71      Events.addEventHandler('btnAddSamples', 'base-selected', samples.addSampleCallback);
     72     
     73      Events.addEventHandler('used_quantity', 'keypress', Events.numberOnly);
     74      Events.addEventHandler('used_quantity', 'keyup', samples.usedQuantityOnChange);
     75
     76      samples.parentTypeOnClick();
     77     
    5678    }
    5779    else if (pageId == 'view-page')
     
    184206      Annotations.saveModifiedAnnotationsToForm(frm);
    185207      Annotations.saveInheritedAnnotationsToForm(frm);
    186       frm.modifiedSamples.value = Link.exportModified(frm, 'S', true).join(',');
    187       frm.removedSamples.value = Link.getActionIds(-1, 'S').join(',');
     208      Link.exportActions('samples');
    188209      frm.submit();
    189210    }
    190211  }
    191212 
     213  samples.selectBioPlate = function()
     214  {
     215    var frm = document.forms['sample'];
     216    var url = '&resetTemporary=1';
     217    url += '&tmpfilter:INT:bioPlateType.bioMaterialType=|'+Data.get('page-data', 'sample-type');
     218    var subtypeId = ItemSubtype.getSubtypeId('subtype_id');
     219    // Restrict to plates with the given subtype
     220    url += '&tmpfilter:INT:bioPlateType.itemSubtype='+(subtypeId ? '|' + subtypeId : '=');
     221    url += '&tmpfilter:BOOLEAN:destroyed=false';
     222    Dialogs.selectItem('BIOPLATE', 'bioplate_id', 0, url);
     223  }
     224 
     225  samples.setBioPlateCallback = function(event)
     226  {
     227    var frm = document.forms['sample'];
     228    var list = frm.bioplate_id;
     229    if (list.length < 2 || list[1].value == '0')
     230    {
     231      Forms.addListOption(list, 1, new Option());
     232    }
     233    list[1].value = event.detail.id;
     234    list[1].text = event.detail.name;
     235    list.selectedIndex = 1;
     236    samples.bioPlateOnChange();
     237  }
     238
     239  samples.bioPlateOnChange = function()
     240  {
     241    var frm = document.forms['sample'];
     242    var list = frm.bioplate_id;
     243    frm.biowell_id.selectedIndex=0;
     244    frm.biowell_id.remove(1);     
     245  }
     246 
     247  samples.initBioWell = function()
     248  {
     249    var biowell = JSON.parse(Data.get('page-data', 'biowell'));
     250    if (biowell)
     251    {
     252      var frm = document.forms['sample'];
     253      var option = new Option(biowell.location, -biowell.id, true);
     254      frm.biowell_id[1] = option;
     255    }
     256  }
     257 
     258  samples.selectBioWell = function()
     259  {
     260    var frm = document.forms['sample'];
     261    var bioplateId = Math.abs(parseInt(frm.bioplate_id.value))
     262    if (bioplateId == 0)
     263    {
     264      Forms.showNotification('bioplate_id.select', 'You must first select a bioplate', null, 'pointer-below');
     265      return;
     266    }
     267   
     268    var url = '&bioplate_id='+bioplateId;
     269    url += '&resetTemporary=1&tmpfilter:STRING:$mbm.name='+escape('=');
     270    url += '&tmpfilter:STRING:originalBioMaterial.name='+escape('=');
     271    url += '&columns=row,column';
     272
     273    Dialogs.selectItem('BIOWELL', 'biowell_id', 0, url);
     274  }
     275  samples.setBioWellCallback = function(event)
     276  {
     277    var frm = document.forms['sample'];
     278    var list = frm.biowell_id;
     279    if (list.length < 2 || list[1].value == '0')
     280    {
     281      Forms.addListOption(list, 1, new Option());
     282    }
     283    list[1].value = event.detail.id;
     284    list[1].text = event.detail.name;
     285    list.selectedIndex = 1;
     286  }
    192287 
    193288  samples.loadAnnotationsFrame = function()
     
    197292    if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
    198293    {
    199       protocolId = Math.abs(parseInt(frm.protocol_id[frm.protocol_id.selectedIndex].value));       
     294      protocolId = Math.abs(parseInt(frm.protocol_id.value));       
    200295    }
    201296    Annotations.autoLoadEditFrame(protocolId, ItemSubtype.getSubtypeId('subtype_id'));
     
    204299  samples.loadInheritedAnnotationsFrame = function()
    205300  {
    206     Annotations.autoLoadInheritFrame(getParents());
     301    Annotations.autoLoadInheritFrame(samples.getParents());
     302  }
     303 
     304  samples.getParents = function()
     305  {
     306    var frm = document.forms['sample'];
     307    var parents = [];
     308    if (frm.parentType[0].checked)
     309    {
     310      var bioSourceId = Math.abs(parseInt(frm.biosource_id.value));
     311      if (bioSourceId > 0) parents[parents.length] = 'BIOSOURCE:'+bioSourceId;
     312    }
     313    else
     314    {
     315      var ids = Link.getIdsInList(frm.samples, 'SAMPLE');
     316      if (ids.length > 0)
     317      {
     318        parents[parents.length] = 'SAMPLE:'+ids.join(':');
     319      }
     320    }
     321    return parents;
    207322  }
    208323 
     
    222337  samples.setProtocolCallback = function(event)
    223338  {
    224     var id = event.detail.id;
    225     var name = event.detail.name;
    226339    var frm = document.forms['sample'];
    227340    var list = frm.protocol_id;
     
    230343      Forms.addListOption(list, 1, new Option());
    231344    }
    232     list[1].value = id;
    233     list[1].text = name;
     345    list[1].value = event.detail.id;
     346    list[1].text = event.detail.name;
    234347    list.selectedIndex = 1;
    235348  }
     
    244357  }
    245358
     359  samples.parentTypeOnClick = function()
     360  {
     361    var frm = document.forms['sample'];
     362    var useSamples = frm.parentType[1].checked;
     363    frm.biosource_id.disabled = useSamples;
     364    frm.samples.disabled = !useSamples;
     365    frm.used_quantity.disabled = !useSamples;
     366  }
     367
     368  samples.selectBioSource = function()
     369  {
     370    var frm = document.forms['sample'];
     371    var url = '&resetTemporary=1';
     372    url += ItemSubtype.createRelatedFilter('subtype_id', 'BIOSOURCE');
     373    if (frm.biosource_id.length > 1)
     374    {
     375      var id = Math.abs(parseInt(frm.biosource_id[1].value));       
     376      url += '&item_id='+id;
     377    }
     378    Dialogs.selectItem('BIOSOURCE', 'biosource_id', 0, url);
     379  }
     380 
     381  samples.setBioSourceCallback = function(event)
     382  {
     383    var frm = document.forms['sample'];
     384    var list = frm.biosource_id;
     385    if (list.length < 2 || list[1].value == '0')
     386    {
     387      Forms.addListOption(list, 1, new Option());
     388    }
     389    list[1].value = event.detail.id;
     390    list[1].text = event.detail.name;
     391    list.selectedIndex = 1;
     392
     393    frm.parentType[0].checked = true;
     394    frm.parentType[1].checked = false;
     395    samples.parentTypeOnClick();
     396  }
     397
     398 
     399  samples.addSamplesOnClick = function(event)
     400  {
     401    var frm = document.forms['sample'];
     402    var currentSamples = Link.getIdsInList(frm.samples, 'SAMPLE');
     403    var url = "&resetTemporary=1&exclude="+currentSamples.join(',');
     404    url += ItemSubtype.createRelatedFilter('subtype_id', 'SAMPLE');
     405    Dialogs.selectItem('SAMPLE', event.currentTarget.id, 1, url);
     406  }
     407
     408  samples.addSampleCallback = function(event)
     409  {
     410    var frm = document.forms['sample'];
     411    event.detail.name += ' [-]';
     412    Link.addItem('samples', 'SAMPLE', event.detail);
     413    frm.parentType[0].checked = false;
     414    frm.parentType[1].checked = true;
     415    samples.parentTypeOnClick();
     416  }
     417
     418  samples.usedQuantityOnChange = function()
     419  {
     420    var frm = document.forms['sample'];
     421    var usedQuantity = frm.used_quantity.value;
     422    var displayQuantity = usedQuantity == '' ? '-' : usedQuantity+' µg';
     423    for (var i = 0; i < frm.samples.length; i++)
     424    {
     425      var option = frm.samples[i];
     426      if (option.selected && option.item.id)
     427      {
     428        option.item.value = usedQuantity;
     429        var text = option.text.replace(/\[.*\]/, '['+displayQuantity+']');
     430        option.text = text;
     431      }
     432    }
     433  }
     434 
     435  samples.samplesOnChange = function()
     436  {
     437    var frm = document.forms['sample'];
     438    var item = frm.samples[frm.samples.selectedIndex].item;
     439    if (item && item.id && item.value != undefined)
     440    {
     441      frm.used_quantity.value = item.value;
     442    }
     443    else
     444    {
     445      frm.used_quantity.value = '';
     446    }
     447    frm.used_quantity.focus();
     448  }
     449 
    246450  return samples;
    247451}();
  • trunk/www/lims/arraybatches/batches.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', arrayBatches.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', arrayBatches.loadAnnotationsFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', arrayBatches.loadInheritedAnnotationsFrame);
     44      TabControl.addTabValidator('settings.info', arrayBatches.validateArrayBatch);
     45
     46      // Array design
     47      Buttons.addClickHandler('arraydesign_id.select', arrayBatches.selectArrayDesign);
     48      Events.addEventHandler('arraydesign_id', 'base-selected', arrayBatches.setArrayDesignCallback);
     49
     50      // Protocol
     51      Buttons.addClickHandler('protocol_id.select', arrayBatches.selectProtocol);
     52      Events.addEventHandler('protocol_id', 'base-selected', arrayBatches.setProtocolCallback);
     53
     54      // Print robot
     55      Buttons.addClickHandler('printrobot_id.select', arrayBatches.selectPrintRobot);
     56      Events.addEventHandler('printrobot_id', 'base-selected', arrayBatches.setPrintRobotCallback);
     57
    3858    }
    3959    else if (pageId == 'view-page')
     
    104124  }
    105125 
     126  arrayBatches.validateArrayBatch = function()
     127  {
     128    var frm = document.forms['batch'];
     129    if (Main.trimString(frm.name.value) == '')
     130    {
     131      Forms.showNotification(frm.name, 'You must enter a name');
     132      return false;
     133    }
     134    if (frm.arraydesign_id && !frm.arraydesign_id.value)
     135    {
     136      Forms.showNotification('arraydesign_id.select', 'You must select an array design');
     137      return false;
     138    }
     139    return true;
     140  }
     141
     142  // Submit the form
     143  arrayBatches.save = function()
     144  {
     145    var frm = document.forms['batch'];
     146    if (TabControl.validateActiveTab('settings'))
     147    {
     148      Annotations.saveModifiedAnnotationsToForm(frm);
     149      Annotations.saveInheritedAnnotationsToForm(frm);
     150      frm.submit();
     151    }
     152  }
     153 
     154  arrayBatches.loadAnnotationsFrame = function()
     155  {
     156    Annotations.autoLoadEditFrame(arrayBatches.getProtocolId());
     157  }
     158 
     159  arrayBatches.loadInheritedAnnotationsFrame = function()
     160  {
     161    Annotations.autoLoadInheritFrame(arrayBatches.getParents());
     162  }
     163
     164  arrayBatches.getProtocolId = function()
     165  {
     166    var frm = document.forms['batch'];
     167    var protocolId = 0;
     168    if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
     169    {
     170      protocolId = Math.abs(parseInt(frm.protocol_id.value));       
     171    }
     172    return protocolId;
     173  }
     174
     175  arrayBatches.getParents = function()
     176  {
     177    var frm = document.forms['batch'];
     178    var parents = new Array();
     179    if (frm.arraydesign_id)
     180    {
     181      var arrayDesignId = Math.abs(parseInt(frm.arraydesign_id.value));
     182      if (arrayDesignId > 0) parents[parents.length] = 'ARRAYDESIGN:'+arrayDesignId;
     183    }
     184    return parents;
     185  }
     186
     187  arrayBatches.selectArrayDesign = function()
     188  {
     189    var frm = document.forms['batch'];
     190    var url = '';
     191    if (frm.arraydesign_id.length > 0)
     192    {
     193      var id = Math.abs(parseInt(frm.arraydesign_id[0].value));       
     194      url += '&item_id='+id;
     195    }
     196    Dialogs.selectItem('ARRAYDESIGN', 'arraydesign_id', 0, url);
     197  }
     198 
     199  arrayBatches.setArrayDesignCallback = function(event)
     200  {
     201    var frm = document.forms['batch'];
     202    var list = frm.arraydesign_id;
     203    if (list.length < 1 || list[0].value == '0')
     204    {
     205      Forms.addListOption(list, 0, new Option());
     206    }
     207    list[0].value = event.detail.id;
     208    list[0].text = event.detail.name;
     209    list.selectedIndex = 0;
     210  }
     211
     212  arrayBatches.selectProtocol = function()
     213  {
     214    var frm = document.forms['batch'];
     215    var url = '';
     216    if (frm.protocol_id.length > 1)
     217    {
     218      var id = Math.abs(parseInt(frm.protocol_id[1].value));       
     219      url += '&item_id='+id;
     220    }
     221    url += '&resetTemporary=1&tmpfilter:INT:itemSubtype='+Data.get('page-data', 'printing-protocol');
     222    Dialogs.selectItem('PROTOCOL', 'protocol_id', 0, url);
     223  }
     224 
     225  arrayBatches.setProtocolCallback = function(event)
     226  {
     227    var frm = document.forms['batch'];
     228    var list = frm.protocol_id;
     229    if (list.length < 2 || list[1].value == '0')
     230    {
     231      Forms.addListOption(list, 1, new Option());
     232    }
     233    list[1].value = event.detail.id;
     234    list[1].text = event.detail.name;
     235    list.selectedIndex = 1;
     236  }
     237 
     238  arrayBatches.selectPrintRobot = function()
     239  {
     240    var frm = document.forms['batch'];
     241    var url = '';
     242    if (frm.printrobot_id.length > 1)
     243    {
     244      var id = Math.abs(parseInt(frm.printrobot_id[1].value));       
     245      url += '&item_id='+id;
     246    }
     247    url += '&resetTemporary=1&tmpfilter:INT:itemSubtype='+Data.get('page-data', 'print-robot');
     248    Dialogs.selectItem('HARDWARE', 'printrobot_id', 0, url);
     249  }
     250 
     251  arrayBatches.setPrintRobotCallback = function(event)
     252  {
     253    var frm = document.forms['batch'];
     254    var list = frm.printrobot_id;
     255    if (list.length < 2 || list[1].value == '0')
     256    {
     257      Forms.addListOption(list, 1, new Option());
     258    }
     259    list[1].value = event.detail.id;
     260    list[1].text = event.detail.name;
     261    list.selectedIndex = 1;
     262  }
     263 
    106264  return arrayBatches;
    107265}();
  • trunk/www/lims/arraybatches/edit_batch.jsp

    r6254 r6312  
    138138  {
    139139    batch = ArrayBatch.getById(dc, itemId);
     140    batch.checkPermission(Permission.WRITE);
    140141    cc.setObject("item", batch);
    141142    title = "Edit array batch -- " + HTML.encodeTags(batch.getName());
     
    164165      readCurrentProtocol = false;
    165166    }
    166   }
    167   if (batch != null && !batch.hasPermission(Permission.WRITE))
    168   {
    169     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    170   }
    171  
     167  }
    172168 
    173169  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), batch);
    174170  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    175171  %>
    176   <base:page type="popup" title="<%=title%>">
    177   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     172  <base:page type="popup" title="<%=title%>" id="edit-page">
     173  <base:head scripts="tabcontrol-2.js,~batches.js" styles="tabcontrol.css">
    178174    <ext:scripts context="<%=jspContext%>" />
    179175    <ext:stylesheets context="<%=jspContext%>" />
    180     <script>
    181     // Validate the "ArrayBatch" tab
    182     function validateArrayBatch()
    183     {
    184       var frm = document.forms['batch'];
    185       if (Main.trimString(frm.name.value) == '')
    186       {
    187         Forms.showNotification(frm.name, 'You must enter a name');
    188         return false;
    189       }
    190       if (frm.arraydesign_id && !frm.arraydesign_id.value)
    191       {
    192         Forms.showNotification('arraydesign_id.select', 'You must select an array design');
    193         return false;
    194       }
    195       return true;
    196     }
    197 
    198     // Submit the form
    199     function saveSettings()
    200     {
    201       var frm = document.forms['batch'];
    202       if (TabControl.validateActiveTab('settings'))
    203       {
    204         Annotations.saveModifiedAnnotationsToForm(frm);
    205         Annotations.saveInheritedAnnotationsToForm(frm);
    206         frm.submit();
    207       }
    208     }
     176  </base:head>
     177  <base:body>
     178    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
     179    <div id="page-data" class="datacontainer"
     180      data-printing-protocol="<%=SystemItems.getId(Protocol.PRINTING)%>"
     181      data-print-robot="<%=SystemItems.getId(Hardware.PRINT_ROBOT)%>"
     182    ></div>
    209183   
    210     function loadAnnotationsFrame()
    211     {
    212       Annotations.autoLoadEditFrame(getProtocolId());
    213     }
    214    
    215     function loadInheritedAnnotationsFrame()
    216     {
    217       Annotations.autoLoadInheritFrame(getParents());
    218     }
    219 
    220     function getProtocolId()
    221     {
    222       var frm = document.forms['batch'];
    223       var protocolId = 0;
    224       if (frm.protocol_id.length > 0 && !frm.protocol_id.disabled)
    225       {
    226         protocolId = Math.abs(parseInt(frm.protocol_id[frm.protocol_id.selectedIndex].value));       
    227       }
    228       return protocolId;
    229     }
    230 
    231     function getParents()
    232     {
    233       var frm = document.forms['batch'];
    234       var parents = new Array();
    235       if (frm.arraydesign_id)
    236       {
    237         var arrayDesignId = Math.abs(parseInt(frm.arraydesign_id[frm.arraydesign_id.selectedIndex].value));
    238         if (arrayDesignId > 0) parents[parents.length] = 'ARRAYDESIGN:'+arrayDesignId;
    239       }
    240       return parents;
    241     }
    242 
    243     function selectArrayDesignOnClick()
    244     {
    245       var frm = document.forms['batch'];
    246       var url = '../../lims/arraydesigns/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setArrayDesignCallback';
    247       if (frm.arraydesign_id.length > 0)
    248       {
    249         var id = Math.abs(parseInt(frm.arraydesign_id[0].value));       
    250         url += '&item_id='+id;
    251       }
    252       Main.openPopup(url, 'SelectArrayDesign', 1050, 700);
    253     }
    254     function setArrayDesignCallback(id, name)
    255     {
    256       var frm = document.forms['batch'];
    257       var list = frm.arraydesign_id;
    258       if (list.length < 1 || list[0].value == '0') // >
    259       {
    260         Forms.addListOption(list, 0, new Option());
    261       }
    262       list[0].value = id;
    263       list[0].text = name;
    264       list.selectedIndex = 0;
    265     }
    266 
    267     function selectProtocolOnClick()
    268     {
    269       var frm = document.forms['batch'];
    270       var url = '../../admin/protocols/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setProtocolCallback';
    271       if (frm.protocol_id.length > 1)
    272       {
    273         var id = Math.abs(parseInt(frm.protocol_id[1].value));       
    274         url += '&item_id='+id;
    275       }
    276       url += '&resetTemporary=1&tmpfilter:INT:itemSubtype=<%=SystemItems.getId(Protocol.PRINTING)%>';
    277       Main.openPopup(url, 'SelectProtocol', 1050, 700);
    278     }
    279     function setProtocolCallback(id, name)
    280     {
    281       var frm = document.forms['batch'];
    282       var list = frm.protocol_id;
    283       if (list.length < 2 || list[1].value == '0') // >
    284       {
    285         Forms.addListOption(list, 1, new Option());
    286       }
    287       list[1].value = id;
    288       list[1].text = name;
    289       list.selectedIndex = 1;
    290     }
    291     function selectPrintRobotOnClick()
    292     {
    293       var frm = document.forms['batch'];
    294       var url = '../../admin/hardware/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setPrintRobotCallback';
    295       if (frm.printrobot_id.length > 1)
    296       {
    297         var id = Math.abs(parseInt(frm.printrobot_id[1].value));       
    298         url += '&item_id='+id;
    299       }
    300       url += '&resetTemporary=1&tmpfilter:INT:itemSubtype=<%=SystemItems.getId(Hardware.PRINT_ROBOT)%>';
    301       Main.openPopup(url, 'SelectPrintRobot', 1050, 700);
    302     }
    303     function setPrintRobotCallback(id, name)
    304     {
    305       var frm = document.forms['batch'];
    306       var list = frm.printrobot_id;
    307       if (list.length < 2 || list[1].value == '0') // >
    308       {
    309         Forms.addListOption(list, 1, new Option());
    310       }
    311       list[1].value = id;
    312       list[1].text = name;
    313       list.selectedIndex = 1;
    314     }
    315 
    316    
    317     function init()
    318     {
    319       var frm = document.forms['batch'];
    320       <%
    321       if (batch == null)
    322       {
    323         %>
    324         frm.name.focus();
    325         frm.name.select();
    326         <%
    327       }
    328       %>
    329     }
    330     </script>
    331   </base:head>
    332   <base:body onload="init()">
    333     <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    334184    <form action="index.jsp?ID=<%=ID%>" method="post" name="batch">
    335185    <input type="hidden" name="cmd" value="UpdateItem">
     
    337187    <t:tabcontrol id="settings"
    338188      subclass="content dialogtabcontrol"
    339       position="bottom"  remember="<%=batch != null%>"
     189      position="bottom" remember="<%=batch != null%>"
    340190      extensions="<%=invoker%>">
    341     <t:tab id="info" title="Array batch" validate="validateArrayBatch()" helpid="arraybatch.edit">
     191    <t:tab id="info" title="Array batch" helpid="arraybatch.edit">
    342192      <table class="fullform input100">
    343193      <tr>
    344194        <th>Name</th>
    345         <td><input class="text required" type="text" name="name"
     195        <td><input class="text required auto-init" data-auto-init="<%=batch == null ? "focus-select" : "focus" %>"
     196          type="text" name="name"
    346197          value="<%=HTML.encodeTags(batch == null ? Values.getString(cc.getPropertyValue("name"), "New array batch") : batch.getName())%>"
    347198          maxlength="<%=ArrayBatch.MAX_NAME_LENGTH%>"></td>
     
    370221              defaultitems="<%=defaultArrayDesigns%>"
    371222              newitem="true"
    372               onselect="selectArrayDesignOnClick()"
    373223            />
    374224            <%
     
    390240            defaultitems="<%=defaultPrintRobots%>"
    391241            newitem="<%=batch == null%>"
    392             onselect="selectPrintRobotOnClick()"
    393242          />
    394243        </td>
     
    407256            defaultitems="<%=defaultProtocols%>"
    408257            newitem="<%=batch == null%>"
    409             onselect="selectProtocolOnClick()"
    410258          />
    411259        </td>
     
    425273    </t:tab>
    426274   
    427     <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     275    <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit">
    428276      <jsp:include page="../../common/annotations/annotate_frameset.jsp">
    429277        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    434282   
    435283    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    436       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     284      helpid="annotations.edit.inherited">
    437285      <jsp:include page="../../common/annotations/inherit_frameset.jsp">
    438286        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    449297
    450298    <base:buttongroup subclass="dialogbuttons">
    451       <base:button onclick="saveSettings()" title="Save" />
    452       <base:button onclick="window.close()" title="Cancel" />
     299      <base:button id="btnSave" title="Save" />
     300      <base:button id="close" title="Cancel" />
    453301    </base:buttongroup>
    454302  </base:body>
  • trunk/www/lims/arraydesigns/designs.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', arrayDesigns.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', Annotations.autoLoadEditFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', Annotations.autoLoadInheritFrame);
     44      TabControl.addTabActivateListener('settings.datafiles', arrayDesigns.loadDataFilesFrame);
     45      TabControl.addTabValidator('settings.info', arrayDesigns.validateArrayDesign);
     46     
     47      // Num arrays
     48      Events.addEventHandler('numArrays', 'keypress', Events.integerOnly);
    3849    }
    3950    else if (pageId == 'view-page')
     
    109120  }
    110121
     122  arrayDesigns.validateArrayDesign = function()
     123  {
     124    var frm = document.forms['design'];
     125    if (Main.trimString(frm.name.value) == '')
     126    {
     127      Forms.showNotification(frm.name, 'You must enter a name');
     128      return false;
     129    }
     130    else if (!Numbers.isInteger(frm.numArrays.value))
     131    {
     132      Forms.showNotification(frm.numArrays, "'" + frm.numArrays.value + "' is not a valid number");
     133      return false;
     134    }
     135    else if (parseInt(frm.numArrays.value) <= 0)
     136    {
     137      Forms.showNotification(frm.numArrays, "Number of arrays must be &gt;0");
     138      return false;
     139    }
     140    return true;
     141  }
     142
     143  arrayDesigns.save = function()
     144  {
     145    var frm = document.forms['design'];
     146    if (TabControl.validateActiveTab('settings'))
     147    {
     148      Annotations.saveModifiedAnnotationsToForm(frm);
     149      Annotations.saveInheritedAnnotationsToForm(frm);
     150      DataFiles.writeFileActionsToForm(frm);
     151      frm.submit();
     152    }
     153  }
     154 
     155  arrayDesigns.loadDataFilesFrame = function()
     156  {
     157    var frm = document.forms['design'];
     158    var selected = frm.platform[frm.platform.selectedIndex];
     159    var platform = Data.get(selected, 'platform');
     160    var variant = Data.get(selected, 'variant');
     161    DataFiles.autoLoadEditFrame(platform ? platform : 0, variant ? variant : 0, 0);
     162  }
     163
    111164 
    112165  return arrayDesigns;
  • trunk/www/lims/arraydesigns/edit_design.jsp

    r6256 r6312  
    4141  import="net.sf.basedb.core.PermissionDeniedException"
    4242  import="net.sf.basedb.core.BaseException"
     43  import="net.sf.basedb.core.query.Restrictions"
    4344  import="net.sf.basedb.core.query.Orders"
    4445  import="net.sf.basedb.core.query.Hql"
     
    122123  {
    123124    design = ArrayDesign.getById(dc, itemId);
     125    design.checkPermission(Permission.WRITE);
    124126    cc.setObject("item", design);
    125127    title = "Edit array design -- " + HTML.encodeTags(design.getName());
     
    134136      deniedPlatform = true;
    135137    }
    136     design.checkPermission(Permission.WRITE);
    137138  }
    138139
     
    146147  variantQuery.include(Include.REMOVED, Include.NOT_REMOVED);
    147148  variantQuery.order(Orders.asc(Hql.property("name")));
    148   variantQuery.setCacheResult(true);
    149   ItemResultList<PlatformVariant> variants = variantQuery.list(dc);
     149  variantQuery.restrict(Restrictions.eq(Hql.property("platform"), Hql.entityParameter("platform", Item.PLATFORM)));
    150150 
    151151  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), design);
    152152  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    153153  %>
    154   <base:page type="popup" title="<%=title%>">
    155   <base:head scripts="tabcontrol.js,platforms.js" styles="tabcontrol.css">
     154  <base:page type="popup" title="<%=title%>" id="edit-page">
     155  <base:head scripts="tabcontrol-2.js,~designs.js" styles="tabcontrol.css">
    156156    <ext:scripts context="<%=jspContext%>" />
    157157    <ext:stylesheets context="<%=jspContext%>" />
    158     <script>
    159     // Validate the "ArrayDesign" tab
    160     function validateArrayDesign()
    161     {
    162       var frm = document.forms['design'];
    163       if (Main.trimString(frm.name.value) == '')
    164       {
    165         Forms.showNotification(frm.name, 'You must enter a name');
    166         return false;
    167       }
    168       else if (!Numbers.isInteger(frm.numArrays.value))
    169       {
    170         Forms.showNotification(frm.numArrays, "'" + frm.numArrays.value + "' is not a valid number");
    171         return false;
    172       }
    173       else if (parseInt(frm.numArrays.value) <= 0)
    174       {
    175         Forms.showNotification(frm.numArrays, "Number of arrays must be &gt;0");
    176         return false;
    177       }
    178       return true;
    179     }
    180 
    181     // Submit the form
    182     function saveSettings()
    183     {
    184       var frm = document.forms['design'];
    185       if (TabControl.validateActiveTab('settings'))
    186       {
    187         Annotations.saveModifiedAnnotationsToForm(frm);
    188         Annotations.saveInheritedAnnotationsToForm(frm);
    189         DataFiles.writeFileActionsToForm(frm);
    190         frm.submit();
    191       }
    192     }
    193    
    194     function loadAnnotationsFrame()
    195     {
    196       Annotations.autoLoadEditFrame();
    197     }
    198    
    199     function loadInheritedAnnotationsFrame()
    200     {
    201       Annotations.autoLoadInheritFrame();
    202     }
    203    
    204     function loadDataFilesFrame()
    205     {
    206       var frm = document.forms['design'];
    207       var platform = Platforms.getSelectedPlatform(frm.platform);
    208       var variant = Platforms.getSelectedVariant(frm.platform);
    209       DataFiles.autoLoadEditFrame(platform ? platform.id : 0, variant ? variant.id : 0, 0);
    210     }
    211 
    212     function init()
    213     {
    214       var frm = document.forms['design'];
    215       <%
    216       if (design == null)
    217       {
    218         %>
    219         frm.name.focus();
    220         frm.name.select();
    221         <%
    222       }
    223       %>
    224       initPlatforms(<%=currentPlatform == null ? 0 : currentPlatform.getId()%>, <%=currentVariant == null ? 0 : currentVariant.getId()%>);
    225     }
    226    
    227     function initPlatforms(platformId, variantId)
    228     {
    229       <%
    230       for (Platform p : platforms)
    231       {
    232         if (!p.isRemoved() || p.equals(currentPlatform))
    233         {
    234           RawDataType rdt = p.isFileOnly() ? null : p.getRawDataType();
    235           %>
    236           var p<%=p.getId()%> = new Platform(<%=p.getId()%>, '<%=HTML.javaScriptEncode(p.getExternalId())%>', '<%=HTML.javaScriptEncode(p.getName())%>', <%=p.isFileOnly()%>, '<%=rdt == null ? "" : rdt.getId()%>');
    237           <%
    238         }
    239       }
    240       for (PlatformVariant v : variants)
    241       {
    242         Platform p = v.getPlatform();
    243         if ((!v.isRemoved() || v.equals(currentVariant)) && (!p.isRemoved() || p.equals(currentPlatform)))
    244         {
    245           RawDataType rdt = v.isFileOnly() ? null : v.getRawDataType();
    246           %>
    247           var v<%=v.getId()%> = new Variant(p<%=p.getId()%>, <%=v.getId()%>, '<%=HTML.javaScriptEncode(v.getExternalId())%>', '<%=HTML.javaScriptEncode(v.getName())%>', <%=v.isFileOnly()%>, '<%=rdt == null ? "" : rdt.getId()%>');
    248           <%
    249         }
    250       }
    251       %>
    252       var frm = document.forms['design'];
    253       Platforms.populateList(frm.platform, platformId, variantId);
    254     }
    255     </script>
     158    <style>
     159    .platform
     160    {
     161      font-weight: bold;
     162      margin-top: 2px;
     163    }
     164    </style>
    256165  </base:head>
    257   <base:body onload="init()">
     166  <base:body>
    258167    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    259168    <form action="index.jsp?ID=<%=ID%>" method="post" name="design">
     
    264173      position="bottom" active="<%=tabId%>" remember="<%=tabId == null && design != null%>"
    265174      extensions="<%=invoker%>">
    266     <t:tab id="info" title="Array design" validate="validateArrayDesign()" helpid="arraydesign.edit">
     175    <t:tab id="info" title="Array design" helpid="arraydesign.edit">
    267176      <table class="fullform input100">
    268177      <tr>
    269178        <th>Name</th>
    270         <td><input class="text required" type="text" name="name"
     179        <td><input class="text required auto-init" data-auto-init="<%=design == null ? "focus-select" : "focus" %>"
     180          type="text" name="name"
    271181          value="<%=HTML.encodeTags(design == null ? Values.getString(cc.getPropertyValue("name"), "New array design") : design.getName())%>"
    272182          maxlength="<%=ArrayDesign.MAX_NAME_LENGTH%>"></td>
     
    285195            <%
    286196          }
     197          else
     198          {
     199            for (Platform p : platforms)
     200            {
     201              if (!p.isRemoved() || p.equals(currentPlatform))
     202              {
     203                boolean selected = p.equals(currentPlatform) && currentVariant == null;
     204                %>
     205                <option class="platform"
     206                  value="PLATFORM:<%=p.getId()%>"
     207                  data-platform="<%=p.getId()%>"
     208                  <%=selected ? "selected" : ""%>><%=HTML.encodeTags(p.getName()) %>
     209                <%
     210              }
     211              variantQuery.setEntityParameter("platform", p);
     212              List<PlatformVariant> variants = variantQuery.list(dc);
     213              PlatformVariant lastVariant = variants.size()>0 ? variants.get(variants.size()-1) : null;
     214              for (PlatformVariant v : variants)
     215              {
     216                if ((!v.isRemoved() || v.equals(currentVariant)) && (!p.isRemoved() || p.equals(currentPlatform)))
     217                {
     218                  boolean selected = v.equals(currentVariant);
     219                  String prefix = v == lastVariant ? " └ " : " ├ ";
     220                  %>
     221                  <option class="variant"
     222                    value="VARIANT:<%=v.getId()%>"
     223                    data-platform="<%=p.getId()%>"
     224                    data-variant="<%=v.getId()%>"
     225                    <%=selected ? "selected" : ""%>><%=prefix%><%=HTML.encodeTags(v.getName()) %>
     226                  <%
     227                }
     228              }
     229            }
     230          }
    287231          %>
    288232          </select>
     
    292236      <tr>
    293237        <th>Arrays / slide</th>
    294         <td><input class="text required" type="text" name="numArrays" style="width: 15em;"
     238        <td><input class="text required" type="text" name="numArrays" id="numArrays" style="width: 15em;"
    295239          value="<%=design == null ? Values.getString(cc.getPropertyValue("numArrays"), "1") : design.getNumArrays()%>"
    296           maxlength="10" onkeypress="return Numbers.integerOnly(event)"></td>
     240          maxlength="10"></td>
    297241        <td></td>
    298242      </tr>
     
    325269    </t:tab>
    326270
    327     <t:tab id="datafiles" title="Data files" helpid="datafiles.edit" activate="loadDataFilesFrame()">
     271    <t:tab id="datafiles" title="Data files" helpid="datafiles.edit">
    328272      <jsp:include page="../../common/datafiles/select_frameset.jsp">
    329273        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    333277    </t:tab>
    334278
    335     <t:tab id="annotations" title="Annotations" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     279    <t:tab id="annotations" title="Annotations" helpid="annotations.edit">
    336280      <jsp:include page="../../common/annotations/annotate_frameset.jsp">
    337281        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    342286   
    343287    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    344       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     288      helpid="annotations.edit.inherited">
    345289      <jsp:include page="../../common/annotations/inherit_frameset.jsp">
    346290        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    357301
    358302    <base:buttongroup subclass="dialogbuttons">
    359       <base:button onclick="saveSettings()" title="Save" />
    360       <base:button onclick="window.close()" title="Cancel" />
     303      <base:button id="btnSave" title="Save" />
     304      <base:button id="close" title="Cancel" />
    361305    </base:buttongroup>
    362306  </base:body>
  • trunk/www/lims/arraydesigns/index.jsp

    r6192 r6312  
    169169   
    170170    String[] pv = request.getParameter("platform").split(":");
    171     int platformId = Values.getInt(pv[0], -1);
    172     int variantId = pv.length > 1 ? Values.getInt(pv[1], -1) : -1;
    173     Platform platform = platformId > 0 ? Platform.getById(dc, platformId) : null;
    174     PlatformVariant variant = variantId > 0 ? PlatformVariant.getById(dc, variantId) : null;
     171    Platform platform = null;
     172    PlatformVariant variant = null;
     173    if ("PLATFORM".equals(pv[0]))
     174    {
     175      int platformId = Values.getInt(pv[1]);
     176      platform = Platform.getById(dc, platformId);
     177    }
     178    else
     179    {
     180      int variantId = Values.getInt(pv[1]);
     181      variant = PlatformVariant.getById(dc, variantId);
     182      platform = variant.getPlatform();
     183    }
    175184    if (platform != null) cc.setRecent(platform, maxRecent);
    176185    if (variant != null) cc.setRecent(variant, maxRecent);
     
    394403   
    395404    List<Plate> plates = new java.util.LinkedList<Plate>();
    396     String[] plateIds = request.getParameterValues("plates");
    397     if (plateIds != null)
    398     {
    399       for (String pId : plateIds)
    400       {
    401         plates.add(Plate.getById(dc, Values.getInt(pId)));
    402       }
     405    for (String pId : request.getParameter("+PLATE").split(","))
     406    {
     407      plates.add(Plate.getById(dc, Values.getInt(pId)));
    403408    }
    404409    design.setPlateList(plates);
  • trunk/www/lims/arraydesigns/manage_plates.jsp

    r6217 r6312  
    4444  import="net.sf.basedb.clients.web.util.HTML"
    4545  import="net.sf.basedb.util.Values"
     46  import="net.sf.basedb.util.json.JsonUtil"
     47  import="net.sf.basedb.util.json.JsonConverter"
     48  import="org.json.simple.JSONObject"
    4649  import="java.util.List"
    4750  import="java.util.Set"
     
    6265{
    6366  ArrayDesign design = ArrayDesign.getById(dc, itemId);
     67  design.checkPermission(Permission.WRITE);
    6468  cc.setObject("item", design);
    6569  String title = "Attach plate -- " + HTML.encodeTags(design.getName());
    66   if (!design.hasPermission(Permission.WRITE))
     70 
     71  // Load current plates
     72  JSONObject jsonPlates = new JSONObject();
     73  jsonPlates.put("itemType", "PLATE");
     74  ItemQuery<ArrayDesignPlate> platesQuery = design.getArrayDesignPlates();
     75  platesQuery.include(Include.MINE, Include.SHARED, Include.OTHERS, Include.IN_PROJECT);
     76  platesQuery.order(Orders.asc(Hql.property("position")));
     77  jsonPlates.put("items", JsonUtil.toArray(platesQuery.iterate(dc), new JsonConverter<ArrayDesignPlate>()
    6778  {
    68     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    69   }
    70  
    71  
     79    public Object convert(ArrayDesignPlate adp)
     80    {
     81      Plate plate = adp.getPlate();
     82      JSONObject json = new JSONObject();
     83      json.put("id", plate.getId());
     84      json.put("name", plate.getName());
     85      return json;
     86    }
     87  }));
    7288  %>
    73 
    7489  <base:page type="popup" title="<%=title%>">
    75   <base:head scripts="tabcontrol.js,linkitems.js" styles="tabcontrol.css">
    76     <script>
    77     // Validate the "Plates" tab
    78     function validatePlates()
    79     {
    80       return true;
    81     }
    82 
    83     // Submit the form
    84     function saveSettings()
    85     {
    86       var frm = document.forms['design'];
    87       if (validatePlates())
    88       {
    89         var plates = frm.plates;
    90         for (var i = 0; i < plates.length; ++i) // >
    91         {
    92           plates[i].selected = true;
    93         }
    94         frm.submit();
    95       }
    96     }
    97    
    98     function addPlatesOnClick()
    99     {
    100       var ids = Link.getListIds(document.forms['design'].plates, '');
    101       var excludes = ids.join(',');
    102       var url = '../plates/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple&callback=addPlateCallback';
    103       url += '&excludes='+excludes;
    104       Main.openPopup(url, 'AddPlates', 1050, 700);
    105     }
    106 
    107     function addPlateCallback(plateId, name)
    108     {
    109       var item = Link.getItem('', plateId);
    110       if (!item) item = new Item('', plateId, name);
    111       Link.addItem(document.forms['design'].plates, item);
    112     }
    113    
    114     function removePlatesOnClick()
    115     {
    116       Link.removeSelected(document.forms['design'].plates);
    117     }
    118 
    119     function init()
    120     {
    121       var frm = document.forms['design'];
    122       var plates = frm.plates;
    123       <%
    124       ItemQuery<ArrayDesignPlate> platesQuery = design.getArrayDesignPlates();
    125       platesQuery.include(Include.MINE, Include.SHARED, Include.OTHERS, Include.IN_PROJECT);
    126       platesQuery.order(Orders.asc(Hql.property("position")));
    127       ItemResultList<ArrayDesignPlate> plates = platesQuery.list(dc);
    128       for (ArrayDesignPlate adPlate : plates)
    129       {
    130         Plate plate = adPlate.getPlate();
    131         %>
    132         Link.addNewItem(plates, new Item('', <%=plate.getId()%>, '<%=HTML.javaScriptEncode(plate.getName())%>'));
    133         <%
    134       }
    135       %>
    136     }
    137     </script>
    138   </base:head>
    139   <base:body onload="init()">
     90  <base:head scripts="linkitems-2.js,~manage_plates.js" />
     91  <base:body>
    14092    <h1><%=title%> <base:help helpid="arraydesign.edit.plates" /></h1>
    14193    <form action="index.jsp?ID=<%=ID%>" method="post" name="design">
     
    157109            <base:buttongroup vertical="true">
    158110              <base:button
    159                 onclick="Forms.moveListOptions(document.forms['design'].plates, false)"
     111                id="moveUp"
     112                data-down="0"
    160113                image="move_up.png"
    161114                tooltip="Move up"
     
    163116              />
    164117              <base:button
    165                 onclick="Forms.moveListOptions(document.forms['design'].plates, true)"
     118                id="moveDown"
     119                data-down="1"
    166120                image="move_down.png"
    167121                tooltip="Move down"
     
    171125          </td>
    172126          <td>
    173             <select name="plates" size="15" multiple>
     127            <select name="plates" id="plates"
     128              class="auto-init"
     129              data-auto-init="link-container"
     130              data-initial-items="[<%=HTML.encodeTags(jsonPlates.toJSONString()) %>]"
     131              size="15" multiple>
    174132            </select>
    175133          </td>
     
    177135            <base:buttongroup vertical="true">
    178136              <base:button
    179                 subclass="leftaligned"
     137                subclass="leftaligned auto-init"
     138                data-auto-init="add-link"
     139                data-list-id="plates"
     140                data-item-type="PLATE"
    180141                style="width: 12em;"
    181                 onclick="addPlatesOnClick()"
    182142                title="Add plates..."
    183143                tooltip="Add plates to be used"
    184144              />
    185145              <base:button
    186                 subclass="leftaligned"
     146                subclass="leftaligned auto-init"
     147                data-auto-init="remove-link"
     148                data-list-id="plates"
    187149                style="width: 12em;"
    188                 onclick="removePlatesOnClick()"
    189150                title="Remove"
    190151                tooltip="Remove the selected plates"
     
    202163
    203164    <base:buttongroup subclass="dialogbuttons">
    204       <base:button onclick="saveSettings()" title="Save" />
    205       <base:button onclick="window.close()" title="Cancel" />
     165      <base:button id="btnSave" title="Save" />
     166      <base:button id="close" title="Cancel" />
    206167    </base:buttongroup>
    207168  </base:body>
  • trunk/www/lims/arrayslides/create_wizard.jsp

    r6217 r6312  
    2323  @version 2.0
    2424--%>
    25 
    26 
    27 
    2825<%@ page pageEncoding="UTF-8" session="false"
    2926  import="net.sf.basedb.core.SessionControl"
     
    4441  import="net.sf.basedb.util.Values"
    4542  import="java.util.List"
    46  
    4743%>
    4844<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
     
    6258{
    6359  String title = null;
    64   ArraySlide slide = null;
    6560  String name = "New slides.";
    6661 
     
    8580  {
    8681    name = HTML.encodeTags(currentArrayBatch.getName()) + ".";
    87   }
    88 
    89   if (slide != null && !slide.hasPermission(Permission.WRITE))
    90   {
    91     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    92   }
    93  
    94    
     82  }   
    9583  %>
    96 
    97   <base:page type="popup" title="<%=title%>">
    98   <base:head scripts="tabcontrol.js" styles="tabcontrol.css,toolbar.css">
    99     <script>
    100     // Validate the "ArraySlide" tab
    101     function validateArraySlide()
    102     {
    103       var frm = document.forms['WizardStep1'];
    104       if (Main.trimString(frm.name.value) == '')
    105       {
    106         Forms.showNotification(frm.name, 'You must enter a name');
    107         return false;
    108       }
    109       if (frm.arraybatch_id && !frm.arraybatch_id.value)
    110       {
    111         Forms.showNotification('arraybatch_id.select', 'You must select an array batch');
    112         return false;
    113       }
    114       if (Main.trimString(frm.quantity.value) == '')
    115       {
    116         Forms.showNotification(frm.quantity, 'You must enter a quantity of slides');
    117         return false;
    118       }
    119       if (frm.quantity.value < 1 || frm.quantity.value > 999)
    120       {
    121         Forms.showNotification(frm.quantity, 'The quantity of array slides to be created must be between 1 and 999');
    122         return false;
    123       }
    124       return true;
    125     }
    126    
    127     function validateNames()
    128     {
    129       var frm = document.forms['WizardStep2'];
    130       var quantity = parseInt(frm.quantity.value);
    131       for (i = 0; i < quantity; i++)
    132       {
    133         var name = frm['name'+i];
    134         if (Main.trimString(name.value) == '')
    135         {
    136           Forms.showNotification(name, 'You must enter a name for all slides', null, 'pointer-left');
    137           return false;
    138         }
    139       }
    140       return true;
    141     }
    142    
    143     // Submit the step 1 form and continue to step 2
    144     function nextStep()
    145     {     
    146       if (validateArraySlide())
    147       {
    148         var frm = document.forms['WizardStep1'];
    149         frm.submit();
    150       }
    151     }   
    152     // Submit and finish the wizard
    153     function saveSettings()
    154     {
    155       if (validateNames())
    156       {
    157         var frm = document.forms['WizardStep2'];   
    158         frm.submit();
    159       }
    160     }
    161 
    162     function selectArrayBatchOnClick()
    163     {
    164       var frm = document.forms['WizardStep1'];
    165       var url = '../../lims/arraybatches/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setArrayBatchCallback';
    166       if (frm.arraybatch_id.length > 0) url += '&item_id='+frm.arraybatch_id[0].value;
    167       Main.openPopup(url, 'SelectArrayBatch', 1050, 700);
    168     }
    169     function setArrayBatchCallback(id, name)
    170     {
    171       var frm = document.forms['WizardStep1'];
    172       var list = frm.arraybatch_id;
    173       if (list.length < 1 || list[0].value == '0') // >
    174       {
    175         Forms.addListOption(list, 0, new Option());
    176       }
    177       list[0].value = id;
    178       list[0].text = name;
    179       list.selectedIndex = 0;
    180     }
    181    
    182     function pasteMultiple(prefix)
    183     {
    184       Main.openPopup('paste_multiple.jsp?ID=<%=ID%>&form=WizardStep2&prefix=' + prefix, 'PasteMultiple', 400, 600);
    185     }
    186 
    187     function clearAll(prefix)
    188     {
    189       var frm = document.forms['WizardStep2'];
    190       var i = 0;
    191       var field;
    192       while(field = frm[prefix+i])
    193       {
    194         field.value = '';
    195         i++;
    196       }
    197     }
    198    
    199     function init()
    200     {         
    201       var frm = document.forms['WizardStep1'];
    202       if (frm != null)
    203       {
    204         frm.name.focus();
    205         frm.name.select();
    206       }
    207       else
    208       {
    209         frm = document.forms['WizardStep2'];
    210         frm.barcode1.focus();
    211       }
    212     }
    213     </script>
    214   </base:head>
    215   <base:body onload="init()">
     84  <base:page type="popup" title="<%=title%>" id="<%=HTML.encodeTags(cmd)%>">
     85  <base:head scripts="~wizard.js" />
     86  <base:body>
    21687    <%
    21788    //Wizard step1
     
    21990    {
    22091    %>       
    221       <h1><%=title%> <base:help tabcontrol="settings" /></h1>
     92      <h1><%=title%> <base:help helpid="arrayslide.createwizard.1" /></h1>
    22293      <form action="create_wizard.jsp?ID=<%=ID%>" method="post" name="WizardStep1">
    22394      <input type="hidden" name="cmd" value="WizardStep2">
     
    22798        <tr>
    22899          <th>Name</th>
    229           <td><input class="text required" type="text" name="name"
     100          <td><input class="text required auto-init" data-auto-init="focus-select"
     101            type="text" name="name"
    230102            value="<%=name%>"
    231103            maxlength="<%=ArraySlide.MAX_NAME_LENGTH%>"></td>
     
    243115              recent="<%=recentArrayBatches%>"
    244116              newitem="true"
    245               onselect="selectArrayBatchOnClick()"
    246117            />
    247118          </td>
     
    250121        <tr>
    251122          <th>Quantity</th>
    252           <td><input class="text required" type="text" name="quantity" value="50"
    253              maxlength="3" style="width: 5em;"
    254             onkeypress="return Numbers.integerOnly(event)"><i> (1-999)</i></td>
     123          <td><input class="text required" type="text" name="quantity" id="quantity"
     124            value="50" maxlength="3" style="width: 5em;"><i> (1-999)</i></td>
    255125          <td></td>
    256126        </tr>
    257127        <tr>
    258128          <th>Start at</th>
    259           <td><input class="text" type="text" name="start_at" value="1"
    260             maxlength="10" style="width: 10em;"
    261             onkeypress="return Numbers.integerOnly(event)">
     129          <td><input class="text" type="text" name="start_at" id="start_at"
     130            value="1" maxlength="10" style="width: 10em;">
    262131          </td>
    263132          <td></td>
     
    266135          <th class="subprompt">- pad size</th>
    267136          <td>
    268             <input class="text" type="text" name="pad_length" value=""
    269             maxlength="1" style="width: 10em;"
    270             onkeypress="return Numbers.integerOnly(event)">
     137            <input class="text" type="text" name="pad_length" id="pad_length"
     138            value="" maxlength="1" style="width: 10em;">
    271139          </td>
    272140          <td>
     
    307175      int startAt = Values.getInt(request.getParameter("start_at"), 1);
    308176      %> 
    309       <h1><%=title%> <base:help tabcontrol="settings" /></h1>
     177      <h1><%=title%> <base:help helpid="arrayslide.createwizard.2" /></h1>
    310178      <form action="index.jsp?ID=<%=ID%>" method="post" name="WizardStep2">       
    311179      <input type="hidden" name="cmd" value="CreateItems">
     
    326194            <th>&nbsp;</th>
    327195            <th>Name:
    328               <base:icon image="paste.png" onclick="pasteMultiple('name')"
    329                 tooltip="Paste multiple values in a single large textarea" />
    330               <base:icon image="clear_down.png" onclick="clearAll('name')"
    331                 tooltip="Clear all values" />
     196              <base:icon
     197                id="pasteMultipleName"
     198                data-form-prefix="name"
     199                image="paste.png"
     200                tooltip="Paste multiple values in a single large textarea"
     201              />
     202              <base:icon
     203                id="clearAllNames"
     204                data-form-prefix="name"
     205                image="clear_down.png"
     206                tooltip="Clear all values"
     207              />
    332208            </th>
    333209            <th>Barcode:
    334               <base:icon image="paste.png" onclick="pasteMultiple('barcode')"
    335                 tooltip="Paste multiple values in a single large textarea" />
    336               <base:icon image="clear_down.png" onclick="clearAll('barcode')"
    337                 tooltip="Clear all values" />
     210              <base:icon
     211                id="pasteMultipleBarcode"
     212                data-form-prefix="barcode"
     213                image="paste.png"
     214                tooltip="Paste multiple values in a single large textarea"
     215              />
     216              <base:icon
     217                id="clearAllBarcodes"
     218                data-form-prefix="barcode"
     219                image="clear_down.png"
     220                tooltip="Clear all values"
     221              />
    338222            </th>
    339223          </tr>
     
    381265   
    382266    <base:buttongroup subclass="dialogbuttons">
    383       <base:button onclick="saveSettings();" title="Save" visible="<%=cmd.equals("WizardStep2")%>" />
    384       <base:button onclick="nextStep();" title="Next" image="gonext.png" visible="<%=cmd.equals("WizardStep1")%>" />
    385       <base:button onclick="window.close();" title="Cancel" />
     267      <base:button id="btnSave" title="Save" visible="<%=cmd.equals("WizardStep2")%>" />
     268      <base:button id="btnNext" title="Next" image="gonext.png" visible="<%=cmd.equals("WizardStep1")%>" />
     269      <base:button id="close" title="Cancel" />
    386270    </base:buttongroup>
    387271  </base:body>
  • trunk/www/lims/arrayslides/edit_slide.jsp

    r6254 r6312  
    9797  {
    9898    slide = ArraySlide.getById(dc, itemId);
     99    slide.checkPermission(Permission.WRITE);
    99100    cc.setObject("item", slide);
    100101    title = "Edit array slide -- " + HTML.encodeTags(slide.getName());
     
    108109    }
    109110  }
    110   if (slide != null && !slide.hasPermission(Permission.WRITE))
    111   {
    112     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    113   }
    114  
    115111 
    116112  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), slide);
    117113  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    118114  %>
    119   <base:page type="popup" title="<%=title%>">
    120   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     115  <base:page type="popup" title="<%=title%>" id="edit-page">
     116  <base:head scripts="tabcontrol-2.js,~slides.js" styles="tabcontrol.css">
    121117    <ext:scripts context="<%=jspContext%>" />
    122118    <ext:stylesheets context="<%=jspContext%>" />
    123     <script>
    124     // Validate the "ArraySlide" tab
    125     function validateArraySlide()
    126     {
    127       var frm = document.forms['slide'];
    128       if (Main.trimString(frm.name.value) == '')
    129       {
    130         Forms.showNotification(frm.name, 'You must enter a name');
    131         return false;
    132       }
    133       if (frm.arraybatch_id && !frm.arraybatch_id.value)
    134       {
    135         Forms.showNotification('arraybatch_id.select', 'You must select an array batch');
    136         return false;
    137       }
    138       return true;
    139     }
    140 
    141     // Submit the form
    142     function saveSettings()
    143     {
    144       var frm = document.forms['slide'];
    145       if (TabControl.validateActiveTab('settings'))
    146       {
    147         Annotations.saveModifiedAnnotationsToForm(frm);
    148         Annotations.saveInheritedAnnotationsToForm(frm);
    149         frm.submit();
    150       }
    151     }
    152    
    153     function loadAnnotationsFrame()
    154     {
    155       Annotations.autoLoadEditFrame();
    156     }
    157    
    158     function loadInheritedAnnotationsFrame()
    159     {
    160       Annotations.autoLoadInheritFrame(getParents());
    161     }
    162    
    163     function getParents()
    164     {
    165       var frm = document.forms['slide'];
    166       var parents = new Array();
    167       if (frm.arraybatch_id)
    168       {
    169         var batchId = Math.abs(parseInt(frm.arraybatch_id[frm.arraybatch_id.selectedIndex].value));
    170         if (batchId > 0) parents[parents.length] = 'ARRAYBATCH:'+batchId;
    171       }
    172       return parents;
    173     }
    174    
    175     function selectArrayBatchOnClick()
    176     {
    177       var frm = document.forms['slide'];
    178       var url = '../../lims/arraybatches/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setArrayBatchCallback';
    179       if (frm.arraybatch_id.length > 0) url += '&item_id='+frm.arraybatch_id[0].value;
    180       Main.openPopup(url, 'SelectArrayBatch', 1050, 700);
    181     }
    182     function setArrayBatchCallback(id, name)
    183     {
    184       var frm = document.forms['slide'];
    185       var list = frm.arraybatch_id;
    186       if (list.length < 1 || list[0].value == '0') // >
    187       {
    188         Forms.addListOption(list, 0, new Option());
    189       }
    190       list[0].value = id;
    191       list[0].text = name;
    192       list.selectedIndex = 0;
    193     }
    194 
    195     function init()
    196     {
    197       var frm = document.forms['slide'];
    198       <%
    199       if (slide == null)
    200       {
    201         %>
    202         frm.name.focus();
    203         frm.name.select();
    204         <%
    205       }
    206       %>
    207     }
    208     </script>
    209119  </base:head>
    210   <base:body onload="init()">
     120  <base:body>
    211121    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    212122    <form action="index.jsp?ID=<%=ID%>" method="post" name="slide">
     
    215125    <t:tabcontrol id="settings"
    216126      subclass="content dialogtabcontrol"
    217       position="bottom"  remember="<%=slide != null%>"
     127      position="bottom" remember="<%=slide != null%>"
    218128      extensions="<%=invoker%>">
    219     <t:tab id="info" title="Array slide" validate="validateArraySlide()" helpid="arrayslide.edit">
     129    <t:tab id="info" title="Array slide" helpid="arrayslide.edit">
    220130      <table class="fullform input100">
    221131      <tr>
    222132        <th>Name</th>
    223         <td><input class="text required" type="text" name="name"
     133        <td><input class="text required auto-init" data-auto-init="<%=slide == null ? "focus-select" : "focus" %>"
     134          type="text" name="name"
    224135          value="<%=HTML.encodeTags(slide == null ? Values.getString(cc.getPropertyValue("name"), "New array slide") : slide.getName())%>"
    225136          maxlength="<%=ArraySlide.MAX_NAME_LENGTH%>"></td>
     
    261172              recent="<%=recentArrayBatches%>"
    262173              newitem="true"
    263               onselect="selectArrayBatchOnClick()"
    264174            />
    265175            <%
     
    271181      <tr>
    272182        <th>Index</th>
    273         <td><input class="text" type="text" name="batch_index" value="<%=slide == null ? Values.getInt(cc.getPropertyValue("batchIndex"), maxIndex + 1) : slide.getBatchIndex()%>"
    274           maxlength="10" style="width: 15em;"
    275           onkeypress="return Numbers.integerOnly(event)"></td>
     183        <td><input class="text" type="text" name="batch_index" id="batch_index"
     184          value="<%=slide == null ? Values.getInt(cc.getPropertyValue("batchIndex"), maxIndex + 1) : slide.getBatchIndex()%>"
     185          maxlength="10" style="width: 15em;"></td>
    276186        <td></td>
    277187      </tr>
     
    289199    </t:tab>
    290200   
    291     <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     201    <t:tab id="annotations" title="Annotations &amp; parameters" helpid="annotations.edit">
    292202      <jsp:include page="../../common/annotations/annotate_frameset.jsp">
    293203        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    298208   
    299209    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    300       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     210      helpid="annotations.edit.inherited">
    301211      <jsp:include page="../../common/annotations/inherit_frameset.jsp">
    302212        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    313223
    314224    <base:buttongroup subclass="dialogbuttons">
    315       <base:button onclick="saveSettings()" title="Save" />
    316       <base:button onclick="window.close()" title="Cancel" />
     225      <base:button id="btnSave" title="Save" />
     226      <base:button id="close" title="Cancel" />
    317227    </base:buttongroup>
    318228  </base:body>
  • trunk/www/lims/arrayslides/paste_multiple.jsp

    r6162 r6312  
    5959%>
    6060
    61   <base:page type="popup" title="<%=title%>">
    62   <base:head>
    63     <script>
    64     // Validate the "ArraySlide" tab
    65     function init()
    66     {
    67       var pfrm = window.opener.document.forms['<%=form%>'];
    68       var frm = document.forms['paste'];
    69       if (pfrm)
    70       {
    71         var i = 0;
    72         var text = '';
    73         while (pfrm['<%=prefix%>'+i])
    74         {
    75           text += pfrm['<%=prefix%>'+i].value + '\n';
    76           i++;
    77         }
    78         frm['text'].value = text;
    79       }
    80     }
    81 
    82     // Submit the form
    83     function save()
    84     {
    85       var pfrm = window.opener.document.forms['<%=form%>'];
    86       var frm = document.forms['paste'];
    87       if (pfrm)
    88       {
    89         var text = frm['text'].value.split('\n');
    90         for (var i = 0; i < text.length; ++i)
    91         {
    92           var field = '<%=prefix%>' + i;
    93           if (pfrm[field]) pfrm[field].value = text[i];
    94         }
    95         // Clear any remaining fields
    96         while (pfrm['<%=prefix%>'+i])
    97         {
    98           pfrm['<%=prefix%>'+i].value = '';
    99           i++;
    100         }
    101       }
    102       window.close();
    103     }
    104     </script>
    105   </base:head>
    106   <base:body onload="init()">
     61  <base:page type="popup" title="<%=title%>" id="paste-multiple">
     62  <base:head scripts="~wizard.js" />
     63  <base:body>
    10764    <h1><%=title%> <base:help helpid="arrayslide.createwizard.pastemultiple" /></h1>
     65    <div id="page-data" class="datacontainer"
     66      data-form-name="<%=form %>"
     67      data-form-prefix="<%=prefix %>"
     68    ></div>
    10869    <form name="paste">
    109 
    11070    <div class="content">
    11171      <table style="width: 100%; height: 100%;">
     
    11373        <td class="padded filled">
    11474        <i>
    115           Enter one name or barcode per line. Click <b>Save</b> to store the
     75          Enter one name or barcode per line. Click <b>Ok</b> to store the
    11676          result in the parent form.
    11777        </i>
     
    13090
    13191    <base:buttongroup subclass="dialogbuttons">
    132       <base:button onclick="save()" title="Save" />
    133       <base:button onclick="window.close()" title="Cancel" />
     92      <base:button id="btnOk" title="Ok" />
     93      <base:button id="close" title="Cancel" />
    13494    </base:buttongroup>
    13595  </base:body>
  • trunk/www/lims/arrayslides/slides.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', arraySlides.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', Annotations.autoLoadEditFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', arraySlides.loadInheritedAnnotationsFrame);
     44      TabControl.addTabValidator('settings.info', arraySlides.validateArraySlide);
     45     
     46      // Array batch
     47      Buttons.addClickHandler('arraybatch_id.select', arraySlides.selectArrayBatch);
     48      Events.addEventHandler('arraybatch_id', 'base-selected', arraySlides.setArrayBatchCallback);
     49     
     50      // Batch order
     51      Events.addEventHandler('batch_index', 'keypress', Events.integerOnly);
    3852    }
    3953    else if (pageId == 'view-page')
     
    8397  }
    8498 
     99  arraySlides.validateArraySlide = function()
     100  {
     101    var frm = document.forms['slide'];
     102    if (Main.trimString(frm.name.value) == '')
     103    {
     104      Forms.showNotification(frm.name, 'You must enter a name');
     105      return false;
     106    }
     107    if (frm.arraybatch_id && !frm.arraybatch_id.value)
     108    {
     109      Forms.showNotification('arraybatch_id.select', 'You must select an array batch');
     110      return false;
     111    }
     112    return true;
     113  }
     114
     115  arraySlides.save = function()
     116  {
     117    var frm = document.forms['slide'];
     118    if (TabControl.validateActiveTab('settings'))
     119    {
     120      Annotations.saveModifiedAnnotationsToForm(frm);
     121      Annotations.saveInheritedAnnotationsToForm(frm);
     122      frm.submit();
     123    }
     124  }
     125 
     126  arraySlides.loadInheritedAnnotationsFrame = function()
     127  {
     128    Annotations.autoLoadInheritFrame(arraySlides.getParents());
     129  }
     130 
     131  arraySlides.getParents = function()
     132  {
     133    var frm = document.forms['slide'];
     134    var parents = new Array();
     135    if (frm.arraybatch_id)
     136    {
     137      var batchId = Math.abs(parseInt(frm.arraybatch_id[frm.arraybatch_id.selectedIndex].value));
     138      if (batchId > 0) parents[parents.length] = 'ARRAYBATCH:'+batchId;
     139    }
     140    return parents;
     141  }
     142
     143  arraySlides.selectArrayBatch = function()
     144  {
     145    var frm = document.forms['slide'];
     146    var url = '';
     147    if (frm.arraybatch_id.length > 0)
     148    {
     149      url += '&item_id='+frm.arraybatch_id[0].value;
     150    }
     151    Dialogs.selectItem('ARRAYBATCH', 'arraybatch_id', 0, url);
     152  }
     153 
     154  arraySlides.setArrayBatchCallback = function(event)
     155  {
     156    var frm = document.forms['slide'];
     157    var list = frm.arraybatch_id;
     158    if (list.length < 1 || list[0].value == '0')
     159    {
     160      Forms.addListOption(list, 0, new Option());
     161    }
     162    list[0].value = event.detail.id;
     163    list[0].text = event.detail.name;
     164    list.selectedIndex = 0;
     165  }
     166
     167 
    85168  return arraySlides;
    86169}();
  • trunk/www/lims/platemappings/edit_mapping.jsp

    r6217 r6312  
    9494  {
    9595    mapping = PlateMapping.getById(dc, itemId);
     96    mapping.checkPermission(Permission.WRITE);
    9697    cc.setObject("item", mapping);
    9798    title = "Edit plate mapping -- " + HTML.encodeTags(mapping.getName());
     
    114115    }
    115116  }
    116   if (mapping != null && !mapping.hasPermission(Permission.WRITE))
    117   {
    118     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    119   }
    120  
    121  
    122117  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), mapping);
    123118  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    124119  %>
    125   <base:page type="popup" title="<%=title%>">
    126   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     120  <base:page type="popup" title="<%=title%>" id="edit-page">
     121  <base:head scripts="tabcontrol-2.js,~mappings.js" styles="tabcontrol.css">
    127122    <ext:scripts context="<%=jspContext%>" />
    128123    <ext:stylesheets context="<%=jspContext%>" />
    129     <script>
    130     // Validate the "PlateMapping" tab
    131     function validatePlateMapping()
    132     {
    133       var frm = document.forms['mapping'];
    134       if (Main.trimString(frm.name.value) == '')
    135       {
    136         Forms.showNotification(frm.name, 'You must enter a name');
    137         return false;
    138       }
    139       return true;
    140     }
    141 
    142     // Submit the form
    143     function saveSettings()
    144     {
    145       var frm = document.forms['mapping'];
    146       if (TabControl.validateActiveTab('settings'))
    147       {
    148         frm.submit();
    149       }
    150     }
    151 
    152     function updateImage()
    153     {
    154       var frm = document.forms['mapping'];
    155       var newSrc = frm.image.value;
    156       var imageSrc = '../../images/platemappings/'+newSrc;
    157       var image = document.getElementById('mappingImage');
    158       if (image && newSrc && imageSrc != image.src)
    159       {
    160         image.src = imageSrc;
    161       }
    162     }
    163 
    164     function init()
    165     {
    166       var frm = document.forms['mapping'];
    167       <%
    168       if (mapping == null)
    169       {
    170         %>
    171         frm.name.focus();
    172         frm.name.select();
    173         <%
    174       }
    175       %>
    176     }
    177     </script>
    178124  </base:head>
    179   <base:body onload="init()">
     125  <base:body>
    180126    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    181127    <form action="index.jsp?ID=<%=ID%>" method="post" name="mapping">
     
    186132      position="bottom" remember="<%=mapping != null%>"
    187133      extensions="<%=invoker%>">
    188     <t:tab id="info" title="Plate mapping" validate="validatePlateMapping()" helpid="platemapping.edit">
     134    <t:tab id="info" title="Plate mapping" helpid="platemapping.edit">
    189135      <table class="fullform input100 smaller">
    190136      <tr>
    191137        <th>Name</th>
    192         <td><input class="text required" type="text" name="name"
     138        <td><input class="text required auto-init" data-auto-init="<%=mapping == null ? "focus-select" : "focus" %>"
     139          type="text" name="name"
    193140          value="<%=HTML.encodeTags(mapping == null ? Values.getString(cc.getPropertyValue("name"), "New plate mapping") : mapping.getName())%>"
    194141          maxlength="<%=PlateMapping.MAX_NAME_LENGTH%>"></td>
     
    202149          {
    203150            %>
    204             <input class="text required" type="text" name="source_count" style="width: 15em;"
    205               value="<%=Values.getInt(cc.getPropertyValue("sourceCount"), 1)%>"
    206               maxlength="10" onkeypress="return Numbers.integerOnly(event)">
     151            <input class="text required" type="text" name="source_count" id="source_count"
     152              style="width: 15em;" maxlength="10"
     153              value="<%=Values.getInt(cc.getPropertyValue("sourceCount"), 1)%>">
    207154            plate(s) of
    208155            <select name="sourcegeometry_id" class="required">
     
    237184          {
    238185            %>
    239             <input class="text required" type="text" name="destination_count" style="width: 15em;"
    240               value="<%=Values.getInt(cc.getPropertyValue("destinationCount"), 1)%>"
    241               maxlength="10" onkeypress="return Numbers.integerOnly(event)">
     186            <input class="text required" type="text" name="destination_count" id="destination_count"
     187              style="width: 15em;" maxlength="10"
     188              value="<%=Values.getInt(cc.getPropertyValue("destinationCount"), 1)%>">
    242189            plate(s) of
    243190            <select name="destinationgeometry_id" class="required">
     
    268215        <th>Image</th>
    269216        <td>
    270           <input class="text" type="text" name="image"
     217          <input class="text" type="text" name="image" id="image"
    271218            value="<%=HTML.encodeTags(mapping == null ? "" : mapping.getImage())%>"
    272             maxlength="<%=PlateMapping.MAX_IMAGE_LENGTH%>"
    273             onBlur="updateImage()">
     219            maxlength="<%=PlateMapping.MAX_IMAGE_LENGTH%>">
    274220            <br><br>
    275221            <%
     
    304250
    305251    <base:buttongroup subclass="dialogbuttons">
    306       <base:button onclick="saveSettings()" title="Save" />
    307       <base:button onclick="window.close()" title="Cancel" />
     252      <base:button id="btnSave" title="Save" />
     253      <base:button id="close" title="Cancel" />
    308254    </base:buttongroup>
    309255  </base:body>
  • trunk/www/lims/platemappings/mappings.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', plateMappings.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabValidator('settings.info', plateMappings.validatePlateMapping);
     43     
     44      // Count
     45      Events.addEventHandler('source_count', 'keypress', Events.integerOnly);
     46      Events.addEventHandler('destination_count', 'keypress', Events.integerOnly);
     47     
     48      // Image
     49      Events.addEventHandler('image', 'blur', plateMappings.updateImage);
    3850    }
    3951    else if (pageId == 'view-page')
     
    7284    }
    7385  }
    74    
     86 
     87 
     88  plateMappings.validatePlateMapping = function()
     89  {
     90    var frm = document.forms['mapping'];
     91    if (Main.trimString(frm.name.value) == '')
     92    {
     93      Forms.showNotification(frm.name, 'You must enter a name');
     94      return false;
     95    }
     96    return true;
     97  }
     98
     99  // Submit the form
     100  plateMappings.save = function()
     101  {
     102    var frm = document.forms['mapping'];
     103    if (TabControl.validateActiveTab('settings'))
     104    {
     105      frm.submit();
     106    }
     107  }
     108
     109  plateMappings.updateImage = function()
     110  {
     111    var frm = document.forms['mapping'];
     112    var newSrc = frm.image.value;
     113    var imageSrc = '../../images/platemappings/'+newSrc;
     114    var image = Doc.element('mappingImage');
     115    if (image && newSrc && imageSrc != image.src)
     116    {
     117      image.src = imageSrc;
     118    }
     119  }
     120
    75121  return plateMappings;
    76122}();
  • trunk/www/lims/plates/edit_plate.jsp

    r6254 r6312  
    5656<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
    5757<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
     58<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
    5859<%
    5960final Item itemType = Item.PLATE;
     
    9091  {
    9192    plate = Plate.getById(dc, itemId);
     93    plate.checkPermission(Permission.WRITE);
    9294    cc.setObject("item", plate);
    9395    title = "Edit plate -- " + HTML.encodeTags(plate.getName());
     
    101103    }
    102104  }
    103   if (plate != null && !plate.hasPermission(Permission.WRITE))
    104   {
    105     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    106   }
    107  
    108105 
    109106  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), plate);
    110107  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    111108  %>
    112   <base:page type="popup" title="<%=title%>">
    113   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     109  <base:page type="popup" title="<%=title%>" id="edit-page">
     110  <base:head scripts="tabcontrol-2.js,~plates.js" styles="tabcontrol.css">
    114111    <ext:scripts context="<%=jspContext%>" />
    115112    <ext:stylesheets context="<%=jspContext%>" />
    116     <script>
    117     // Validate the "Plate" tab
    118     function validatePlate()
    119     {
    120       var frm = document.forms['plate'];
    121       if (Main.trimString(frm.name.value) == '')
    122       {
    123         Forms.showNotification(frm.name, 'You must enter a name');
    124         return false;
    125       }
    126       if (frm.platetype_id && frm.platetype_id.length == 0)
    127       {
    128         Forms.showNotification('platetype_id.select', 'You must select a plate type');
    129         return false;
    130       }
    131       return true;
    132     }
    133 
    134     // Submit the form
    135     function saveSettings()
    136     {
    137       var frm = document.forms['plate'];
    138       if (TabControl.validateActiveTab('settings'))
    139       {
    140         Annotations.saveModifiedAnnotationsToForm(frm);
    141         Annotations.saveInheritedAnnotationsToForm(frm);
    142         frm.submit();
    143       }
    144     }
    145    
    146     function loadAnnotationsFrame()
    147     {
    148       Annotations.autoLoadEditFrame();
    149     }
    150    
    151     function loadInheritedAnnotationsFrame()
    152     {
    153       Annotations.autoLoadInheritFrame();
    154     }
    155 
    156     function selectPlateTypeOnClick()
    157     {
    158       var frm = document.forms['plate'];
    159       var url = '../platetypes/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setPlateTypeCallback';
    160       if (frm.platetype_id.length > 0) url += '&item_id='+frm.platetype_id[0].value;
    161       Main.openPopup(url, 'SelectArrayBatch', 1050, 700);
    162     }
    163     function setPlateTypeCallback(plateTypeId, name)
    164     {
    165       var frm = document.forms['plate'];
    166       if (frm.platetype_id.length < 1) // >
    167       {
    168         frm.platetype_id[frm.platetype_id.length] = new Option();
    169       }
    170       frm.platetype_id[0].value = plateTypeId;
    171       frm.platetype_id[0].text = name;
    172       frm.platetype_id.selectedIndex = 0;
    173     }
    174 
    175     function init()
    176     {
    177       var frm = document.forms['plate'];
    178       <%
    179       if (plate == null)
    180       {
    181         %>
    182         frm.name.focus();
    183         frm.name.select();
    184         <%
    185       }
    186       %>
    187     }
    188     </script>
    189113  </base:head>
    190   <base:body onload="init()">
     114  <base:body>
    191115    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
    192116    <form action="index.jsp?ID=<%=ID%>" method="post" name="plate">
     
    195119    <t:tabcontrol id="settings"
    196120      subclass="content dialogtabcontrol"
    197       position="bottom"  remember="<%=plate != null%>"
     121      position="bottom" remember="<%=plate != null%>"
    198122      extensions="<%=invoker%>">
    199     <t:tab id="info" title="Plate" validate="validatePlate()" helpid="plate.edit">
     123    <t:tab id="info" title="Plate" helpid="plate.edit">
    200124      <table class="fullform input100 smaller">
    201125      <tr>
    202126        <th>Name</th>
    203         <td><input class="text required" type="text" name="name"
     127        <td><input class="text required auto-init" data-auto-init="<%=plate == null ? "focus-select" : "focus" %>" type="text" name="name"
    204128          value="<%=HTML.encodeTags(plate == null ? Values.getString(cc.getPropertyValue("name"), "New plate") : plate.getName())%>"
    205129          maxlength="<%=Plate.MAX_NAME_LENGTH%>"></td>
     
    236160            <tr>
    237161            <td>
    238               <select name="platetype_id" size="1"
     162              <select name="platetype_id" id="platetype_id" size="1"
    239163                <%=!readCurrentPlateType ? "disabled readonly class=\"disabled\"" : "class=\"required\""%>
    240164                style="width: 20em;">
     
    258182              </select>
    259183            </td>
    260             <td><base:button onclick="selectPlateTypeOnClick()" title="Select&hellip;" /></td>
     184            <td><base:button id="platetype_id.select" title="Select&hellip;" /></td>
    261185            </tr>
    262186            </table>
     
    280204    </t:tab>
    281205   
    282     <t:tab id="annotations" title="Annotations" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     206    <t:tab id="annotations" title="Annotations" helpid="annotations.edit">
    283207      <jsp:include page="../../common/annotations/annotate_frameset.jsp">
    284208        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    289213   
    290214    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    291       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     215      helpid="annotations.edit.inherited">
    292216      <jsp:include page="../../common/annotations/inherit_frameset.jsp">
    293217        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    304228
    305229    <base:buttongroup subclass="dialogbuttons">
    306       <base:button onclick="saveSettings()" title="Save" />
    307       <base:button onclick="window.close()" title="Cancel" />
     230      <base:button id="btnSave" title="Save" />
     231      <base:button id="close" title="Cancel" />
    308232    </base:buttongroup>
    309233  </base:body>
  • trunk/www/lims/plates/events/edit_event.jsp

    r6217 r6312  
    125125  {
    126126    event = PlateEvent.getById(dc, itemId);
     127    event.checkPermission(Permission.WRITE);
    127128    eventType = event.getPlateEventType();
    128129    eventDate = event.getEventDate();
     
    154155    }
    155156  }
    156  
    157   if (event != null && !event.hasPermission(Permission.WRITE))
    158   {
    159     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    160   }
    161  
    162  
     157   
    163158  Formatter<Date> dateFormatter = FormatterFactory.getDateFormatter(sc);
    164159  String dateFormat = FormatterSettings.getDateFormat(sc);
     
    168163  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    169164  %>
    170   <base:page type="popup" title="<%=title%>">
    171   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     165  <base:page type="popup" title="<%=title%>" id="edit-page">
     166  <base:head scripts="tabcontrol-2.js,~events.js" styles="tabcontrol.css">
    172167    <ext:scripts context="<%=jspContext%>" />
    173168    <ext:stylesheets context="<%=jspContext%>" />
    174     <script>
    175     // Validate the "Event" tab
    176     function validateEvent()
    177     {
    178       var frm = document.forms['event'];
    179       return true;
    180     }
    181 
    182     // Submit the form
    183     function saveSettings()
    184     {
    185       var frm = document.forms['event'];
    186       if (TabControl.validateActiveTab('settings'))
    187       {
    188         frm.submit();
    189       }
    190     }
    191    
    192     var protocolTypeFilter = <%=currentProtocolType != null ? currentProtocolType.getId() : 0%>;   
    193     function selectProtocolOnClick()
    194     {
    195       var frm = document.forms['event'];
    196       var url = '../../../admin/protocols/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setProtocolCallback';
    197       if (frm.protocol_id.length > 1)
    198       {
    199         var id = Math.abs(parseInt(frm.protocol_id[1].value));       
    200         url += '&item_id='+id;
    201       }
    202       if (protocolTypeFilter)
    203       {
    204         url += '&resetTemporary=1&tmpfilter:INT:itemSubtype='+protocolTypeFilter;
    205       }
    206       Main.openPopup(url, 'SelectProtocol', 1050, 700);
    207     }
    208     function setProtocolCallback(id, name)
    209     {
    210       var frm = document.forms['event'];
    211       var list = frm.protocol_id;
    212       if (list.length < 2 || list[1].value == '0') // >
    213       {
    214         Forms.addListOption(list, 1, new Option());
    215       }
    216       list[1].value = id;
    217       list[1].text = name;
    218       list.selectedIndex = 1;
    219     }
    220     function selectHardwareOnClick()
    221     {
    222       var frm = document.forms['event'];
    223       var url = '../../../admin/hardware/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone&callback=setHardwareCallback';
    224       if (frm.hardware_id.length > 1)
    225       {
    226         var id = Math.abs(parseInt(frm.hardware_id[1].value));
    227         url += '&item_id='+id;
    228       }
    229       Main.openPopup(url, 'SelectHardware', 1050, 700);
    230     }
    231     function setHardwareCallback(id, name)
    232     {
    233       var frm = document.forms['event'];
    234       var list = frm.hardware_id;
    235       if (list.length < 2 || list[1].value == '0') // >
    236       {
    237         Forms.addListOption(list, 1, new Option());
    238       }
    239       list[1].value = id;
    240       list[1].text = name;
    241       list.selectedIndex = 1;
    242     }
    243 
    244     function init()
    245     {
    246       var frm = document.forms['event'];
    247       plateEventTypeOnChange();
    248     }
    249     <%
    250     if (event == null)
    251     {
    252       %>
    253       var protocolTypes = new Array();
    254       <%
    255       for (PlateEventType pet : eventTypes)
    256       {
    257         try
    258         {
    259           ItemSubtype pt = pet.getProtocolType();
    260           if (pt != null)
    261           {
    262             %>
    263             protocolTypes['P<%=pet.getId()%>'] = <%=pt.getId()%>;
    264             <%
    265           }
    266         }
    267         catch (Throwable t)
    268         {}
    269       }
    270     }
    271     %>
    272     function plateEventTypeOnChange()
    273     {
    274       var frm = document.forms['event'];
    275       if (frm.plateeventtype_id)
    276       {
    277         var eventTypeId = frm.plateeventtype_id[frm.plateeventtype_id.selectedIndex].value;
    278         protocolTypeFilter = protocolTypes['P'+eventTypeId];
    279       }
    280     }
    281     </script>
    282169  </base:head>
    283   <base:body onload="init()">
     170  <base:body>
    284171    <h1><%=title%> <base:help tabcontrol="settings" /></h1>
     172    <div id="page-data" class="datacontainer"
     173      data-protocol-type="<%=currentProtocolType == null ? 0 : currentProtocolType.getId() %>"
     174    ></div>
     175   
    285176    <form action="index.jsp?ID=<%=ID%>" method="post" name="event">
    286177    <input type="hidden" name="cmd" value="UpdateItem">
     
    291182      position="bottom" remember="<%=event != null%>"
    292183      extensions="<%=invoker%>">
    293     <t:tab id="info" title="Event" validate="validateEvent()" helpid="plateevent.edit">
     184    <t:tab id="info" title="Event" helpid="plateevent.edit">
    294185      <table class="fullform input100 smaller">
    295186      <tr>
     
    300191          {
    301192            %>
    302             <select name="plateeventtype_id" class="required" onchange="plateEventTypeOnChange()">
     193            <select name="plateeventtype_id" class="required">
    303194            <%
    304195            for (PlateEventType pet : eventTypes)
    305196            {
     197              ItemSubtype eventProtocolType = null;
     198              try
     199              {
     200                eventProtocolType = pet.getProtocolType();
     201              }
     202              catch (Throwable t)
     203              {}
    306204              %>
    307               <option value="<%=pet.getId()%>"><%=pet.getOrdinal()%>. <%=HTML.encodeTags(pet.getName())%>
     205              <option value="<%=pet.getId()%>"
     206                data-protocol-type="<%=eventProtocolType == null ? 0 : eventProtocolType.getId()%>"><%=pet.getOrdinal()%>. <%=HTML.encodeTags(pet.getName())%>
    308207              <%
    309208            }
     
    356255            recent="<%=recentProtocols%>"
    357256            newitem="<%=event == null%>"
    358             onselect="selectProtocolOnClick()"
    359257          />
    360258        </td>
     
    372270            recent="<%=recentHardware%>"
    373271            newitem="<%=event == null%>"
    374             onselect="selectHardwareOnClick()"
    375272          />
    376273        </td>
     
    397294
    398295    <base:buttongroup subclass="dialogbuttons">
    399       <base:button onclick="saveSettings()" title="Save" />
    400       <base:button onclick="window.close()" title="Cancel" />
     296      <base:button id="btnSabe" title="Save" />
     297      <base:button id="close" title="Cancel" />
    401298    </base:buttongroup>
    402299  </base:body>
  • trunk/www/lims/plates/events/events.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', plateEvents.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabValidator('settings.info', plateEvents.validateEvent);
     43
     44      // Protocol
     45      Buttons.addClickHandler('protocol_id.select', plateEvents.selectProtocol);
     46      Events.addEventHandler('protocol_id', 'base-selected', plateEvents.setProtocolCallback);
     47     
     48      // Hardware
     49      Buttons.addClickHandler('hardware_id.select', plateEvents.selectHardware);
     50      Events.addEventHandler('hardware_id', 'base-selected', plateEvents.setHardwareCallback);
    3851    }
    3952    else if (pageId == 'view-page')
     
    89102
    90103
     104  plateEvents.validateEvent = function()
     105  {
     106    return true;
     107  }
     108
     109  // Submit the form
     110  plateEvents.save = function()
     111  {
     112    var frm = document.forms['event'];
     113    if (TabControl.validateActiveTab('settings'))
     114    {
     115      frm.submit();
     116    }
     117  }
     118
     119  plateEvents.selectHardware = function()
     120  {
     121    var frm = document.forms['event'];
     122    var url = '';
     123    if (frm.hardware_id.length > 1)
     124    {
     125      var id = Math.abs(parseInt(frm.hardware_id[1].value));
     126      url += '&item_id='+id;
     127    }
     128    Dialogs.selectItem('HARDWARE', 'hardware_id', 0, url);
     129  }
     130 
     131  plateEvents.setHardwareCallback = function(event)
     132  {
     133    var frm = document.forms['event'];
     134    var list = frm.hardware_id;
     135    if (list.length < 2 || list[1].value == '0')
     136    {
     137      Forms.addListOption(list, 1, new Option());
     138    }
     139    list[1].value = event.detail.id;
     140    list[1].text = event.detail.name;
     141    list.selectedIndex = 1;
     142  }
     143
     144  plateEvents.selectProtocol = function()
     145  {
     146    var frm = document.forms['event'];
     147    var url = '';
     148    if (frm.protocol_id.length > 1)
     149    {
     150      var id = Math.abs(parseInt(frm.protocol_id[1].value));       
     151      url += '&item_id='+id;
     152    }
     153   
     154    var protocolTypeId;
     155    if (frm.plateeventtype_id)
     156    {
     157      protocolTypeId = Data.int(frm.plateeventtype_id[frm.plateeventtype_id.selectedIndex], 'protocol-type');
     158    }
     159    else
     160    {
     161      protocolTypeId = Data.int('page-data', 'protocol-type');
     162     
     163    }
     164    if (protocolTypeId)
     165    {
     166      url += '&resetTemporary=1&tmpfilter:INT:itemSubtype='+protocolTypeId;
     167    }
     168    Dialogs.selectItem('PROTOCOL', 'protocol_id', 0, url);
     169  }
     170 
     171  plateEvents.setProtocolCallback = function(event)
     172  {
     173    var frm = document.forms['event'];
     174    var list = frm.protocol_id;
     175    if (list.length < 2 || list[1].value == '0')
     176    {
     177      Forms.addListOption(list, 1, new Option());
     178    }
     179    list[1].value = event.detail.id;
     180    list[1].text = event.detail.name;
     181    list.selectedIndex = 1;
     182  }
     183
    91184  return plateEvents;
    92185}();
  • trunk/www/lims/plates/index.jsp

    r6192 r6312  
    329329   
    330330    List<Plate> sourcePlates = new ArrayList<Plate>(plateMapping.getSourceCount());
    331     for (String pId : request.getParameter("mergePlates").split(","))
     331    for (String pId : request.getParameter("+PLATE").split(","))
    332332    {
    333333      sourcePlates.add(Plate.getById(dc, Values.getInt(pId)));
  • trunk/www/lims/plates/merge_plates.jsp

    r6217 r6312  
    5353  String title = "Merge plates -- step 1 of 2 -- Select mapping";
    5454 
    55  
    56  
    5755  // Load recently used items
    5856  List<PlateMapping> recentPlateMappings = (List<PlateMapping>)cc.getRecent(dc, Item.PLATEMAPPING);
     
    6058  %>
    6159
    62   <base:page type="popup" title="<%=title%>">
    63   <base:head>
    64     <script>
    65     // Validate the entered information
    66     function validate()
    67     {
    68       var frm = document.forms['merge'];
    69       if (Main.trimString(frm.name.value) == '')
    70       {
    71         Forms.showNotification(frm.name, 'You must enter a name');
    72         return false;
    73       }
    74       if (!frm.platemapping_id.value)
    75       {
    76         Forms.showNotification('platemapping_id.select', 'You must select a plate mapping');
    77         return false;
    78       }
    79       if (!frm.platetype_id.value)
    80       {
    81         Forms.showNotification('platetype_id.select', 'You must select a plate type');
    82         return false;
    83       }
    84       return true;
    85     }
    86 
    87     // Submit the form
    88     function nextStep()
    89     {
    90       var frm = document.forms['merge'];
    91       if (validate())
    92       {
    93         frm.submit();
    94       }
    95     }
    96    
    97     function selectPlateMappingOnClick()
    98     {
    99       var frm = document.forms['merge'];
    100       var url = '../platemappings/index.jsp?ID=<%=ID%>&mode=selectone&callback=setPlateMappingCallback';
    101       Main.openPopup(url, 'SelectPlateMapping', 1050, 700);
    102     }
    103     function setPlateMappingCallback(id, name)
    104     {
    105       var frm = document.forms['merge'];
    106       var list = frm.platemapping_id;
    107       if (list.length < 1 || list[0].value == '0') // >
    108       {
    109         Forms.addListOption(list, 0, new Option());
    110       }
    111       list[0].value = id;
    112       list[0].text = name;
    113       list.selectedIndex = 0;
    114     }
    115 
    116     function selectPlateTypeOnClick()
    117     {
    118       var frm = document.forms['merge'];
    119       var url = '../platetypes/index.jsp?ID=<%=ID%>&mode=selectone&callback=setPlateTypeCallback';
    120       Main.openPopup(url, 'SelectPlateType', 1050, 700);
    121     }
    122     function setPlateTypeCallback(id, name)
    123     {
    124       var frm = document.forms['merge'];
    125       var list = frm.platetype_id;
    126       if (list.length < 1 || list[0].value == '0') // >
    127       {
    128         Forms.addListOption(list, 0, new Option());
    129       }
    130       list[0].value = id;
    131       list[0].text = name;
    132       list.selectedIndex = 0;
    133     }
    134     </script>
    135   </base:head>
     60  <base:page type="popup" title="<%=title%>" id="step-1">
     61  <base:head scripts="~merge_plates.js" />
    13662  <base:body>
    13763    <h1><%=title%> <base:help helpid="plates.merge.1" /></h1>
     
    15076            recent="<%=recentPlateMappings%>"
    15177            newitem="true"
    152             onselect="selectPlateMappingOnClick()"
    15378          />
    15479        </td>
     
    16994            recent="<%=recentPlateTypes%>"
    17095            newitem="true"
    171             onselect="selectPlateTypeOnClick()"
    17296          />
    17397        </td>
     
    185109   
    186110    <base:buttongroup subclass="dialogbuttons">
    187       <base:button onclick="nextStep()" title="Next" />
    188       <base:button onclick="window.close()" title="Cancel" />
     111      <base:button id="btnNext" title="Next" />
     112      <base:button id="close" title="Cancel" />
    189113    </base:buttongroup>
    190114
  • trunk/www/lims/plates/merge_plates_2.jsp

    r6217 r6312  
    6363 
    6464  String title = "Merge plates -- step 2 of 2 -- Select plates";
    65  
    66  
    6765  %>
    68 
    69   <base:page type="popup" title="<%=title%>">
    70   <base:head scripts="linkitems.js">
    71     <script>
    72     // Validate the entered information
    73     function validate()
    74     {
    75       var frm = document.forms['merge'];
    76       if (Main.trimString(frm.name.value) == '')
    77       {
    78         Forms.showNotification(frm.name, 'You must enter a name');
    79         return false;
    80       }
    81       if (frm.plates.length != <%=plateMapping.getSourceCount()%>)
    82       {
    83         Forms.showNotification(frm.plates, 'You must select exactly <%=plateMapping.getSourceCount()%> plates');
    84         return false;
    85       }
    86       return true;
    87     }
    88 
    89     // Submit the form
    90     function mergePlates()
    91     {
    92       var frm = document.forms['merge'];
    93       if (validate())
    94       {
    95         frm.mergePlates.value = Link.getActionIds(1, 'P').join(',');
    96         frm.submit();
    97       }
    98     }
    99    
    100     function addPlatesOnClick()
    101     {
    102       var ids = Link.getListIds(document.forms['merge'].plates, 'P');
    103       var excludes = ids.join(',');
    104       var url = '../plates/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple&callback=addPlateCallback';
    105       url += "&exclude="+excludes;
    106       url += '&resetTemporary=1&tmpfilter:INT:plateType.plateGeometry=<%=sourceGeometry.getId()%>';
    107       Main.openPopup(url, 'AddPlates', 1050, 700);
    108     }
    109 
    110     function addPlateCallback(plateId, name)
    111     {
    112       var item = Link.getItem('P', plateId);
    113       if (!item) item = new Item('P', plateId, name);
    114       Link.addItem(document.forms['merge'].plates, item);
    115     }
    116    
    117     function removePlatesOnClick()
    118     {
    119       Link.removeSelected(document.forms['merge'].plates);
    120     }
    121     </script>
    122   </base:head>
     66  <base:page type="popup" title="<%=title%>" id="step-2">
     67  <base:head scripts="linkitems-2.js,~merge_plates.js" />
    12368  <base:body>
    12469    <h1><%=title%> <base:help helpid="plates.merge.2" /></h1>
     70
     71    <div id="page-data" class="datacontainer"
     72      data-source-count="<%=plateMapping.getSourceCount()%>"
     73    ></div>
    12574
    12675    <form action="index.jsp?ID=<%=ID%>" method="post" name="merge">
     
    164113            <base:buttongroup vertical="true">
    165114              <base:button
    166                 onclick="Forms.moveListOptions(document.forms['merge'].plates, false)"
     115                id="moveUp"
     116                data-down="0"
    167117                image="move_up.png"
    168118                tooltip="Move up"
     
    170120              />
    171121              <base:button
    172                 onclick="Forms.moveListOptions(document.forms['merge'].plates, true)"
     122                id="moveDown"
     123                data-down="1"
    173124                image="move_down.png"
    174125                tooltip="Move down"
     
    178129          </td>
    179130          <td>
    180             <select name="plates" size="<%=plateMapping.getSourceCount()%>" multiple
    181               style="width: 15em;" class="required">
     131            <select name="plates" id="plates"
     132              class="auto-init"
     133              data-auto-init="link-container"
     134              size="<%=Math.max(5, plateMapping.getSourceCount())%>"
     135              multiple style="width: 15em;" class="required">
    182136            </select>
    183             <input type="hidden" name="mergePlates">
    184137          </td>
    185138          <td>
    186139            <base:buttongroup vertical="true">
    187140              <base:button
    188                 subclass="leftaligned"
     141                subclass="leftaligned auto-init"
     142                data-auto-init="add-link"
     143                data-list-id="plates"
     144                data-item-type="PLATE"
     145                data-extra-url="<%="&resetTemporary=1&tmpfilter:INT:plateType.plateGeometry="+sourceGeometry.getId()%>"
    189146                style="width: 14em;"
    190                 onclick="addPlatesOnClick()"
    191147                title="Add&nbsp;plates&hellip;"
    192148                tooltip="Add plates to be used"
    193149              />
    194150              <base:button
    195                 subclass="leftaligned"
     151                subclass="leftaligned auto-init"
     152                data-auto-init="remove-link"
     153                data-list-id="plates"
    196154                style="width: 14em;"
    197                 onclick="removePlatesOnClick()"
    198155                title="Remove"
    199156                tooltip="Remove the selected plates"
     
    218175   
    219176    <base:buttongroup subclass="dialogbuttons">
    220       <base:button onclick="mergePlates()" title="Merge" image="gonext.png"/>
    221       <base:button onclick="window.close()" title="Cancel" />
     177      <base:button id="btnMerge" title="Merge" image="gonext.png"/>
     178      <base:button id="close" title="Cancel" />
    222179    </base:buttongroup>
    223180
  • trunk/www/lims/plates/plates.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', plates.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', Annotations.autoLoadEditFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', Annotations.autoLoadInheritFrame);
     44      TabControl.addTabValidator('settings.info', plates.validatePlate);
     45
     46      // Plate type
     47      Buttons.addClickHandler('platetype_id.select', plates.selectPlateType);
     48      Events.addEventHandler('platetype_id', 'base-selected', plates.setPlateType);
    3849    }
    3950    else if (pageId == 'view-page')
     
    96107    location.replace(url);
    97108  }
     109 
     110  plates.validatePlate = function()
     111  {
     112    var frm = document.forms['plate'];
     113    if (Main.trimString(frm.name.value) == '')
     114    {
     115      Forms.showNotification(frm.name, 'You must enter a name');
     116      return false;
     117    }
     118    if (frm.platetype_id && frm.platetype_id.length == 0)
     119    {
     120      Forms.showNotification('platetype_id.select', 'You must select a plate type');
     121      return false;
     122    }
     123    return true;
     124  }
     125
     126  // Submit the form
     127  plates.save = function()
     128  {
     129    var frm = document.forms['plate'];
     130    if (TabControl.validateActiveTab('settings'))
     131    {
     132      Annotations.saveModifiedAnnotationsToForm(frm);
     133      Annotations.saveInheritedAnnotationsToForm(frm);
     134      frm.submit();
     135    }
     136  }
     137
     138
     139  plates.selectPlateType = function()
     140  {
     141    var frm = document.forms['plate'];
     142    var url = '';
     143    if (frm.platetype_id.length > 0)
     144    {
     145      url += '&item_id='+frm.platetype_id[0].value;
     146    }
     147    Dialogs.selectItem('PLATETYPE', 'platetype_id', 0, url);
     148  }
     149 
     150  plates.setPlateType = function(event)
     151  {
     152    var frm = document.forms['plate'];
     153    if (frm.platetype_id.length < 1)
     154    {
     155      frm.platetype_id[frm.platetype_id.length] = new Option();
     156    }
     157    frm.platetype_id[0].value = event.detail.id;
     158    frm.platetype_id[0].text = event.detail.name;
     159    frm.platetype_id.selectedIndex = 0;
     160  }
    98161
    99162  return plates;
  • trunk/www/lims/plates/wells/edit_well.jsp

    r6254 r6312  
    4646<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
    4747<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
     48<%@ taglib prefix="ext" uri="/WEB-INF/extensions.tld" %>
    4849<%
    4950final Item itemType = Item.WELL;
     
    5960  String title = null;
    6061  Well well = Well.getById(dc, itemId);
     62  well.checkPermission(Permission.WRITE);
    6163  Plate plate = well.getPlate();
    6264  ReporterData reporter = well.getReporter();
     
    6668 
    6769  title = "Edit well -- " + HTML.encodeTags(plate.getName()) + " [" + rowFormatter.format(well.getRow()) + columnFormatter.format(well.getColumn()) + "]";
    68  
    69   if (well != null && !well.hasPermission(Permission.WRITE))
    70   {
    71     throw new PermissionDeniedException(Permission.WRITE, itemType.toString());
    72   }
    7370  cc.setObject("item", well);
    7471  JspContext jspContext = ExtensionsControl.createContext(dc, pageContext, GuiContext.item(itemType), well);
    7572  ExtensionsInvoker invoker = EditUtil.useEditExtensions(jspContext);
    7673  %>
    77   <base:page type="popup" title="<%=title%>">
    78   <base:head scripts="tabcontrol.js" styles="tabcontrol.css">
     74  <base:page type="popup" title="<%=title%>" id="edit-page">
     75  <base:head scripts="tabcontrol-2.js,~wells.js" styles="tabcontrol.css">
    7976    <ext:scripts context="<%=jspContext%>" />
    8077    <ext:stylesheets context="<%=jspContext%>" />
    81     <script>
    82     // Validate the "Well" tab
    83     function validateWell()
    84     {
    85       var frm = document.forms['well'];
    86       return true;
    87     }
    88 
    89     // Submit the form
    90     function saveSettings()
    91     {
    92       var frm = document.forms['well'];
    93       if (TabControl.validateActiveTab('settings'))
    94       {
    95         Annotations.saveModifiedAnnotationsToForm(frm);
    96         Annotations.saveInheritedAnnotationsToForm(frm);
    97         frm.submit();
    98       }
    99     }
    100    
    101     function loadAnnotationsFrame()
    102     {
    103       Annotations.autoLoadEditFrame();
    104     }
    105    
    106     function loadInheritedAnnotationsFrame()
    107     {
    108       Annotations.autoLoadInheritFrame();
    109     }
    110     </script>
    11178  </base:head>
    11279  <base:body>
     
    12087      position="bottom"
    12188      extensions="<%=invoker%>">
    122     <t:tab id="info" title="Well" validate="validateWell()" helpid="well.edit">
     89    <t:tab id="info" title="Well" helpid="well.edit">
    12390      <table class="fullform input100 outlined">
    12491      <tr>
     
    145112    </t:tab>
    146113
    147     <t:tab id="annotations" title="Annotations" helpid="annotations.edit" activate="loadAnnotationsFrame()">
     114    <t:tab id="annotations" title="Annotations" helpid="annotations.edit">
    148115      <jsp:include page="../../../common/annotations/annotate_frameset.jsp">
    149116        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    154121   
    155122    <t:tab id="inheritedAnnotations" title="Inherited annotations"
    156       helpid="annotations.edit.inherited" activate="loadInheritedAnnotationsFrame()">
     123      helpid="annotations.edit.inherited">
    157124      <jsp:include page="../../../common/annotations/inherit_frameset.jsp">
    158125        <jsp:param name="item_type" value="<%=itemType.name()%>" />
     
    165132
    166133    <base:buttongroup subclass="dialogbuttons">
    167       <base:button onclick="saveSettings()" title="Save" />
    168       <base:button onclick="window.close()" title="Cancel" />
     134      <base:button id="btnSave" title="Save" />
     135      <base:button id="close" title="Cancel" />
    169136    </base:buttongroup>
    170137  </base:body>
  • trunk/www/lims/plates/wells/wells.js

    r6307 r6312  
    3535    if (pageId == 'edit-page')
    3636    {
    37       // TODO
     37      // Save + Close buttons
     38      Buttons.addClickHandler('btnSave', wells.save);
     39      Buttons.addClickHandler('close', App.closeWindow);
     40
     41      // Tab validation
     42      TabControl.addTabActivateListener('settings.annotations', Annotations.autoLoadEditFrame);
     43      TabControl.addTabActivateListener('settings.inheritedAnnotations', Annotations.autoLoadInheritFrame);
     44      TabControl.addTabValidator('settings.info', wells.validateWell);
    3845    }
    3946    else if (pageId == 'view-page')
     
    93100  }
    94101
     102  wells.validateWell = function()
     103  {
     104    return true;
     105  }
    95106
     107  // Submit the form
     108  wells.save = function()
     109  {
     110    var frm = document.forms['well'];
     111    if (TabControl.validateActiveTab('settings'))
     112    {
     113      Annotations.saveModifiedAnnotationsToForm(frm);
     114      Annotations.saveInheritedAnnotationsToForm(frm);
     115      frm.submit();
     116    }
     117  }
     118 
    96119  return wells;
    97120}();
  • trunk/www/lims/platetypes/eventtypes/eventtypes.js

    r6306 r6312  
    122122    var frm = document.forms['eventtype'];
    123123    var protocolType = Data.get('protocoltype_id', 'protocol-type-filter');
    124     var url = url += '&resetTemporary=1&tmpfilter:INT:itemType='+protocolType;
     124    var url = '&resetTemporary=1&tmpfilter:INT:itemType='+protocolType;
    125125    if (frm.protocoltype_id.length > 1)
    126126    {
     
    136136    if (list.length < 2 || list[1].disabled)
    137137    {
    138       Forms.addListOption(list, 0, new Option());
     138      Forms.addListOption(list, 1, new Option());
    139139    }
    140     list[0].value = event.detail.id;
    141     list[0].text = event.detail.name;
     140    list[1].value = event.detail.id;
     141    list[1].text = event.detail.name;
    142142    list.selectedIndex = 1;
    143143  }
Note: See TracChangeset for help on using the changeset viewer.