source: extensions/net.sf.basedb.reggie/trunk/resources/partitionform.jsp @ 1425

Last change on this file since 1425 was 1425, checked in by Martin Svensson, 10 years ago

References #330 The partition wizard is now fully functional. Some testings are left to do.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.0 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.User"
5  import="net.sf.basedb.core.DbControl"
6  import="net.sf.basedb.core.SessionControl"
7  import="net.sf.basedb.clients.web.Base" 
8%>
9<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
10<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
11<%
12final SessionControl sc = Base.getExistingSessionControl(request, true);
13final String ID = sc.getId();
14final float scale = Base.getScale(sc);
15DbControl dc = null;
16try
17{
18  dc = sc.newDbControl();
19  final User user = User.getById(dc, sc.getLoggedInUserId());
20%>
21<base:page type="default" >
22<base:head scripts="ajax.js" styles="path.css">
23  <link rel="stylesheet" type="text/css" href="reggie.css">
24  <script language="JavaScript" src="reggie.js" type="text/javascript" charset="UTF-8"></script>
25 
26 
27<script language="JavaScript">
28var debug = false;
29var currentStep = 1;
30
31var specimenTubes = null;
32var selectedTubes = null;
33
34var partitionDateIsValid = false;
35
36var spWeightsAreValid;
37var apWeightsAreValid;
38var hisWeightsAreValid;
39var nofPiecesAreValid;
40
41function init()
42{
43  var frm = document.forms['reggie'];
44  var selectList = frm.tubesSelect;
45  getSpecimenTubes();
46 
47  var specimenTubeOptions = '';
48  if (specimenTubes != null && specimenTubes.length > 0)
49  {
50    for (var i=0;i<specimenTubes.length;i++)
51    {
52      var tube = specimenTubes[i];
53      selectList.options[selectList.length] = new Option(tube.name, tube.name);
54    }
55  }
56  else
57  {
58    selectList.disabled = true;
59    Main.hide('gonext');   
60    setInputStatus('tubes','No tubes available for partition', 'invalid')
61  } 
62}
63
64function goNext()
65{
66  setInnerHTML('gonext.message', '');
67  if (currentStep == 1)
68  {   
69    gotoStep2();
70  }
71  else if (currentStep == 2)
72  {
73    partitionDateOnBlur();
74    if (step2IsValid()) gotoStep3();
75  }
76}
77
78function step2IsValid()
79{
80  return partitionDateIsValid;
81}
82
83function step3IsValid()
84{
85  for (var i=0; i<spWeightsAreValid.length; i++)
86  {
87    if (spWeightsAreValid[i] == false ||
88        apWeightsAreValid[i] == false ||
89        hisWeightsAreValid[i] == false ||
90        nofPiecesAreValid[i] == false)
91    {
92      return false;
93    }
94  } 
95  return true;
96}
97
98function gotoStep2()
99{
100  var frm = document.forms['reggie'];
101  var selectList = frm.tubesSelect;
102  selectedTubes = new Array();
103  for (var i=0;i<selectList.length; i++)
104  {
105    if (selectList.options[i].selected)
106      selectedTubes.push(specimenTubes[i]);
107  }   
108 
109  if (selectedTubes.length == 0)
110  {
111    setInputStatus('tubes', 'Missing', 'invalid');
112    return;
113  }
114 
115  setInputStatus('tubes', '', 'valid');
116  // Change section
117  frm.tubesSelect.disabled = true;
118 
119  Main.show('partitionSection');
120  Main.show('gocancel');
121  var currentTime = new Date();
122  frm.partitionDate.value = currentTime.getFullYear().toString()+(currentTime.getMonth()+1).toString()+currentTime.getDate().toString();
123  frm.partitionDate.setSelectionRange(0,frm.partitionDate.value.length);
124  frm.partitionDate.focus();
125  currentStep = 2;
126}
127
128function gotoStep3()
129{
130  var frm = document.forms['reggie'];
131  frm.partitionDate.disabled = true; 
132   
133  var inputWeightHtml; 
134  if (selectedTubes.length > 0)
135  {
136    spWeightsAreValid = Array();
137    apWeightsAreValid = Array();
138    hisWeightsAreValid = Array();
139    nofPiecesAreValid = Array();
140       
141    inputWeightHtml = '';
142
143    var spTitle = 'SpWeight<br>';
144    var apTitle = 'ApWeight<br>';
145    var hisTitle = 'HisWeight<br>';
146    var nofTitle = 'NofPieces<br>';
147    var appearanceTitle = 'Appearance<br>';
148    var necrosisTitle = 'Necrosis%<br>';
149    var fatTitle = 'Fat%<br>';
150    var colouredTitle = 'Coloured<br>';
151    var bloodyTitle = 'Bloody<br>';
152   
153    var appearanceOptions = '<option selected ></option>'; 
154    appearanceOptions += '<option value="HOMOGENUS">Homogenus</option>';
155    appearanceOptions += '<option value="HETEROGENUS">Heterogenus</option>';
156   
157    var necrosisOptions = '<option selected value="0">0</option>';
158    necrosisOptions += '<option value="20">20</option>';
159    necrosisOptions += '<option value="40">40</option>';
160    necrosisOptions += '<option value="60">60</option>';
161    necrosisOptions += '<option value="80">80</option>';
162    necrosisOptions += '<option value="100">100</option>';
163   
164    var fatOptions = '<option selected value=0>0</option>';
165    fatOptions += '<option value=20>20</option>';
166    fatOptions += '<option value=40>40</option>';
167    fatOptions += '<option value=60>60</option>';
168    fatOptions += '<option value=80>80</option>';
169    fatOptions += '<option value=100>100</option>';
170   
171    for (var i=0;i<selectedTubes.length; i++)
172    {
173      var tube = selectedTubes[i];
174      var nextStep = i<(selectedTubes.length-1) ? 'focusOnEnter(event, \'bloody'+(i+1)+'\')' : 'doOnTabOrEnter(event, goCreate)';
175     
176      inputWeightHtml += '<tr>';
177      inputWeightHtml += '<td rowspan=2 class=prompt>'+tube.name;
178      // Only show box information if there is something show.     
179      if (tube.row != null && tube.column != null)
180      {
181        inputWeightHtml += ' ['+tube.box+'&nbsp;'+tube.row+tube.column+']';
182      }
183      inputWeightHtml += '</td>';
184     
185      inputWeightHtml += '<td style="width:400px;">';
186      inputWeightHtml += '<table style="width:100%"><tr>';     
187      inputWeightHtml += '<td>'+bloodyTitle+'<input type=checkbox onkeypress="checkOnNumber(event, this);focusOnEnter(event, \'appearance'+i+'\')" onfocus="messageOnFocus(0,'+i+')" name=bloody'+i+' /></td>';
188      inputWeightHtml += '<td>'+appearanceTitle+'<select name=appearance'+i+' onfocus="messageOnFocus(1,'+i+')" onkeypress="focusOnEnter(event, \'necrosis'+i+'\')">'+appearanceOptions+'</select></td>';
189      inputWeightHtml += '<td>'+necrosisTitle+'<select name=necrosis'+i+' onfocus="messageOnFocus(2,'+i+')" onkeypress="focusOnEnter(event, \'fat'+i+'\')">'+necrosisOptions+'</select></td>'; 
190      inputWeightHtml += '<td>'+fatTitle+'<select name=fat'+i+' onfocus="messageOnFocus(3,'+i+')" onkeypress="focusOnEnter(event, \'coloured'+i+'\')">'+fatOptions+'</select></td>';
191      inputWeightHtml += '<td>'+colouredTitle+'<input type=checkbox name=coloured'+i+' onfocus="messageOnFocus(4,'+i+')" onkeypress="checkOnNumber(event, this);focusOnEnter(event, \'nofPieces'+i+'\')" /></td>'
192      inputWeightHtml += '<td>'+nofTitle+'<input name="nofPieces'+i+'" onfocus="messageOnFocus(5,'+i+')" onchange="nofPiecesOnChange('+i+')" onkeypress="focusOnEnter(event, \'spWeight'+i+'\')" size=2 /></td>';
193      inputWeightHtml += '<td>'+spTitle+'<input name="spWeight'+i+'" onfocus="messageOnFocus(6,'+i+')" onchange="spWeightOnChange('+i+')" onkeypress="focusOnEnter(event, \'hisWeight'+i+'\')" size=2 /></td>';
194      inputWeightHtml += '<td>'+hisTitle+'<input name="hisWeight'+i+'" onfocus="messageOnFocus(7,'+i+')" onchange="hisWeightOnChange('+i+')" onkeypress="focusOnEnter(event, \'apWeight'+i+'\')" size=2 /></td>';
195      inputWeightHtml += '<td>'+apTitle+'<input name="apWeight'+i+'" onfocus="messageOnFocus(8,'+i+')" onchange="apWeightOnChange('+i+')" onkeypress="'+nextStep+'" size=2 /></td>';     
196      inputWeightHtml += '</tr>';
197      inputWeightHtml += '</table>';
198      inputWeightHtml += '</td>';
199      inputWeightHtml += '<td rowspan=2 class="status" id="'+i+'.status"></td>';     
200      inputWeightHtml += '</tr>';
201     
202      inputWeightHtml += '<tr>';
203      inputWeightHtml += '<td style="width:400px;" class="help"><span class="message" id="'+i+'.message"></span><span id="'+i+'.help"></span></td>';     
204      inputWeightHtml += '</tr>';     
205      inputWeightHtml += '<tr><td>&nbsp;</td></tr>';
206    }
207    setInnerHTML('weightInputs', inputWeightHtml);
208  }
209  Main.show('weightSection');
210  Main.hide('gonext');
211  Main.show('gocreate');
212  frm.bloody0.focus(); 
213}
214
215function checkOnNumber(event, element)
216{
217  if (event.charCode == 48)
218  {
219    element.checked = false;
220  }
221  else if (event.charCode == 49)
222  {
223    element.checked = true;
224  }
225  return true;
226}
227
228function messageOnFocus(order, tubeIndex)
229{
230  var helpMessage;
231  switch(order)
232  {
233    case 0:
234      helpMessage = 'Check this if the partition is bloody. Unchecked is default.';
235      break;
236    case 1:
237      helpMessage = 'Select appearance. Empty is default';
238      break;
239    case 2:
240      helpMessage = 'Select percentage of necrosis. \'0\' is default.';
241      break;
242    case 3:
243      helpMessage = 'Select percentage of fat. \'0\' is default.';
244      break;
245    case 4:
246      helpMessage = 'Check this if the partition is coloured. Unchecked is default.';
247      break;
248    case 5:
249      helpMessage = 'Number of pieces in this partition.';
250      break;
251    case 6:
252      helpMessage = 'Sp weight in [mg].';
253      break;
254    case 7:
255      helpMessage = 'His weight in [mg].';
256      break;
257    case 8:
258      helpMessage = 'Ap weight in [mg].';
259      break;
260    default:
261      helpMessage='&nbsp;';
262  }
263  for (var i=0;i<selectedTubes.length;i++)
264  {
265    if (i!=tubeIndex) setInnerHTML(i+'.help', '&nbsp;')
266  }
267  setInnerHTML(tubeIndex+'.help', helpMessage); 
268}
269
270function updateInputStatus(tubeIndex)
271{
272  var frm = document.forms['reggie'];
273  if(nofPiecesAreValid[tubeIndex] == false)
274  {
275    setInputStatus(tubeIndex, 'NofPieces is invalid.', 'invalid');
276    frm.elements['nofPieces'+tubeIndex].focus();
277    return ;
278  }
279  if (spWeightsAreValid[tubeIndex] == false)
280  {
281    setInputStatus(tubeIndex, 'SpWeight is invalid.','invalid');
282    return;
283  }
284  if(hisWeightsAreValid[tubeIndex] == false)
285  {
286    setInputStatus(tubeIndex, 'HisWeight is invalid.', 'invalid');
287    return;
288  }
289  if(apWeightsAreValid[tubeIndex] == false)
290  {
291    setInputStatus(tubeIndex, 'APWeight is invalid.', 'invalid');
292    return;
293  }   
294  setInputStatus(tubeIndex, '', 'valid');
295}
296
297function spWeightOnChange(tubeIndex)
298{
299  var inputName = 'spWeight'+tubeIndex;
300  var frm = document.forms['reggie'];
301  var weightInput = frm.elements[inputName].value;
302  if (weightInput != '')
303  {
304    if (weightInput < 0)
305    {
306      spWeightsAreValid[tubeIndex] = false;
307      updateInputStatus(tubeIndex);
308      return;
309    }
310    if (weightInput == '0')
311    {
312      frm.elements[inputName].value = '';
313    }
314  } 
315  spWeightsAreValid[tubeIndex] = true;
316  updateInputStatus(tubeIndex);
317}
318
319function apWeightOnChange(tubeIndex)
320{
321  var inputName = 'apWeight'+tubeIndex;
322  var frm = document.forms['reggie'];
323  var weightInput = frm.elements[inputName].value;
324  if (weightInput != '')
325  {
326    if (weightInput < 0)
327    {
328      apWeightsAreValid[tubeIndex] = false;
329      updateInputStatus(tubeIndex);
330      return;
331    } 
332    if (weightInput == '0')
333    {
334      frm.elements[inputName].value = '';
335    } 
336  }
337  apWeightsAreValid[tubeIndex] = true;
338  updateInputStatus(tubeIndex);
339}
340
341function hisWeightOnChange(tubeIndex)
342{
343  var inputName = 'hisWeight'+tubeIndex;
344  var frm = document.forms['reggie'];
345  var weightInput = frm.elements[inputName].value;
346  if (weightInput != '')
347  {
348    if (weightInput < 0)
349    {
350      hisWeightsAreValid[tubeIndex] = false;
351      updateInputStatus(tubeIndex);
352      return;
353    }
354    if (weightInput == '0')
355    {
356      frm.elements[inputName].value = '';
357    }   
358  } 
359  hisWeightsAreValid[tubeIndex] = true;
360  updateInputStatus(tubeIndex);
361}
362
363function nofPiecesOnChange(tubeIndex)
364{
365  var inputName = 'nofPieces'+tubeIndex;
366  var frm = document.forms['reggie'];
367  var fieldInput = frm.elements[inputName].value;
368  if (fieldInput != '')
369  {
370    if (fieldInput < 0)
371    {
372      nofPiecesAreValid[tubeIndex] = false;
373      updateInputStatus(tubeIndex);
374      return;
375    } 
376    if (fieldInput == '0')
377    {
378      frm.elements[inputName].value = '';
379    } 
380  } 
381  nofPiecesAreValid[tubeIndex] = true;
382  updateInputStatus(tubeIndex);
383}
384
385function partitionDateOnBlur()
386{
387  var frm = document.forms['reggie'];
388  var partitionDate = frm.partitionDate.value;
389  var todaysDate = new Date();
390  partitionDateIsValid = false;
391 
392  setInputStatus('partitionDate', '', '');
393 
394  if (partitionDate != '')
395  {
396    partitionDate = autoFillDate(partitionDate);
397    frm.partitionDate.value = partitionDate;
398   
399    if (!Dates.isDate(partitionDate, 'yyyyMMdd'))
400    {
401      setInputStatus('partitionDate', 'Not a valid date', 'invalid');
402      return;
403    }   
404    if (todaysDate < new Date(partitionDate.substring(0,4), new Number(partitionDate.substring(4,6)-1), partitionDate.substring(6)))
405    {
406      setInputStatus('partitionDate', 'Future dates are not valid','invalid');
407      return;
408    }
409    setInputStatus('partitionDate','','valid');   
410  }
411  else
412  {
413    setInputStatus('partitionDate', 'Missing', 'invalid');
414    return;
415  }
416  partitionDateIsValid = true;
417}
418
419function getSpecimenTubes()
420{
421  var frm = document.forms['reggie']; 
422 
423  var request = Ajax.getXmlHttpRequest();
424  var url = 'PartitionRegistration.servlet?ID=<%=ID%>&cmd=GetSpecimenTubes';   
425  request.open("GET", url, false); 
426  request.send(null);
427
428  if (debug) Main.debug(request.responseText); 
429  var response = JSON.parse(request.responseText); 
430  if (response.status != 'ok')
431  {
432    setFatalError(response.message);
433    return false;
434  } 
435  specimenTubes = response.tubeInfo.specimenTubes;
436}
437
438function goCreate()
439{
440  if (!step3IsValid()) return;
441 
442  Main.hide('gocancel');
443  Main.hide('gocreate');
444 
445  var frm = document.forms['reggie'];
446  var tubeInfo = new Object();
447 
448  var specimens = selectedTubes;
449  var nofTubes = specimens.length;
450  var partitionDateValue = frm.elements['partitionDate'].value;
451  tubeInfo.partitionDate = partitionDateValue;
452  for (var i=0; i<nofTubes; i++)
453  {
454    frm.elements['spWeight'+i].disabled = true;
455    frm.elements['apWeight'+i].disabled = true;
456    frm.elements['hisWeight'+i].disabled = true;
457    frm.elements['nofPieces'+i].disabled = true;
458    frm.elements['bloody'+i].disabled = true;
459    frm.elements['appearance'+i].disabled = true;
460    frm.elements['necrosis'+i].disabled = true;
461    frm.elements['fat'+i].disabled = true;
462    frm.elements['coloured'+i].disabled = true;
463       
464    var specimenTube = specimens[i];
465   
466    var spWeightValue = frm.elements['spWeight'+i].value; 
467    if (spWeightValue != '') specimenTube.spWeight = spWeightValue;
468    var apWeightValue = frm.elements['apWeight'+i].value;
469    if (apWeightValue != '') specimenTube.apWeight = apWeightValue;
470    var hisWeightValue = frm.elements['hisWeight'+i].value;
471    if (hisWeightValue != '') specimenTube.hisWeight = hisWeightValue;
472    var nofPiecesValue = frm.elements['nofPieces'+i].value;
473    if (nofPiecesValue != '') specimenTube.nofPieces = nofPiecesValue;
474   
475    var partitionComment = ''; 
476    var appearanceElement = frm.elements['appearance'+i];
477    var necrosisElement = frm.elements['necrosis'+i];
478    var fatElement = frm.elements['fat'+i];
479    var appearanceValue = appearanceElement.options[appearanceElement.selectedIndex].value;   
480    var necrosisValue = necrosisElement.options[necrosisElement.selectedIndex].value;
481    var fatValue = fatElement.options[fatElement.selectedIndex].value;
482   
483    // Generate partition comment string
484    if (frm.elements['bloody'+i].checked == true) partitionComment += 'BLOODY';
485    if (appearanceValue != '') partitionComment += (partitionComment.length>0 ? ':' : '') + appearanceValue;
486    if (necrosisValue != '0') partitionComment += (partitionComment.length>0 ? ':' : '') + 'NECROSIS'+necrosisValue+'%';
487    if (fatValue != '0') partitionComment += (partitionComment.length>0 ? ':' : '') + 'FAT'+fatValue+'%';
488    if (frm.elements['coloured'+i].checked == true) partitionComment += partitionComment.length>0 ? ':COLOURED' : 'COLOURED';
489   
490    specimenTube.otherPartitionComment = partitionComment.length > 0 ? partitionComment : null;
491   
492    specimens[i] = specimenTube;   
493  }
494  tubeInfo.specimens = specimens;
495  var submitInfo = new Object();
496  submitInfo.tubeInfo = tubeInfo;
497 
498  if (debug) Main.debug(JSON.stringify(caseInfo));
499 
500  var request = Ajax.getXmlHttpRequest();
501  var url = 'PartitionRegistration.servlet?ID=<%=ID%>&cmd=CreatePartitions';
502  request.open("POST", url, false);
503  request.setRequestHeader("Content-Type", "application/json");
504  request.send(JSON.stringify(submitInfo));
505
506  if (debug) Main.debug(request.responseText);
507
508  var response = JSON.parse(request.responseText);
509  if (response.status != 'ok')
510  {
511    setFatalError(response.message);
512    return false;
513  }
514
515  var msg = '<ul>';
516  for (var i = 0; i < response.messages.length; i++)
517  {
518    msg += '<li>' + response.messages[i];
519  }
520  msg += '</ul>';
521  setInnerHTML('done', msg);
522 
523 
524  Main.show('done');
525  Main.show('gorestart');
526}
527</script>
528
529
530</base:head>
531<base:body onload="init()">
532<p:path style="margin-top: 20px; margin-bottom: 10px;">
533    <p:pathelement title="Reggie" href="<%="index.jsp?ID="+ID%>" />
534    <p:pathelement title="Partition registration" />
535  </p:path>
536
537  <%
538  if (sc.getActiveProjectId() == 0)
539  {
540    %>
541    <base:note type="warning" style="width: 800px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
542      No project has been selected. You may proceed with the registration but
543      created items will not be shared.
544    </base:note>
545    <%
546  }
547  %>
548
549  <form name="reggie" onsubmit="return false;">
550 
551  <!-- 1. Case name-->
552  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
553  <tr>
554    <td rowspan="3" class="stepno">1</td>
555    <td class="steptitle">Select specimen tubes</td>
556  </tr>
557  <tr>
558    <td class="stepfields">
559      <table border="0" cellspacing="0" cellpadding="0" width="100%">
560      <tr valign="top">
561        <td class="prompt">Specimen tubes</td>
562        <td class="input"><select style="width:50%" name="tubeSelect" id="tubesSelect" multiple="multiple" size="5" onkeypress='doOnTab(event, goNext)'></select></td>
563        <td class="status" id="tubes.status"></td>
564        <td class="help"><span id="tubes.message" class="message" style="display: none;"></span>Select specimen tubes to include in the partition.</td>
565      </tr>
566      </table>
567    </td>
568  </tr>
569  </table>
570 
571  <!-- 2. General partition information -->
572  <div id="partitionSection" style="display: none;">
573    <p></p>
574    <table border="0" cellspacing="0" cellpadding="0" class="stepform">
575    <tr>
576      <td rowspan="2" class="stepno">2</td>
577      <td class="steptitle">Enter partition information</td>
578    </tr>
579    <tr>
580      <td class="stepfields">
581        <table border="0" cellspacing="0" cellpadding="0" width="100%">
582        <tr valign="top">
583          <td class="prompt">Partition date</td>
584          <td class="input"><input type="text" name="partitionDate" 
585             onkeypress="doOnTabOrEnter(event, goNext)" size="12" maxlength="10" onBlur="partitionDateOnBlur()"></td>
586          <td class="status" id="partitionDate.status"></td>
587          <td class="help"><span id="partitionDate.message" class="message" style="display: none;"></span>The date when the partition was done.</td>
588        </tr>       
589        </table>
590      </td>
591    </tr>
592    </table>
593  </div>
594 
595  <div id="weightSection" style="display:none;">
596    <p></p>
597    <table border="0" cellspacing="0" cellpadding="0" class="stepform">
598    <tr>
599      <td rowspan="2" class="stepno">3</td>
600      <td class="steptitle">Enter weight information</td>   
601    </tr>
602    <tr>
603      <td class="stepfields">
604        <table id="weightInputs" border="0" cellspacing="0" cellpadding="0" width="100%"></table>
605      </td>
606    </tr>
607    </table>
608  </div>
609   
610  <div class="error" id="errorMessage" style="display: none; width: 800px; margin-left: 20px; margin-bottom: 0px;"></div>
611 
612  <div id="done" class="success" style="display: none; width: 800px; margin-left: 20px; margin-top: 20px;"></div>
613 
614  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
615    <tr>
616      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
617      <td><base:button id="gonext" title="Next" image="gonext.gif" onclick="goNext(true)"/></td>
618      <td><base:button id="gocreate" title="Create" image="gonext.gif" onclick="goCreate()" style="display: none;"/></td>
619      <td><base:button id="goupdate" title="Update" image="gonext.gif" onclick="goCreate()" style="display: none;"/></td>
620      <td><base:button id="gorestart" title="Restart" image="goback.gif" onclick="goRestart(true)" style="display: none;"/></td>
621      <td id="gonext.message" class="message"></td>
622    </tr>
623  </table>
624  </form>
625 
626</base:body>
627</base:page>
628<%
629}
630finally
631{
632  if (dc != null) dc.close();
633}
634%>
Note: See TracBrowser for help on using the repository browser.