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

Last change on this file since 1333 was 1333, checked in by Nicklas Nordborg, 12 years ago

Fixes #302: Update functionality in the Personal information registration

The create and update paths have been made more similar to reduce the number of special cases that the code needs to handle. Basically, as much info as we can is extracted from the case (if it exists) and specimen tubes in step 1. This information is used in step 3 and the user can accept it as it is, add missing information or change the current information.

There are some exotic cases that are still problematic. For example, it is not always possible to relate PAD to a case without specimen tubes if there is more than one case for a patient.

Also updated the index page to make it look better.

File size: 31.4 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 debug = false;
29var currentStep = 1;
30var pnrIsValid = false;
31var pnrIsAcceptable = false;
32var caseIsValid = false;
33var lateralityIsValid = false;
34var samplingDateIsValid = false;
35var rnaLaterDateIsValid = false;
36
37var patientInfo = null;
38var caseInfo = null;
39
40function init()
41{
42  var frm = document.forms['reggie'];
43  frm.caseName.focus();
44}
45
46function step1IsValid()
47{
48  return pnrIsValid && caseIsValid;
49}
50
51function step1IsAcceptable()
52{
53  return pnrIsAcceptable && caseIsValid;
54}
55
56function step2IsValid()
57{
58  var formOk = true;
59  var frm = document.forms['reggie'];
60
61  // New patient only
62  if (!patientInfo.id)
63  {
64    // Validate 'New patient' form
65    if (frm.allFirstNames.value == '')
66    {
67      setInputStatus('allFirstNames', 'Missing', 'invalid');
68      frm.allFirstNames.focus();
69      formOk = false;
70    }
71    else
72    {
73      setInputStatus('allFirstNames', '', 'valid');
74    }
75   
76    if (frm.familyName.value == '')
77    {
78      setInputStatus('familyName', 'Missing', 'invalid');
79      frm.familyName.focus();
80      formOk = false;
81    }
82    else
83    {
84      setInputStatus('familyName', '', 'valid');
85    }
86
87    if (frm.patientCode.value == '')
88    {
89      setInputStatus('patientCode', 'Missing', 'invalid');
90      frm.patientCode.focus();
91      formOk = false;
92    }
93    else
94    {
95      setInputStatus('patientCode', '', 'valid');
96    }
97  }
98  return formOk;
99}
100
101function step3IsValid()
102{
103  var isValid = lateralityIsValid;
104  if (caseInfo.specimen && caseInfo.specimen.length > 0)
105  {
106    isValid = isValid && samplingDateIsValid && rnaLaterDateIsValid;
107  }
108  return isValid;
109}
110
111function goNext(manual)
112{
113  setInnerHTML('gonext.message', '');
114  if (currentStep == 1)
115  {
116    if (step1IsValid())
117    {
118      gotoStep2();
119    }
120    else if (step1IsAcceptable())
121    {
122      if (manual)
123      {
124        gotoStep2();
125      }
126      else
127      {
128        setInnerHTML('gonext.message', 'Personal number is non-standard. Click \'Next\' to continue registration.');
129      }
130    }
131  }
132  else if (currentStep == 2)
133  {
134    if (step2IsValid()) gotoStep3();
135  }
136}
137
138function caseNameOnChange()
139{
140  var frm = document.forms['reggie'];
141  var caseName = frm.caseName.value;
142  if (caseName == '')
143  {
144    setInputStatus('case', 'Missing', 'invalid');
145    return;
146  }
147  setInputStatus('case', '', 'valid');
148  caseIsValid = true;
149 
150  getCaseInfo();
151}
152
153function personalNumberOnChange()
154{
155  var frm = document.forms['reggie'];
156  var pnr = frm.personalNumber.value;
157  pnrIsValid = false;
158  pnrIsAcceptable = true;
159 
160  if (pnr.length < 12)
161  {
162    setInputStatus('pnr', 'Too short', 'warning');
163    return;
164  }
165
166  if (!pnr.match(/^\d+$/))
167  {
168    setInputStatus('pnr', 'Non-standard personal number', 'warning');
169    return;
170  }
171 
172  var isValidDate = Dates.isDate(pnr.substring(0, 8), 'yyyyMMdd');
173  if (!isValidDate)
174  {
175    var dayInMonth = parseInt(pnr.substring(6, 8));
176    if (dayInMonth > 60)
177    {
178      // 'Samordningsnummer' has day-in-month + 60; check this
179      dayInMonth -= 60;
180      var tmpPnr = pnr.substring(0, 6);
181      if (dayInMonth < 10) tmpPnr += '0';
182      tmpPnr += dayInMonth;
183      isValidDate = Dates.isDate(tmpPnr, 'yyyyMMdd');
184    }
185  }
186  if (!isValidDate)
187  {
188    setInputStatus('pnr', 'Not a valid date', 'warning');
189    return;
190  }
191 
192  var sum = 0;
193  var factor = 2;
194  //var x = '';
195  for (var i = 2; i < 11; i++)
196  {
197    var digit = parseInt(pnr.substr(i, 1));
198    var tmp = factor * digit;
199    //x += '(' + factor + '*' + digit+')';
200    sum += tmp >= 10 ? tmp - 9: tmp;
201    factor = factor == 2 ? 1 : 2;
202  }
203  //alert(x + "; sum="+sum);
204 
205  var control = 10 - (sum % 10);
206  if (control == 10) control = 0;
207  if (control != parseInt(pnr.substr(11, 1)))
208  {
209    setInputStatus('pnr', 'Invalid control digit', 'warning');
210    return;
211  }
212 
213  setInputStatus('pnr', '', 'valid');
214  pnrIsValid = true;
215}
216
217function lateralityOnChange()
218{
219  lateralityIsValid = false;
220  var updateMode = caseInfo.id;
221 
222  // Check selected laterality against specimen tubes
223  var frm = document.forms['reggie'];
224  var selectedLaterality = Forms.getCheckedRadio(frm.laterality);
225 
226  // No laterality/case selected
227  if (selectedLaterality == null)
228  {
229    setInputStatus('laterality', 'Not selected', 'invalid');
230    return;
231  }
232 
233  var numCases = patientInfo.cases ? patientInfo.cases.length : 0;
234  setInputStatus('laterality', updateMode && numCases > 1 ? 'NOTE! Some alternatives may be missing if there is another case for the patient.' : '', 'valid');
235  lateralityIsValid = true;
236 
237  var laterality = selectedLaterality.value;
238  if (laterality.match(/\d+/))
239  {
240    // It is the ID of an existing case
241    for (var i = 0; i < patientInfo.cases.length; i++)
242    {
243      var cse = patientInfo.cases[i];
244      if (cse.id == laterality)
245      {
246        laterality = cse.laterality;
247        break;
248      }
249    }
250  }
251  else if (laterality == '') 
252  {
253    laterality = null;
254  }
255   
256  // No specimen tubes?
257  if (!caseInfo.specimen || caseInfo.specimen.length == 0) return;
258 
259  for (var i = 0; i < caseInfo.specimen.length; i++)
260  {
261    var specimen = caseInfo.specimen[i];
262    if (specimen.laterality != laterality)
263    {
264      if (specimen.laterality == null || updateMode)
265      {
266        setInputStatus('laterality', 'Specimen tubes are updated to: ' + laterality, 'valid')
267      }
268      else
269      {
270        setInputStatus('laterality', 'Not same laterality as specimen tubes', 'warning');
271      }
272      return;
273    }
274  }
275 
276}
277
278function padOnChange()
279{
280  var frm = document.forms['reggie'];
281  var PAD = frm.pad.value;
282  if (PAD == '')
283  {
284    setInputStatus('pad', 'Missing', 'warning');
285    return;
286  }
287  frm.pad.value = PAD.replace(/\+/, '-');
288  setInputStatus('pad', '', 'valid');
289}
290
291function samplingDateTimeOnChange()
292{
293  var frm = document.forms['reggie'];
294  samplingDateIsValid = false;
295  setInputStatus('samplingDate', '', '');
296 
297  var samplingDate = frm.samplingDate.value;
298  var samplingTime = frm.samplingTime.value;
299 
300  if (samplingDate != '' || samplingTime != '')
301  {
302    if (!Dates.isDate(samplingDate, 'yyyy-MM-dd'))
303    {
304      setInputStatus('samplingDate', 'Not a valid date', 'invalid');
305      return;
306    }
307    if (frm.rnaLaterDate.value == '') frm.rnaLaterDate.value = samplingDate;
308   
309    if (!Dates.isDate(samplingDate + ' ' + samplingTime, 'yyyy-MM-dd HH:mm'))
310    {
311      if (samplingDate != '') setInputStatus('samplingDate', 'Not a valid time', 'invalid');
312      return;
313    }
314    setInputStatus('samplingDate', '', 'valid');
315  }
316  samplingDateIsValid = true;
317}
318
319function rnaLaterDateTimeOnChange()
320{
321  var frm = document.forms['reggie'];
322  rnaLaterDateIsValid = false;
323  setInputStatus('rnaLaterDate', '', '');
324 
325  var rnaLaterDate = frm.rnaLaterDate.value;
326  var rnaLaterTime = frm.rnaLaterTime.value;
327  var rnaLaterTimestamp;
328 
329  if (rnaLaterDate != '' || rnaLaterTime != '')
330  {
331    if (!Dates.isDate(rnaLaterDate, 'yyyy-MM-dd'))
332    {
333      setInputStatus('rnaLaterDate', 'Not a valid date', 'invalid');
334      return;
335    }
336    rnaLaterTimestamp = Dates.parseString(rnaLaterDate + ' ' + rnaLaterTime, 'yyyy-MM-dd HH:mm');
337    if (rnaLaterTimestamp == null)
338    {
339      if (rnaLaterDate != '') setInputStatus('rnaLaterDate', 'Not a valid time', 'invalid');
340      return;
341    }
342    setInputStatus('rnaLaterDate', '', 'valid');
343  }
344 
345  rnaLaterDateIsValid = true;
346
347  if (samplingDateIsValid && rnaLaterTimestamp)
348  {
349    var samplingTimestamp = Dates.parseString(frm.samplingDate.value + ' ' + frm.samplingTime.value, 'yyyy-MM-dd HH:mm');
350    if (samplingTimestamp && rnaLaterTimestamp.getDate() != samplingTimestamp.getDate())
351    {
352      setInputStatus('rnaLaterDate', 'Sampling and RNA later dates are different', 'warning');
353    }
354  }
355}
356
357
358function goNextOnTab(event)
359{
360  if (event.keyCode == 9) setTimeout('goNext()', 200);
361  return true;
362}
363
364function goNextOnTabOrEnter(event)
365{
366  if (event.keyCode == 9 || event.keyCode == 13) setTimeout('goNext()', 200);
367  return true;
368}
369
370function focusOnEnter(event, inputField)
371{
372  if (event.keyCode == 13) setTimeout("document.forms['reggie']."+inputField+".focus()", 200);
373  return true;
374}
375
376function getCaseInfo()
377{
378  // Check entered case and pnr with AJAX
379  var frm = document.forms['reggie'];
380  var caseName = frm.caseName.value;
381  var request = Ajax.getXmlHttpRequest();
382  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetCaseInfo';
383  url += '&caseName=' + caseName;
384  request.open("GET", url, false);
385  request.send(null);
386 
387  if (debug) Main.debug(request.responseText);
388  var response = JSON.parse(request.responseText);
389  if (response.status != 'ok')
390  {
391    setFatalError(response.message);
392    return false;
393  }
394 
395  // Get biosource information from the AJAX response
396  caseInfo = response.caseInfo;
397 
398  if (caseInfo && caseInfo.patient)
399  {
400    frm.personalNumber.value = caseInfo.patient.personalNumber;
401    gotoStep2();
402  }
403 
404}
405
406function gotoStep2()
407{
408  // Check entered case and pnr with AJAX
409  var frm = document.forms['reggie'];
410  frm.caseName.disabled = true;
411  frm.personalNumber.disabled = true;
412  currentStep = 2;
413 
414  var pnr = frm.personalNumber.value;
415  var request = Ajax.getXmlHttpRequest();
416  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetPatientInfo';
417  url += '&personalNumber=' + pnr;
418  url += '&pnrIsValid=' + pnrIsValid;
419  request.open("GET", url, false);
420  request.send(null);
421 
422  if (debug) Main.debug(request.responseText);
423 
424  var response = JSON.parse(request.responseText);
425  if (response.status != 'ok')
426  {
427    setFatalError(response.message);
428    return false;
429  }
430 
431  // Get patient information from the AJAX response
432  patientInfo = response.patientInfo;
433
434  Main.show('gocancel');
435 
436  if (!patientInfo.id)
437  {
438    Main.show('newPatientSection');
439    frm.patientCode.value=patientInfo.name;
440    setInnerHTML('new.dateOfBirth', patientInfo.dateOfBirth ? patientInfo.dateOfBirth : "---");
441    setInnerHTML('new.gender', patientInfo.gender ? patientInfo.gender : "---");
442    frm.familyName.focus();
443    if (!pnrIsValid)
444    {
445      setInputStatus('gender', 'Gender and DateOfBirth can\'t be automatically generated for non-standard Personal number', 'warning');
446    }
447  }
448  else
449  {
450    Main.show('existingPatientSection');
451    setInnerHTML('existing.patientCode', patientInfo.name);
452    setInnerHTML('existing.familyName', patientInfo.familyName);
453    setInnerHTML('existing.allFirstNames', patientInfo.allFirstNames);
454    if (patientInfo.dateOfBirth) setInnerHTML('existing.dateOfBirth', patientInfo.dateOfBirth);
455    if (patientInfo.gender) setInnerHTML('existing.gender', patientInfo.gender);
456    gotoStep3();
457  }
458}
459
460function gotoStep3()
461{
462  // Check entered case and pnr with AJAX
463  var frm = document.forms['reggie'];
464 
465  if (!patientInfo.id)
466  {
467    frm.patientCode.disabled = true;
468    frm.familyName.disabled = true;
469    frm.allFirstNames.disabled = true;
470    patientInfo.familyName = frm.familyName.value;
471    patientInfo.allFirstNames = frm.allFirstNames.value;
472  }
473  currentStep = 3;
474 
475  var updateMode = caseInfo.id;
476 
477  // Generate list of specimen tubes
478  var hasLeftSpecimen = false;
479  var hasRightSpecimen = false;
480  var hasUnknownSpecimen = false;
481  var thisCaseLaterality = caseInfo.laterality;
482  var hasSpecimen = caseInfo.specimen && caseInfo.specimen.length > 0;
483  var thisCasePAD = null;
484  var hasPAD = false;
485  var thisCaseSamplingDate = null;
486  var thisCaseRNALaterDate = null;
487 
488  if (hasSpecimen)
489  {
490    var specimenTubes = '';
491    Main.hide('reasonIfNoSpecimenSection');
492    for (var i = 0; i < caseInfo.specimen.length; i++)
493    {
494      var specimen = caseInfo.specimen[i];
495      specimenTubes += specimen.name;
496      if (specimen.pad && !hasPAD) 
497      {
498        hasPAD = true;
499        thisCasePAD = specimen.pad;
500      }
501      if (specimen.samplingDate && !thisCaseSamplingDate) 
502      {
503        thisCaseSamplingDate = specimen.samplingDate;
504      }
505      if (specimen.rnaLaterDate && !thisCaseRNALaterDate) 
506      {
507        thisCaseRNALaterDate = specimen.rnaLaterDate;
508      }
509      if (specimen.laterality) 
510      {
511        specimenTubes += ' ('+specimen.laterality + ')';
512        Forms.checkRadio(frm.laterality, specimen.laterality);
513        if (specimen.laterality == 'LEFT') hasLeftSpecimen = true;
514        if (specimen.laterality == 'RIGHT') hasRightSpecimen = true;
515        if (!thisCaseLaterality) thisCaseLaterality = specimen.laterality;
516      }
517      else
518      {
519        hasUnknownSpecimen = true;
520        specimenTubes += ' (<i>unknown laterality</i>)';
521      }
522      specimenTubes += '<br>';
523    }
524    setInnerHTML('specimenTubes', specimenTubes);
525   
526    // Check that all specimen tubes have the same laterality
527    var numLateralities = 0;
528    if (hasLeftSpecimen) numLateralities++;
529    if (hasRightSpecimen) numLateralities++;
530    if (hasUnknownSpecimen) numLateralities++;
531    if (numLateralities > 1)
532    {
533      setInputStatus('specimenTubes', 'Specimen tubes with different laterality', 'warning');
534      thisCaseLaterality = null;
535    }
536
537    // Show and populate 'Sampling date' and 'RNA Later date' fields
538    Main.show('samplingDateSection');
539    Main.show('rnaLaterDateSection');
540    if (thisCaseSamplingDate != null)
541    {
542      frm.samplingDate.value = thisCaseSamplingDate.substring(0, 10);
543      frm.samplingTime.value = thisCaseSamplingDate.substring(11, 16);
544      samplingDateTimeOnChange();
545    }
546    if (thisCaseRNALaterDate != null)
547    {
548      frm.rnaLaterDate.value = thisCaseRNALaterDate.substring(0, 10);
549      frm.rnaLaterTime.value = thisCaseRNALaterDate.substring(11, 16);
550      rnaLaterDateTimeOnChange();
551    }
552  }
553  else
554  {
555    // No specimen tubes... if there is only one PAD on the case... use that
556    if (caseInfo.pad && caseInfo.pad.length == 1)
557    {
558      hasPAD = true;
559      thisCasePAD = caseInfo.pad[0];
560    }
561   
562    // Hide 'Sampling date' and 'RNA Later date' fields
563    Main.hide('samplingDateSection');
564    Main.hide('rnaLaterDateSection');
565  }
566
567  frm.pad.value = thisCasePAD;
568  caseInfo.oldPad = thisCasePAD;
569  //Main.showHide('padSection', !hasPAD || updateMode);
570 
571 
572 
573  if (updateMode && !hasSpecimen)
574  {
575    // Try to find 'reasonIfNoSpecimen' annotation on the case
576    for (var i = 0; i < caseInfo.reasonIfNoSpecimen.length; i++)
577    {
578      var rns = caseInfo.reasonIfNoSpecimen[i];
579      if (rns.indexOf('['+caseInfo.originalName+']') == 0)
580      {
581        caseInfo.oldReasonIfNoSpecimen = rns;
582        frm.reasonIfNoSpecimen.value = rns.substring(rns.indexOf(']')+2);
583        i = 999;
584      }
585    }
586  }
587 
588  Main.show('caseSection');
589 
590  // Existing cases for this patient
591  var hasLeftCase = false;
592  var hasRightCase = false;
593  var hasUnknownCase = false;
594  if (patientInfo.cases && patientInfo.cases.length > 0)
595  {
596    var cases = '';
597    for (var i = 0; i < patientInfo.cases.length; i++)
598    {
599      var cc = patientInfo.cases[i];
600      if (cc.laterality == 'LEFT') 
601      {
602        if (hasLeftCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=LEFT', 'warning');
603        hasLeftCase = true;
604      }
605      else if (cc.laterality == 'RIGHT') 
606      {
607        if (hasRightCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=RIGHT', 'warning');
608        hasRightCase = true;
609      }
610      else
611      {
612        hasUnknownCase = true; 
613      }
614      if (!updateMode || cc.id == caseInfo.id)
615      {
616        cases += '<input type="radio" name="laterality" value="' + cc.id + '"';
617        if (cc.laterality == thisCaseLaterality) cases += ' checked';
618        cases += ' onclick="lateralityOnChange()">';
619        if (cc.laterality)
620        {
621          cases += cc.laterality;
622        }
623        else
624        {
625          cases += '<i>unknown laterality</i>';
626        }
627        if (!updateMode)
628        {
629          cases += ' [merge with ' + cc.name + ']';
630        }
631        cases += '<br>';
632      }
633    }
634   
635    if (patientInfo.cases.length == 1 || updateMode)
636    {
637      if (!hasLeftCase)
638      {
639        cases += '<input type="radio" name="laterality" value="LEFT" ';
640        if (thisCaseLaterality == 'LEFT') cases += ' checked';
641        cases += ' onclick="lateralityOnChange()">LEFT';
642        if (!updateMode) cases += ' [<i>new case</i>]';
643        cases += '<br>';
644      }
645      if (!hasRightCase)
646      {
647        cases += '<input type="radio" name="laterality" value="RIGHT"';
648        if (thisCaseLaterality == 'RIGHT') cases += ' checked';
649        cases += ' onclick="lateralityOnChange()">RIGHT';
650        if (!updateMode) cases += ' [<i>new case</i>]';
651        cases += '<br>';
652      }
653      if (!updateMode && !hasLeftCase && !hasRightCase)
654      {
655        cases += '<input type="radio" name="laterality" value=""';
656        if (thisCaseLaterality == null) cases += ' checked';
657        cases += ' onclick="lateralityOnChange()"><i>unknown laterality</i> [<i>new case</i>]<br>';
658      }
659    }
660   
661    if (updateMode)
662    {
663      if (caseInfo.merged)
664      {
665        setInnerHTML('step3.title', 'Update case \''+caseInfo.originalName+'\' (which is merged with case \'' + caseInfo.name + '\')');
666      }
667      else
668      {
669        setInnerHTML('step3.title', 'Update case \''+caseInfo.name+'\'');
670      }
671     
672    }
673    else if (patientInfo.cases.length == 2)
674    {
675      setInnerHTML('step3.title', 'Merge with existing case'); 
676    }
677    else if (patientInfo.cases.length > 0)
678    {
679      setInnerHTML('step3.title', 'Create new case or merge with existing case');
680    }
681   
682    setInnerHTML('laterality.input', cases);
683  }
684  lateralityOnChange();
685
686  Main.hide('gonext');
687  if (updateMode)
688  {
689    Main.show('goupdate');
690  }
691  else
692  {
693    Main.show('gocreate');
694  }
695 
696  if (lateralityIsValid) frm.pad.focus();
697}
698
699function goCreate()
700{
701  if (!step3IsValid()) return;
702 
703  Main.hide('gocreate');
704  Main.hide('gocancel');
705  Main.hide('goupdate');
706  var frm = document.forms['reggie'];
707
708  caseInfo.laterality = Forms.getCheckedRadio(frm.laterality).value;
709  caseInfo.reasonIfNoSpecimen = frm.reasonIfNoSpecimen.value;
710  caseInfo.pad = frm.pad.value;
711  caseInfo.samplingDate = Main.trimString(frm.samplingDate.value + ' ' + frm.samplingTime.value);
712  caseInfo.rnaLaterDate = Main.trimString(frm.rnaLaterDate.value + ' ' + frm.rnaLaterTime.value);
713
714  for (var i = 0; i < frm.laterality.length; i++)
715  {
716    frm.laterality[i].disabled = true;
717  }
718  frm.reasonIfNoSpecimen.disabled = true;
719  frm.pad.disabled = true;
720  frm.samplingDate.disabled = true;
721  frm.samplingTime.disabled = true;
722  frm.rnaLaterDate.disabled = true;
723  frm.rnaLaterTime.disabled = true;
724
725  var updateMode = caseInfo.id;
726  var submitInfo = new Object();
727  submitInfo.patientInfo = patientInfo;
728  submitInfo.caseInfo = caseInfo;
729
730  if (debug) Main.debug(JSON.stringify(submitInfo));
731 
732  var request = Ajax.getXmlHttpRequest();
733  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=';
734  url += updateMode ? 'UpdateCase' : 'CreateCase';
735  request.open("POST", url, false);
736  request.setRequestHeader("Content-Type", "application/json");
737  request.send(JSON.stringify(submitInfo));
738
739  if (debug) Main.debug(request.responseText);
740 
741  var response = JSON.parse(request.responseText);
742  if (response.status != 'ok')
743  {
744    setFatalError(response.message);
745    return false;
746  }
747 
748  var msg = '<ul>';
749  for (var i = 0; i < response.messages.length; i++)
750  {
751    msg += '<li>' + response.messages[i];
752  }
753  msg += '</ul>';
754  setInnerHTML('done', msg);
755  Main.show('done');
756  Main.show('gorestart');
757
758}
759
760
761function setInnerHTML(id, html)
762{
763  var tag = document.getElementById(id);
764  if (!tag) alert('No tag with id='+id);
765  tag.innerHTML = html;
766}
767
768function setInputStatus(prefix, message, clazz)
769{
770  var tag = document.getElementById(prefix + '.status');
771  tag.className = 'status ' + clazz;
772 
773  setInnerHTML(prefix + '.message', message);
774  if (message)
775  {
776    Main.showInline(prefix + '.message');
777  }
778  else
779  {
780    Main.hide(prefix + '.message');
781  }
782}
783
784function setFatalError(message)
785{
786  setInnerHTML('errorMessage', message);
787  Main.show('errorMessage');
788  Main.hide('gonext');
789  Main.hide('gocancel');
790  Main.show('gorestart');
791  var frm = document.forms['reggie'];
792  for (var i = 0; i < frm.elements.length; i++)
793  {
794    frm.elements[i].disabled = true; 
795  }
796
797}
798
799function goRestart(force)
800{
801  if (!force && !confirm('Cancel this registration?')) return;
802  location.href = location.href;
803}
804</script>
805<style>
806
807.stepform
808{
809  margin-left: 20px;
810  border: 1px solid #999999;
811  width: 800px;
812  table-layout: fixed;
813}
814
815.stepno
816{
817  width: 20px;
818  font-size: 20px;
819  font-weight: bold;
820  color: #E0E0E0;
821  background: #555577;
822  vertical-align: top;
823  text-align: center;
824}
825
826.steptitle
827{
828  width: 780px;
829  color: #333377;
830  background: #E0E0E0;
831  font-weight: bold;
832  padding: 1px 4px 1px 4px;
833  border-bottom: 1px solid #999999;
834}
835
836.nextstep
837{
838  width: 780px;
839  color: #333377;
840  background: #E0E0E0;
841  font-weight: bold;
842  padding: 1px 4px 1px 4px;
843  border-top: 1px solid #999999;
844}
845
846.stepfields
847{
848  width: 780px;
849}
850
851.stepfields .prompt
852{
853  width: 150px;
854  font-weight: bold;
855  padding: 1px 2px 1px 2px;
856}
857
858.stepfields .subprompt
859{
860  width: 150px;
861  text-align: right;
862  padding: 1px 2px 1px 2px;
863  white-space: nowrap;
864}
865
866.stepfields .input
867{
868  width: 250px;
869  padding: 1px 2px 1px 2px;
870}
871
872.stepfields .status
873{
874  width: 30px;
875  padding: 1px 2px 1px 2px;
876}
877
878.stepfields .help
879{
880  background: #e0e0e0;
881  width: 350px;
882  font-style: italic;
883  padding: 1px 2px 1px 2px;
884}
885
886.stepfields .message, .navigation .message
887{
888  color: #cc0000;
889  font-weight: bold;
890  padding-right: 6px;
891}
892
893.status.invalid:before
894{
895  content: url('../../images/error.gif');
896}
897.status.warning:before
898{
899  content: url('../../images/warning.gif');
900}
901.status.valid:before
902{
903  content: url('../../images/ok.gif');
904}
905.success ul
906{
907  list-style-image: url('../../images/ok.gif');
908}
909</style>
910</base:head>
911<base:body onload="init()">
912
913  <p:path style="margin-top: 20px; margin-bottom: 10px;">
914    <p:pathelement title="Reggie" href="<%="index.jsp?ID="+ID%>" />
915    <p:pathelement title="Personal information registration" />
916  </p:path>
917
918  <%
919  if (sc.getActiveProjectId() == 0)
920  {
921    %>
922    <base:note type="warning" style="width: 800px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
923      No project has been selected. You may proceed with the registration but
924      created items will not be shared.
925    </base:note>
926    <%
927  }
928  %>
929
930  <form name="reggie" onsubmit="return false;">
931 
932  <!-- 1. Case + Personal number -->
933  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
934  <tr>
935    <td rowspan="3" class="stepno">1</td>
936    <td class="steptitle">Enter Case Name and Personal Number</td>
937  </tr>
938  <tr>
939    <td class="stepfields">
940      <table border="0" cellspacing="0" cellpadding="0" width="100%">
941      <tr valign="top">
942        <td class="prompt">Case name</td>
943        <td class="input"><input type="text" name="caseName" 
944          size="18" maxlength="12" onblur="caseNameOnChange()" onkeypress="focusOnEnter(event, 'personalNumber')"></td>
945        <td class="status" id="case.status"></td>
946        <td class="help"><span id="case.message" class="message" style="display: none;"></span>The case (barcode) associated with this patient.</td>
947      </tr>
948      <tr>
949        <td class="prompt">Personal number</td>
950        <td class="input"><input type="text" name="personalNumber" 
951          size="18" maxlength="12" onkeyup="personalNumberOnChange()" onkeypress="goNextOnTabOrEnter(event)"></td>
952        <td class="status" id="pnr.status"></td>
953        <td class="help"><span id="pnr.message" class="message" style="display: none;"></span>(YYYYMMDDZZZZ)</td>
954      </tr>
955      </table>
956    </td>
957  </tr>
958  </table>
959
960  <!-- 2. New patient registration -->
961  <div id="newPatientSection" style="display: none;">
962  <p>
963  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
964  <tr>
965    <td rowspan="2" class="stepno">2</td>
966    <td class="steptitle">New patient: Enter all names</td>
967  </tr>
968  <tr>
969    <td class="stepfields">
970      <table border="0" cellspacing="0" cellpadding="0" width="100%">
971      <tr>
972        <td class="prompt">Patient code</td>
973        <td class="input"><input type="text" name="patientCode" 
974          value="" size="18" maxlength="12" 
975          onkeypress="focusOnEnter(event, 'familyName')"></td>
976        <td class="status" id="patientCode.status"></td>
977        <td class="help"><span id="patientCode.message" class="message" style="display: none;"></span></td>
978      </tr>
979      <tr valign="top">
980        <td class="prompt">Family name</td>
981        <td class="input"><input type="text" name="familyName" 
982          value="" size="35" maxlength="255"
983          onkeypress="focusOnEnter(event, 'allFirstNames')"></td>
984        <td class="status" id="familyName.status"></td>
985        <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>
986      </tr>
987      <tr valign="top">
988        <td class="prompt">All first names</td>
989        <td class="input"><input type="text" name="allFirstNames" 
990          size="35" maxlength="255" onkeypress="goNextOnTabOrEnter(event)"></td>
991        <td class="status" id="allFirstNames.status"></td>
992        <td class="help"><span id="allFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
993      </tr>
994      <tr>
995        <td class="prompt">Gender</td>
996        <td class="input" id="new.gender"></td>
997        <td class="status" id="gender.status" rowspan="2"></td>
998        <td class="help" rowspan="2"><span id="gender.message" class="message" style="display:none;"></span></td>
999      </tr>
1000      <tr>
1001        <td class="prompt">Date of birth</td>
1002        <td class="input" id="new.dateOfBirth"></td>
1003      </tr>
1004      </table>
1005    </td>
1006  </tr>
1007  </table>
1008  </div>
1009 
1010  <!-- 2b. Existing patient -->
1011  <div id="existingPatientSection" style="display: none;">
1012  <p>
1013  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1014  <tr>
1015    <td rowspan="2" class="stepno">2</td>
1016    <td class="steptitle">Existing patient: Verify names</td>
1017  </tr>
1018  <tr>
1019    <td class="stepfields">
1020      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1021      <tr>
1022        <td class="prompt">Patient code</td>
1023        <td class="input" id="existing.patientCode"></td>
1024        <td class="status"></td>
1025        <td class="help"></td>
1026      </tr>
1027      <tr>
1028        <td class="prompt">Family name</td>
1029        <td class="input" id="existing.familyName"></td>
1030        <td class="status"></td>
1031        <td class="help"></td>
1032      </tr>
1033      <tr>
1034        <td class="prompt">All first names</td>
1035        <td class="input" id="existing.allFirstNames"></td>
1036        <td class="status"></td>
1037        <td class="help"></td>
1038      </tr>
1039      <tr>
1040        <td class="prompt">Gender</td>
1041        <td class="input" id="existing.gender"></td>
1042        <td class="status"></td>
1043        <td class="help"></td>
1044      </tr>
1045      <tr>
1046        <td class="prompt">Date of birth</td>
1047        <td class="input" id="existing.dateOfBirth"></td>
1048        <td class="status"></td>
1049        <td class="help"></td>
1050      </tr>
1051      </table>
1052    </td>
1053  </tr>
1054  </table>
1055  </div>
1056
1057
1058  <!-- 3. Case registration -->
1059  <div id="caseSection" style="display: none;">
1060  <p>
1061  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1062  <tr>
1063    <td rowspan="2" class="stepno">3</td>
1064    <td class="steptitle" id="step3.title">Create new case</td>
1065  </tr>
1066  <tr>
1067    <td class="stepfields">
1068      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1069      <tr valign="top">
1070        <td class="prompt" id="laterality.prompt">Laterality</td>
1071        <td class="input" id="laterality.input">
1072          <input type="radio" name="laterality" value="LEFT" onclick="lateralityOnChange()">LEFT<br>
1073          <input type="radio" name="laterality" value="RIGHT" onclick="lateralityOnChange()">RIGHT<br>
1074          <input type="radio" name="laterality" value="" checked onclick="lateralityOnChange()"><i>unknown</i>
1075        </td>
1076        <td class="status" id="laterality.status"></td>
1077        <td class="help"><span id="laterality.message" class="message" style="display: none;"></span></td>
1078      </tr>
1079      <tr id="padSection" valign="top">
1080        <td class="prompt">PAD</td>
1081        <td class="input"><input type="text" name="pad" 
1082          value="" size="18" maxlength="12" 
1083          onkeypress="focusOnEnter(event, caseInfo.specimen && caseInfo.specimen.length > 0 ? 'samplingDate' : 'reasonIfNoSpecimen')"
1084          onblur="padOnChange()"></td>
1085        <td class="status" id="pad.status"></td>
1086        <td class="help"><span id="pad.message" class="message" style="display: none;"></span></td>
1087      </tr>
1088      <tr valign="top">
1089        <td class="prompt">Specimen tubes</td>
1090        <td class="input" id="specimenTubes"><i>not found</i></td>
1091        <td class="status" id="specimenTubes.status"></td>
1092        <td class="help"><span id="specimenTubes.message" class="message" style="display: none;"></span>The specimen tube(s) associated with this case.</td>
1093      </tr>
1094      <tr id="samplingDateSection" valign="top">
1095        <td class="subprompt">Sampling date</td>
1096        <td class="input"><input type="text" name="samplingDate" value="" size="12" maxlength="10" 
1097            onkeypress="focusOnEnter(event, 'samplingTime')" onblur="samplingDateTimeOnChange()">
1098          Time <input type="text" name="samplingTime" value="" size="6" maxlength="5" 
1099            onkeypress="focusOnEnter(event, 'rnaLaterDate')" onblur="samplingDateTimeOnChange()"></td>
1100        <td class="status" id="samplingDate.status"></td>
1101        <td class="help"><span id="samplingDate.message" class="message" style="display: none;"></span>Date+time of surgical removal (YYYY-MM-DD, HH:MM)</td>
1102      </tr>
1103      <tr id="rnaLaterDateSection" valign="top">
1104        <td class="subprompt">RNA Later date</td>
1105        <td class="input"><input type="text" name="rnaLaterDate" value="" size="12" maxlength="10"
1106            onkeypress="focusOnEnter(event, 'rnaLaterTime')" onblur="rnaLaterDateTimeOnChange()">
1107          Time <input type="text" name="rnaLaterTime" value="" size="6" maxlength="5"
1108            onblur="rnaLaterDateTimeOnChange()"></td>
1109        <td class="status" id="rnaLaterDate.status"></td>
1110        <td class="help"><span id="rnaLaterDate.message" class="message" style="display: none;"></span>Date+time of pathology handling (YYYY-MM-DD, HH:MM)</td>
1111      </tr>
1112      <tr id="reasonIfNoSpecimenSection" valign="top">
1113        <td class="subprompt">Reason if no specimen</td>
1114        <td class="input"><textarea rows="3" cols="30" name="reasonIfNoSpecimen" value=""></textarea></td>
1115        <td class="status"></td>
1116        <td class="help">Comment why there was no specimen tubes in the delivery.</td>
1117      </tr>
1118      </table>
1119    </td>
1120  </tr>
1121  </table>
1122  </div>
1123
1124  <div class="error" id="errorMessage" style="display: none; width: 800px; margin-left: 20px; margin-bottom: 0px;"></div>
1125
1126  <div id="done" class="success" style="display: none; width: 800px; margin-left: 20px; margin-top: 20px;"></div>
1127
1128  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
1129  <tr>
1130    <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
1131    <td><base:button id="gonext" title="Next" image="gonext.gif" onclick="goNext(true)"/></td>
1132    <td><base:button id="gocreate" title="Create" image="gonext.gif" onclick="goCreate()" style="display: none;"/></td>
1133    <td><base:button id="goupdate" title="Update" image="gonext.gif" onclick="goCreate()" style="display: none;"/></td>
1134    <td><base:button id="gorestart" title="Restart" image="goback.gif" onclick="goRestart(true)" style="display: none;"/></td>
1135    <td id="gonext.message" class="message"></td>
1136  </tr>
1137  </table>
1138  </form>
1139 
1140</base:body>
1141</base:page>
1142<%
1143}
1144finally
1145{
1146  if (dc != null) dc.close();
1147}
1148%>
Note: See TracBrowser for help on using the repository browser.