Changeset 1290


Ignore:
Timestamp:
Feb 21, 2011, 2:29:46 PM (13 years ago)
Author:
Nicklas Nordborg
Message:

References #291: Personal information registration

Should now handle the case with an existing patient properly. Depedning on the number of cases already registered the user may create a new case or merge with an existing case.

Display messages after the registration and added a button to restart the wizard for a second registration.

Location:
extensions/net.sf.basedb.reggie/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk/resources/persinfo.jsp

    r1289 r1290  
    5151  if (caseName == '')
    5252  {
    53     setInputStatus('case', 'Missing', false);
     53    setInputStatus('case', 'Missing', 'invalid');
    5454    return;
    5555  }
    56   setInputStatus('case', '', true);
     56  setInputStatus('case', '', 'valid');
    5757  caseIsValid = true;
    5858}
     
    6666  if (pnr.length < 12)
    6767  {
    68     setInputStatus('pnr', 'Too short', false);
     68    setInputStatus('pnr', 'Too short', 'invalid');
    6969    return;
    7070  }
     
    7272  if (!Dates.isDate(pnr.substring(0, 8), 'yyyyMMdd'))
    7373  {
    74     setInputStatus('pnr', 'Not a valid date', false);
     74    setInputStatus('pnr', 'Not a valid date', 'invalid');
    7575    return;
    7676  }
     
    9191  if (control != parseInt(pnr.substr(11, 1)))
    9292  {
    93     setInputStatus('pnr', 'Invalid control digit', false);
     93    setInputStatus('pnr', 'Invalid control digit', 'invalid');
    9494    return;
    9595  }
    9696 
    97   setInputStatus('pnr', '', true);
     97  setInputStatus('pnr', '', 'valid');
    9898  pnrIsValid = true;
    9999 
    100   if (caseIsValid) gotoStep2();
    101 }
    102 
    103 function allFirstNamesOnKeyPress(event)
     100  //if (caseIsValid) gotoStep2();
     101}
     102
     103function lateralityOnChange()
     104{
     105  // Check selected laterality against specimen tubes
     106  var frm = document.forms['reggie'];
     107  var selectedLaterality = Forms.getCheckedRadio(frm.laterality);
     108 
     109  // No laterality/case selected
     110  if (selectedLaterality == null) return;
     111 
     112  var laterality = selectedLaterality.value;
     113  if (laterality != 'LEFT' && laterality != 'RIGHT')
     114  {
     115    // It is the ID of an existing case
     116    for (var i = 0; i < patientInfo.cases.length; i++)
     117    {
     118      var cse = patientInfo.cases[i];
     119      if (cse.id == laterality)
     120      {
     121        laterality = cse.laterality;
     122        break;
     123      }
     124    }
     125  }
     126 
     127  if (!laterality) return;
     128 
     129  // No specimen tubes
     130  if (!caseInfo.specimen || caseInfo.specimen.length == 0) return;
     131 
     132  for (var i = 0; i < caseInfo.specimen.length; i++)
     133  {
     134    var specimen = caseInfo.specimen[i];
     135    if (specimen.laterality && specimen.laterality != laterality)
     136    {
     137      setInputStatus('laterality', 'Not same laterality as specimen tubes', 'warning');
     138      return;
     139    }
     140  }
     141  setInputStatus('laterality', '', 'valid');
     142}
     143
     144function goNextOnTab(event)
    104145{
    105146  if (event.keyCode == 9) setTimeout('goNext()', 200);
     
    153194    setInnerHTML('existing.dateOfBirth', patientInfo.dateOfBirth);
    154195    setInnerHTML('existing.gender', patientInfo.gender);
    155    
     196    gotoStep3();
    156197  }
    157198}
     
    161202  // Check entered case and pnr with AJAX
    162203  var frm = document.forms['reggie'];
    163   if (frm.patientCode)
     204
     205  if (!patientInfo.id)
    164206  {
    165207    var formOk = true;
     
    167209    if (frm.allFirstNames.value == '')
    168210    {
    169       setInputStatus('allFirstNames', 'Missing', false);
     211      setInputStatus('allFirstNames', 'Missing', 'invalid');
    170212      frm.allFirstNames.focus();
    171213      formOk = false;
     
    173215    else
    174216    {
    175       setInputStatus('allFirstNames', '', true);
     217      setInputStatus('allFirstNames', '', 'valid');
    176218    }
    177219   
    178220    if (frm.familyName.value == '')
    179221    {
    180       setInputStatus('familyName', 'Missing', false);
     222      setInputStatus('familyName', 'Missing', 'invalid');
    181223      frm.familyName.focus();
    182224      formOk = false;
     
    184226    else
    185227    {
    186       setInputStatus('familyName', '', true);
     228      setInputStatus('familyName', '', 'valid');
    187229    }
    188230
     
    190232    if (frm.patientCode.value == '')
    191233    {
    192       setInputStatus('patientCode', 'Missing', false);
     234      setInputStatus('patientCode', 'Missing', 'invalid');
    193235      frm.patientCode.focus();
    194236      formOk = false;
     
    196238    else
    197239    {
    198       setInputStatus('patientCode', '', true);
     240      setInputStatus('patientCode', '', 'valid');
    199241    }
    200242    if (!formOk) return;
     
    211253  }
    212254 
    213   if (!patientInfo.cases || patientInfo.cases.length == 0)
    214   {
    215     Main.show('newCaseSection'); 
    216   }
    217  
     255  // Generate list of specimen tubes
     256  var thisCaseLaterality;
    218257  if (caseInfo.specimen && caseInfo.specimen.length > 0)
    219258  {
     
    228267        specimenTubes += ' ('+specimen.laterality + ')';
    229268        Forms.checkRadio(frm.laterality, specimen.laterality);
     269       
     270        if (thisCaseLaterality && thisCaseLaterality != specimen.laterality)
     271        {
     272          setInputStatus('specimenTubes', 'Specimen tubes with different laterality', 'warning');
     273        }
     274        thisCaseLaterality = specimen.laterality;
    230275      }
    231276      specimenTubes += '<br>';
     
    233278    setInnerHTML('specimenTubes', specimenTubes);
    234279  }
    235  
     280
     281 
     282  Main.show('caseSection');
     283 
     284  // Existing cases for this patient
     285  var hasLeftCase = false;
     286  var hasRightCase = false;
     287  if (patientInfo.cases && patientInfo.cases.length > 0)
     288  {
     289    var cases = '';
     290    for (var i = 0; i < patientInfo.cases.length; i++)
     291    {
     292      var cc = patientInfo.cases[i];
     293      cases += '<input type="radio" name="laterality" value="' + cc.id + '"';
     294      if (cc.laterality == 'LEFT')
     295      {
     296        if (hasLeftCase) setInputStatus('laterality', 'Two cases with LEFT', 'warning');
     297        hasLeftCase = true;
     298      }
     299      if (cc.laterality == 'RIGHT')
     300      {
     301        if (hasRightCase) setInputStatus('laterality', 'Two cases with RIGHT', 'warning');
     302        hasRightCase = true;
     303      }
     304      if (cc.laterality == thisCaseLaterality) cases += ' checked';
     305      cases += ' onclick="lateralityOnChange()">';
     306      cases += cc.name + ' (' + cc.laterality + ')<br>';
     307    }
     308   
     309    if (!hasLeftCase)
     310    {
     311      cases += '<input type="radio" name="laterality" value="LEFT" ';
     312      if (thisCaseLaterality == 'LEFT') cases += ' checked';
     313      cases += ' onclick="lateralityOnChange()"><i>new case</i> (LEFT)<br>';
     314    }
     315    if (!hasRightCase)
     316    {
     317      cases += '<input type="radio" name="laterality" value="RIGHT"';
     318      if (thisCaseLaterality == 'RIGHT') cases += ' checked';
     319      cases += ' onclick="lateralityOnChange()"><i>new case</i> (RIGHT)<br>';
     320    }
     321   
     322    if (hasLeftCase && hasRightCase)
     323    {
     324      setInnerHTML('laterality.prompt', 'Merge with case');
     325    }
     326    else
     327    {
     328      setInnerHTML('laterality.prompt', 'Merge/create new case');
     329    }
     330   
     331    setInnerHTML('laterality.input', cases);
     332  }
     333  lateralityOnChange();
     334
    236335  Main.hide('gonext');
    237336  Main.show('gocreate');
     
    240339function goCreate()
    241340{
     341  Main.hide('gocreate');
    242342  var frm = document.forms['reggie'];
    243343
     
    248348  submitInfo.patientInfo = patientInfo;
    249349  submitInfo.caseInfo = caseInfo;
    250   //alert(JSON.stringify(submitInfo));
    251350
    252351  var request = Ajax.getXmlHttpRequest();
     
    257356
    258357  setInnerHTML('debug', request.responseText);
     358 
     359  var response = JSON.parse(request.responseText);
     360  if (response.status != 'ok')
     361  {
     362    setFatalError(response.message);
     363    return false;
     364  }
     365 
     366  var msg = '<ul>';
     367  for (var i = 0; i < response.messages.length; i++)
     368  {
     369    msg += '<li>' + response.messages[i];
     370  }
     371  msg += '</ul>';
     372  setInnerHTML('done', msg);
     373  Main.show('done');
     374  Main.show('gorestart');
     375
    259376}
    260377
     
    267384}
    268385
    269 function setInputStatus(prefix, message, isValid)
     386function setInputStatus(prefix, message, clazz)
    270387{
    271388  var tag = document.getElementById(prefix + '.status');
    272   Main.addClass(tag, isValid ? 'isvalid' : 'invalid');
    273   Main.removeClass(tag, isValid ? 'invalid' : 'isvalid');
     389  tag.className = 'status ' + clazz;
    274390 
    275391  setInnerHTML(prefix + '.message', message);
     
    381497  content: url('../../images/error.gif');
    382498}
    383 .status.isvalid:before
     499.status.warning:before
     500{
     501  content: url('../../images/warning.gif');
     502}
     503.status.valid:before
    384504{
    385505  content: url('../../images/ok.gif');
    386506}
    387 
     507.success ul
     508{
     509  list-style-image: url('../../images/ok.gif');
     510}
    388511</style>
    389512</base:head>
     
    407530      <table border="0" cellspacing="0" cellpadding="0" width="100%">
    408531      <tr valign="top">
    409         <td class="prompt">Case Name</td>
     532        <td class="prompt">Case name</td>
    410533        <td class="input"><input type="text" name="caseName"
    411534          size="18" maxlength="12" onblur="caseNameOnChange()"></td>
     
    414537      </tr>
    415538      <tr>
    416         <td class="prompt">Personal Number</td>
     539        <td class="prompt">Personal number</td>
    417540        <td class="input"><input type="text" name="personalNumber"
    418           size="18" maxlength="12" onkeyup="personalNumberOnChange()"></td>
     541          size="18" maxlength="12" onkeyup="personalNumberOnChange()" onkeypress="goNextOnTab(event)"></td>
    419542        <td class="status" id="pnr.status"></td>
    420543        <td class="help"><span id="pnr.message" class="message" style="display: none;"></span>(YYYYMMDDZZZZ)</td>
     
    452575        <td class="prompt">All first names</td>
    453576        <td class="input"><input type="text" name="allFirstNames"
    454           size="35" maxlength="255" onkeypress="allFirstNamesOnKeyPress(event)"></td>
     577          size="35" maxlength="255" onkeypress="goNextOnTab(event)"></td>
    455578        <td class="status" id="allFirstNames.status"></td>
    456579        <td class="help"><span id="allFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
     
    522645
    523646
    524   <!-- 3. New case registration -->
    525   <div id="newCaseSection" style="display: none;">
     647  <!-- 3. Case registration -->
     648  <div id="caseSection" style="display: none;">
    526649  <p>
    527650  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
    528651  <tr>
    529652    <td rowspan="2" class="stepno">3</td>
    530     <td class="steptitle">New case: Enter information</td>
     653    <td class="steptitle">About this case</td>
    531654  </tr>
    532655  <tr>
    533656    <td class="stepfields">
    534657      <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
     658      <tr valign="top">
     659        <td class="prompt" id="laterality.prompt">Laterality</td>
     660        <td class="input" id="laterality.input">
     661          <input type="radio" name="laterality" value="LEFT" onclick="lateralityOnChange()">LEFT
     662          <input type="radio" name="laterality" value="RIGHT" onclick="lateralityOnChange()">RIGHT
    540663        </td>
    541         <td class="status"></td>
    542         <td class="help"></td>
     664        <td class="status" id="laterality.status"></td>
     665        <td class="help"><span id="laterality.message" class="message" style="display: none;"></span></td>
    543666      </tr>
    544667      <tr valign="top">
    545668        <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        
     669        <td class="input" id="specimenTubes"><i>not found</i></td>
     670        <td class="status" id="specimenTubes.status"></td>
     671        <td class="help"><span id="specimenTubes.message" class="message" style="display: none;"></span>The specimen tube(s) associated with this case.</td>
     672      </tr>
    551673      <tr id="reasonIfNoSpecimenSection" valign="top">
    552674        <td class="prompt">Reason if no specimen</td>
     
    562684
    563685  <div class="error" id="errorMessage" style="display: none; width: 800px; margin-left: 20px; margin-bottom: 0px;"></div>
     686
     687  <div id="done" class="success" style="display: none; width: 800px; margin-left: 20px; margin-top: 20px;"></div>
    564688
    565689  <table style="margin-left: 20px; margin-top: 10px;">
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/PersonalRegistrationServlet.java

    r1289 r1290  
    3535import net.sf.basedb.reggie.Reggie;
    3636import net.sf.basedb.util.MD5;
     37import net.sf.basedb.util.Values;
    3738import net.sf.basedb.util.error.ThrowableUtil;
    3839import net.sf.basedb.util.formatter.DateFormatter;
     
    204205    JSONObject json = new JSONObject();
    205206    json.put("status", "ok");
     207   
     208    JSONArray jsonMessages = new JSONArray();
    206209 
    207210    final SessionControl sc = Application.getSessionControl(ID, req.getRemoteAddr());
     
    245248          as.getAnnotation(dateOfBirthType).setValue(df.parseString(pnr.substring(0, 8)));
    246249          dc.saveItem(patient);
    247         }
    248        
    249         // Create new case
    250         Sample cse = Sample.getNew(dc);
    251         cse.setName((String)jsonCase.get("name"));
    252         AnnotationType lateralityType = Reggie.findAnnotationType(dc, Item.SAMPLE, Reggie.ANNOTATION_LATERALITY, true);
    253         AnnotationSet as = cse.getAnnotationSet();
    254         as.getAnnotation(lateralityType).setValue((String)jsonCase.get("laterality"));
    255         cse.setBioSource(patient);
    256         dc.saveItem(cse);
     250         
     251          jsonMessages.add("Patient '" + patient.getName() + "' created successfully.");
     252        }
     253       
     254        String laterality = (String)jsonCase.get("laterality");
     255       
     256        String originalCaseName = (String)jsonCase.get("name");
     257        Sample theCase = null;
     258        if ("LEFT".equals(laterality) || "RIGHT".equals(laterality))
     259        {
     260          // Register a new case
     261          theCase = Sample.getNew(dc);
     262          theCase.setName(originalCaseName);
     263          AnnotationType lateralityType = Reggie.findAnnotationType(dc, Item.SAMPLE, Reggie.ANNOTATION_LATERALITY, true);
     264          AnnotationSet as = theCase.getAnnotationSet();
     265          as.getAnnotation(lateralityType).setValue((String)jsonCase.get("laterality"));
     266          theCase.setBioSource(patient);
     267          dc.saveItem(theCase);
     268          jsonMessages.add("Case '" + originalCaseName + "' created successfully.");
     269        }
     270        else
     271        {
     272          // Merge with existing case
     273          theCase = Sample.getById(dc, Values.getInt(laterality));
     274          jsonMessages.add("Case '" + originalCaseName + "' merged with case '" + theCase.getName() + "' successfully.");
     275        }
    257276       
    258277        // Link the case with specimen
     278        AnnotationSet caseAnnotations = theCase.getAnnotationSet();
    259279        JSONArray jsonSpecimen = (JSONArray)jsonCase.get("specimen");
    260280        if (jsonSpecimen != null && jsonSpecimen.size() > 0)
     
    262282          AnnotationType padType = Reggie.findAnnotationType(dc, Item.SAMPLE, Reggie.ANNOTATION_PAD, true);
    263283          AnnotationType padCaseType = Reggie.findAnnotationType(dc, Item.SAMPLE, Reggie.ANNOTATION_PAD_CASE, true);
    264           List padCase = new ArrayList(as.getAnnotation(padCaseType).getValues());
     284          List padCase = new ArrayList(caseAnnotations.getAnnotation(padCaseType).getValues());
    265285          for (int i = 0; i < jsonSpecimen.size(); ++i)
    266286          {
    267287            JSONObject jsonSpec = (JSONObject)jsonSpecimen.get(i);
    268288            Sample specimen = Sample.getById(dc, ((Long)jsonSpec.get("id")).intValue());
     289            // Set specimen to 'pooled' and link with case
    269290            specimen.setPooled(true);
    270             specimen.getCreationEvent().addSource(cse, null);
     291            specimen.getCreationEvent().addSource(theCase, null);
     292            // Copy PAD annotation on specimen to PADcase annotation on case
    271293            String pad = (String)Reggie.getAnnotationValue(specimen, padType);
    272294            if (pad != null && !padCase.contains(pad)) padCase.add(pad);
    273295          }
    274           as.getAnnotation(padCaseType).setValues(padCase);
     296          if (padCase.size() > 0) caseAnnotations.getAnnotation(padCaseType).setValues(padCase);
     297          jsonMessages.add(jsonSpecimen.size() + " specimen tubes linked with case '" + theCase.getName() + "' successfully.");
    275298        }
    276299        else
    277300        {
    278301          AnnotationType reasonIfNoSpecimenType = Reggie.findAnnotationType(dc, Item.SAMPLE, Reggie.ANNOTATION_REASON_IF_NO_SPECIMEN, true);
    279           Annotation reasonIfNoSpecimen = as.getAnnotation(reasonIfNoSpecimenType);
     302          Annotation reasonIfNoSpecimen = caseAnnotations.getAnnotation(reasonIfNoSpecimenType);
    280303          List values = new ArrayList(reasonIfNoSpecimen.getValues());
    281           values.add("[" + cse.getName() + "] " + jsonCase.get("reasonIfNoSpecimen"));
     304          values.add("[" + originalCaseName + "] " + jsonCase.get("reasonIfNoSpecimen"));
    282305          reasonIfNoSpecimen.setValues(values);
    283306        }
    284307       
    285308        dc.commit();
     309        json.put("messages", jsonMessages);
    286310       
    287311      }
Note: See TracChangeset for help on using the changeset viewer.