source: extensions/net.sf.basedb.reggie/trunk/resources/persinfo.jsp @ 1289

Last change on this file since 1289 was 1289, checked in by Nicklas Nordborg, 11 years ago

References #291: Personal information registration

Copy PAD annotations to PADcase. Display more specimen information in the third step of the registration. Automatic selection of laterality if it is present on the specimen. More error handling in case no specimen is found.

File size: 14.6 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.Application"
5  import="net.sf.basedb.core.User"
6  import="net.sf.basedb.core.DbControl"
7  import="net.sf.basedb.core.SessionControl"
8  import="net.sf.basedb.clients.web.Base"
9  import="net.sf.basedb.clients.web.util.HTML"
10  import="net.sf.basedb.util.Values"
11%>
12<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
13<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
14<%
15final SessionControl sc = Base.getExistingSessionControl(request, true);
16final String ID = sc.getId();
17final float scale = Base.getScale(sc);
18DbControl dc = null;
19try
20{
21  dc = sc.newDbControl();
22  final User user = User.getById(dc, sc.getLoggedInUserId());
23%>
24<base:page type="default" >
25<base:head scripts="ajax.js" styles="path.css">
26<script language="JavaScript">
27
28var currentStep = 1;
29var pnrIsValid = false;
30var caseIsValid = false;
31
32var patientInfo = null;
33var caseInfo = null;
34
35function goNext()
36{
37  if (currentStep == 1)
38  {
39    if (pnrIsValid && caseIsValid) gotoStep2();
40  }
41  else if (currentStep == 2)
42  {
43    gotoStep3();
44  }
45}
46
47function caseNameOnChange()
48{
49  var frm = document.forms['reggie'];
50  var caseName = frm.caseName.value;
51  if (caseName == '')
52  {
53    setInputStatus('case', 'Missing', false);
54    return;
55  }
56  setInputStatus('case', '', true);
57  caseIsValid = true;
58}
59
60function personalNumberOnChange()
61{
62  var frm = document.forms['reggie'];
63  var pnr = frm.personalNumber.value;
64  pnrIsValid = false;
65 
66  if (pnr.length < 12)
67  {
68    setInputStatus('pnr', 'Too short', false);
69    return;
70  }
71 
72  if (!Dates.isDate(pnr.substring(0, 8), 'yyyyMMdd'))
73  {
74    setInputStatus('pnr', 'Not a valid date', false);
75    return;
76  }
77 
78  var sum = 0;
79  var factor = 2;
80  var x = '';
81  for (var i = 2; i < 11; i++)
82  {
83    var digit = parseInt(pnr.substr(i, 1));
84    var tmp = factor * digit;
85    x += '(' + factor + '*' + digit+')';
86    sum += tmp >= 10 ? tmp - 9: tmp;
87    factor = factor == 2 ? 1 : 2;
88  }
89 
90  var control = 10 - (sum % 10);
91  if (control != parseInt(pnr.substr(11, 1)))
92  {
93    setInputStatus('pnr', 'Invalid control digit', false);
94    return;
95  }
96 
97  setInputStatus('pnr', '', true);
98  pnrIsValid = true;
99 
100  if (caseIsValid) gotoStep2();
101}
102
103function allFirstNamesOnKeyPress(event)
104{
105  if (event.keyCode == 9) setTimeout('goNext()', 200);
106  return true;
107}
108
109function gotoStep2()
110{
111  // Check entered case and pnr with AJAX
112  var frm = document.forms['reggie'];
113  frm.caseName.disabled = true;
114  frm.personalNumber.disabled = true;
115  currentStep = 2;
116 
117  var pnr = frm.personalNumber.value;
118  var caseName = frm.caseName.value;
119  var request = Ajax.getXmlHttpRequest();
120  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=CheckPersonalNumberAndCaseName';
121  url += '&personalNumber=' + pnr;
122  url += '&caseName=' + caseName;
123  request.open("GET", url, false);
124  request.send(null);
125 
126  setInnerHTML('debug', request.responseText);
127 
128  var response = JSON.parse(request.responseText);
129  if (response.status != 'ok')
130  {
131    setFatalError(response.message);
132    return false;
133  }
134 
135  // Get biosource information from the AJAX response
136  patientInfo = response.patientInfo;
137  caseInfo = response.caseInfo;
138 
139  if (!patientInfo.id)
140  {
141    Main.show('newPatientSection');
142    frm.patientCode.value=patientInfo.name;
143    setInnerHTML('new.dateOfBirth', patientInfo.dateOfBirth);
144    setInnerHTML('new.gender', patientInfo.gender);
145    frm.familyName.focus();
146  }
147  else
148  {
149    Main.show('existingPatientSection');
150    setInnerHTML('existing.patientCode', patientInfo.name);
151    setInnerHTML('existing.familyName', patientInfo.familyName);
152    setInnerHTML('existing.allFirstNames', patientInfo.allFirstNames);
153    setInnerHTML('existing.dateOfBirth', patientInfo.dateOfBirth);
154    setInnerHTML('existing.gender', patientInfo.gender);
155   
156  }
157}
158
159function gotoStep3()
160{
161  // Check entered case and pnr with AJAX
162  var frm = document.forms['reggie'];
163  if (frm.patientCode)
164  {
165    var formOk = true;
166    // Validate 'New patient' form
167    if (frm.allFirstNames.value == '')
168    {
169      setInputStatus('allFirstNames', 'Missing', false);
170      frm.allFirstNames.focus();
171      formOk = false;
172    }
173    else
174    {
175      setInputStatus('allFirstNames', '', true);
176    }
177   
178    if (frm.familyName.value == '')
179    {
180      setInputStatus('familyName', 'Missing', false);
181      frm.familyName.focus();
182      formOk = false;
183    }
184    else
185    {
186      setInputStatus('familyName', '', true);
187    }
188
189   
190    if (frm.patientCode.value == '')
191    {
192      setInputStatus('patientCode', 'Missing', false);
193      frm.patientCode.focus();
194      formOk = false;
195    }
196    else
197    {
198      setInputStatus('patientCode', '', true);
199    }
200    if (!formOk) return;
201  }
202 
203  currentStep = 3;
204  if (!patientInfo.id)
205  {
206    frm.patientCode.disabled = true;
207    frm.familyName.disabled = true;
208    frm.allFirstNames.disabled = true;
209    patientInfo.familyName = frm.familyName.value;
210    patientInfo.allFirstNames = frm.allFirstNames.value;
211  }
212 
213  if (!patientInfo.cases || patientInfo.cases.length == 0)
214  {
215    Main.show('newCaseSection'); 
216  }
217 
218  if (caseInfo.specimen && caseInfo.specimen.length > 0)
219  {
220    var specimenTubes = '';
221    Main.hide('reasonIfNoSpecimenSection');
222    for (var i = 0; i < caseInfo.specimen.length; i++)
223    {
224      var specimen = caseInfo.specimen[i];
225      specimenTubes += specimen.name ;
226      if (specimen.laterality) 
227      {
228        specimenTubes += ' ('+specimen.laterality + ')';
229        Forms.checkRadio(frm.laterality, specimen.laterality);
230      }
231      specimenTubes += '<br>';
232    }
233    setInnerHTML('specimenTubes', specimenTubes);
234  }
235 
236  Main.hide('gonext');
237  Main.show('gocreate');
238}
239
240function goCreate()
241{
242  var frm = document.forms['reggie'];
243
244  caseInfo.laterality = Forms.getCheckedRadio(frm.laterality).value;
245  caseInfo.reasonIfNoSpecimen = frm.reasonIfNoSpecimen.value;
246 
247  var submitInfo = new Object();
248  submitInfo.patientInfo = patientInfo;
249  submitInfo.caseInfo = caseInfo;
250  //alert(JSON.stringify(submitInfo));
251
252  var request = Ajax.getXmlHttpRequest();
253  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=Create';
254  request.open("POST", url, false);
255  request.setRequestHeader("Content-Type", "application/json");
256  request.send(JSON.stringify(submitInfo));
257
258  setInnerHTML('debug', request.responseText);
259}
260
261
262function setInnerHTML(id, html)
263{
264  var tag = document.getElementById(id);
265  if (!tag) alert('No tag with id='+id);
266  tag.innerHTML = html;
267}
268
269function setInputStatus(prefix, message, isValid)
270{
271  var tag = document.getElementById(prefix + '.status');
272  Main.addClass(tag, isValid ? 'isvalid' : 'invalid');
273  Main.removeClass(tag, isValid ? 'invalid' : 'isvalid');
274 
275  setInnerHTML(prefix + '.message', message);
276  if (message)
277  {
278    Main.showInline(prefix + '.message');
279  }
280  else
281  {
282    Main.hide(prefix + '.message');
283  }
284}
285
286function setFatalError(message)
287{
288  setInnerHTML('errorMessage', message);
289  Main.show('errorMessage');
290  Main.hide('gonext');
291  Main.show('gorestart');
292}
293
294function goRestart()
295{
296  location.href = location.href;
297}
298</script>
299<style>
300
301.stepform
302{
303  margin-left: 20px;
304  border: 1px solid #999999;
305  width: 800px;
306  table-layout: fixed;
307}
308
309.stepno
310{
311  width: 20px;
312  font-size: 20px;
313  font-weight: bold;
314  color: #E0E0E0;
315  background: #555577;
316  vertical-align: top;
317  text-align: center;
318}
319
320.steptitle
321{
322  width: 780px;
323  color: #333377;
324  background: #E0E0E0;
325  font-weight: bold;
326  padding: 1px 4px 1px 4px;
327  border-bottom: 1px solid #999999;
328}
329
330.nextstep
331{
332  width: 780px;
333  color: #333377;
334  background: #E0E0E0;
335  font-weight: bold;
336  padding: 1px 4px 1px 4px;
337  border-top: 1px solid #999999;
338}
339
340.stepfields
341{
342  width: 780px;
343}
344
345.prompt
346{
347  width: 150px;
348  font-weight: bold;
349  padding: 1px 2px 1px 2px;
350}
351
352.input
353{
354  width: 250px;
355  padding: 1px 2px 1px 2px;
356}
357
358.status
359{
360  width: 30px;
361  padding: 1px 2px 1px 2px;
362}
363
364.help
365{
366  background: #e0e0e0;
367  width: 350px;
368  font-style: italic;
369  padding: 1px 2px 1px 2px;
370}
371
372.message
373{
374  color: #cc0000;
375  font-weight: bold;
376  padding-right: 6px;
377}
378
379.status.invalid:before
380{
381  content: url('../../images/error.gif');
382}
383.status.isvalid:before
384{
385  content: url('../../images/ok.gif');
386}
387
388</style>
389</base:head>
390<base:body>
391
392  <p:path style="margin-top: 20px; margin-bottom: 10px;">
393    <p:pathelement title="Reggie" href="<%="index.jsp?ID="+ID%>" />
394    <p:pathelement title="Personal information registration" />
395  </p:path>
396
397  <form name="reggie" onsubmit="return false;">
398 
399  <!-- 1. Case + Personal number -->
400  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
401  <tr>
402    <td rowspan="3" class="stepno">1</td>
403    <td class="steptitle">Enter Case Name and Personal Number</td>
404  </tr>
405  <tr>
406    <td class="stepfields">
407      <table border="0" cellspacing="0" cellpadding="0" width="100%">
408      <tr valign="top">
409        <td class="prompt">Case Name</td>
410        <td class="input"><input type="text" name="caseName" 
411          size="18" maxlength="12" onblur="caseNameOnChange()"></td>
412        <td class="status" id="case.status"></td>
413        <td class="help"><span id="case.message" class="message" style="display: none;"></span>The case (barcode) associated with this patient.</td>
414      </tr>
415      <tr>
416        <td class="prompt">Personal Number</td>
417        <td class="input"><input type="text" name="personalNumber" 
418          size="18" maxlength="12" onkeyup="personalNumberOnChange()"></td>
419        <td class="status" id="pnr.status"></td>
420        <td class="help"><span id="pnr.message" class="message" style="display: none;"></span>(YYYYMMDDZZZZ)</td>
421      </tr>
422      </table>
423    </td>
424  </tr>
425  </table>
426
427  <!-- 2. New patient registration -->
428  <div id="newPatientSection" style="display: none;">
429  <p>
430  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
431  <tr>
432    <td rowspan="2" class="stepno">2</td>
433    <td class="steptitle">New patient: Enter all names</td>
434  </tr>
435  <tr>
436    <td class="stepfields">
437      <table border="0" cellspacing="0" cellpadding="0" width="100%">
438      <tr>
439        <td class="prompt">Patient code</td>
440        <td class="input"><input type="text" name="patientCode" value="" size="18" maxlength="12"></td>
441        <td class="status" id="patientCode.status"></td>
442        <td class="help"><span id="patientCode.message" class="message" style="display: none;"></span></td>
443      </tr>
444      <tr valign="top">
445        <td class="prompt">Family name</td>
446        <td class="input"><input type="text" name="familyName" 
447          size="35" maxlength="255"></td>
448        <td class="status" id="familyName.status"></td>
449        <td class="help"><span id="familyName.message" class="message" style="display: none;"></span>Keep hyphens, keep åäö, replace all special accented letters [e.g. éèü etc] with standard alphabet character.</td>
450      </tr>
451      <tr valign="top">
452        <td class="prompt">All first names</td>
453        <td class="input"><input type="text" name="allFirstNames" 
454          size="35" maxlength="255" onkeypress="allFirstNamesOnKeyPress(event)"></td>
455        <td class="status" id="allFirstNames.status"></td>
456        <td class="help"><span id="allFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
457      </tr>
458      <tr>
459        <td class="prompt">Gender</td>
460        <td class="input" id="new.gender"></td>
461        <td class="status"></td>
462        <td class="help"></td>
463      </tr>
464      <tr>
465        <td class="prompt">Date of birth</td>
466        <td class="input" id="new.dateOfBirth"></td>
467        <td class="status"></td>
468        <td class="help"></td>
469      </tr>
470      </table>
471    </td>
472  </tr>
473  </table>
474  </div>
475 
476  <!-- 2b. Existing patient -->
477  <div id="existingPatientSection" style="display: none;">
478  <p>
479  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
480  <tr>
481    <td rowspan="2" class="stepno">2</td>
482    <td class="steptitle">Existing patient: Verify names</td>
483  </tr>
484  <tr>
485    <td class="stepfields">
486      <table border="0" cellspacing="0" cellpadding="0" width="100%">
487      <tr>
488        <td class="prompt">Patient code</td>
489        <td class="input" id="existing.patientCode"></td>
490        <td class="status"></td>
491        <td class="help"></td>
492      </tr>
493      <tr>
494        <td class="prompt">Family name</td>
495        <td class="input" id="existing.familyName"></td>
496        <td class="status"></td>
497        <td class="help"></td>
498      </tr>
499      <tr>
500        <td class="prompt">All first names</td>
501        <td class="input" id="existing.allFirstNames"></td>
502        <td class="status"></td>
503        <td class="help"></td>
504      </tr>
505      <tr>
506        <td class="prompt">Gender</td>
507        <td class="input" id="existing.gender"></td>
508        <td class="status"></td>
509        <td class="help"></td>
510      </tr>
511      <tr>
512        <td class="prompt">Date of birth</td>
513        <td class="input" id="existing.dateOfBirth"></td>
514        <td class="status"></td>
515        <td class="help"></td>
516      </tr>
517      </table>
518    </td>
519  </tr>
520  </table>
521  </div>
522
523
524  <!-- 3. New case registration -->
525  <div id="newCaseSection" style="display: none;">
526  <p>
527  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
528  <tr>
529    <td rowspan="2" class="stepno">3</td>
530    <td class="steptitle">New case: Enter information</td>
531  </tr>
532  <tr>
533    <td class="stepfields">
534      <table border="0" cellspacing="0" cellpadding="0" width="100%">
535      <tr>
536        <td class="prompt">Laterality</td>
537        <td class="input">
538          <input type="radio" name="laterality" value="LEFT">LEFT
539          <input type="radio" name="laterality" value="RIGHT">RIGHT
540        </td>
541        <td class="status"></td>
542        <td class="help"></td>
543      </tr>
544      <tr valign="top">
545        <td class="prompt">Specimen tubes</td>
546        <td class="input" id="specimenTubes">not found</td>
547        <td class="status"></td>
548        <td class="help">The specimen tube(s) associated with this case.</td>
549      </tr>
550       
551      <tr id="reasonIfNoSpecimenSection" valign="top">
552        <td class="prompt">Reason if no specimen</td>
553        <td class="input"><textarea rows="3" cols="30" name="reasonIfNoSpecimen" value=""></textarea></td>
554        <td class="status"></td>
555        <td class="help">Comment why there was no specimen tubes in the delivery.</td>
556      </tr>
557      </table>
558    </td>
559  </tr>
560  </table>
561  </div>
562
563  <div class="error" id="errorMessage" style="display: none; width: 800px; margin-left: 20px; margin-bottom: 0px;"></div>
564
565  <table style="margin-left: 20px; margin-top: 10px;">
566    <tr><td><base:button id="gonext" title="Next" image="gonext.gif" onclick="goNext()"/></td></tr>
567    <tr><td><base:button id="gocreate" title="Create" image="gonext.gif" onclick="goCreate()" style="display: none;"/></td></tr>
568    <tr><td><base:button id="gorestart" title="Restart" image="goback.gif" onclick="goRestart()" style="display: none;"/></td></tr>
569  </table>
570  </form>
571
572  <pre>
573  <div id="debug"></div>
574  </pre>
575 
576</base:body>
577</base:page>
578<%
579}
580finally
581{
582  if (dc != null) dc.close();
583}
584%>
Note: See TracBrowser for help on using the repository browser.