First prototype of the new Patient Portal

You can test it out here: https://clear.dental/test/test.php

Here is the source code that I hereby release under GPL v3:

 

<!doctype html>
<html>

<head>
	<title>Welcome New Patient</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	

	<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> 
	
	<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script>
    
    <script src="https://cdn.jsdelivr.net/npm/signature_pad@2.3.2/dist/signature_pad.min.js"></script>
    
</head>


    <body>
        <form>
<?php

include "stateList.php";

$json = file_get_contents('newPatQuestions.json');
$json_data = json_decode($json,true);

//echo var_dump($json_data);
$pageCounter =1;

foreach($json_data as $index => $page) {
    echo "<div data-role=\"page\" id=\"page{$pageCounter}\" data-theme=\"a\"> <div role=\"main\" class=\"ui-content\">\n";
    $hasCut = false;
    $cutName = ""; //is init here in order to get a high span...
    
    foreach($page as $index1 => $line) {
        //echo "Line: ".$line["name"]."\n";
        
        if($line["type"] == "header") { 
            if($pageCounter > 1) {
                echo "\t<div data-role=\"header\" data-add-back-btn=\"true\"><h1>{$line["prompt"]}:</h1></div>\n";
            } else {
                echo "\t<div data-role=\"header\"><h1>{$line["prompt"]}:</h1></div>\n";
            }
        } else if($line["type"] == "lineText") {
            echo "\t<div class=\"ui-field-contain\"><label for=\"".$line["name"]."\">".$line["prompt"].":</label>";
            echo "\t<input type=\"text\" name=\"".$line["name"]."\" value=\"\"  data-clear-btn=\"true\"></div>\n";
        }else if($line["type"] == "date") {
            echo "\t<div class=\"ui-field-contain\"><label for=\"".$line["name"]."\">".$line["prompt"].":</label>";
            echo "\t<input type=\"date\" name=\"".$line["name"]."\" value=\"\"></div>\n";        
        } else if($line["type"] == "choose") { 
            echo "\t<fieldset class=\"ui-field-contain\" data-role=\"controlgroup\">\n";
            echo "\t\t<legend>".$line["prompt"].":</legend>\n";
            foreach($line["options"] as $option) {
                echo "\t\t<label for=\"radio-choice-".$line["name"].$option."\">".$option."</label>\n";
                echo "\t\t<input type=\"radio\" name=\"radio-choice-".$line["name"]."\" id=\"radio-choice-".$line["name"].$option."\">\n";
            }
            echo "\t</fieldset>\n";
        } else if($line["type"] == "chooseLine") { 
            echo "\t<div class=\"ui-field-contain\">";
            echo "\t\t<label for=\"".$line["name"]."\">".$line["prompt"]."</label>";
            echo "\t\t<select name=\"".$line["name"]."\" id=\"".$line["name"]."\">";
            foreach($line["options"] as $option) {
                echo "\t\t\t<option value=\"".$option."\">".$option."</option>";
            }
            echo "\t</select></div>";
        } else if($line["type"] == "usState") {
            echo "\t<div class=\"ui-field-contain\">";
            echo "\t\t<label for=\"".$line["name"]."\">".$line["prompt"]."</label>";
            echo "\t\t<select name=\"".$line["name"]."\" id=\"".$line["name"]."\">";
            foreach($state_list as $code => $statename) {
                if($code == "NH")
                    echo "\t\t\t<option selected=\"selected\" value=\"".$code."\">".$statename."</option>";
                else
                    echo "\t\t\t<option value=\"".$code."\">".$statename."</option>";
            }
            echo "\t</select></div>";
        } else if($line["type"] == "number") {
            echo "\t<div class=\"ui-field-contain\"><label for=\"".$line["name"]."\">".$line["prompt"].":</label>";
            echo "\t<input type=\"number\" name=\"".$line["name"]."\" value=\"\"  data-clear-btn=\"true\"></div>\n";
        } else if($line["type"] == "phone") {
            echo "\t<div class=\"ui-field-contain\"><label for=\"".$line["name"]."\">".$line["prompt"].":</label>";
            echo "\t<input type=\"tel\" name=\"".$line["name"]."\" value=\"\"  data-clear-btn=\"true\"></div>\n";
        } else if($line["type"] == "cutoffQuestion") {
            $hasCut = true;
            $cutName = $line["name"];
            echo "\t<h3>".$line["prompt"]."</h3>\n";
            echo '<div data-role="controlgroup" data-type="horizontal">
                <a href="#" class="ui-btn ui-corner-all ui-icon-check ui-btn-icon-left" id="Yes'.$line["name"].'">Yes</a>
                <a href="#" class="ui-btn ui-corner-all ui-icon-delete ui-btn-icon-left" id="No'.$line["name"].'">No</a></div><div id="hideMe'.$line["name"].'">';
            echo '<script>            
                $(document).ready(function(){
                    $("#hideMe'.$line["name"].'").hide();
                    $("#nextBut'.$line["name"].'").hide();
                    $("#Yes'.$line["name"].'").click(function(){
                        $("#hideMe'.$line["name"].'").show(1000);
                        $("#nextBut'.$line["name"].'").show(1000);
                    });
                    $("#No'.$line["name"].'").click(function(){
                        $("#hideMe'.$line["name"].'").hide(1000);
                        $("#nextBut'.$line["name"].'").show(200);
                    });
                });
                    </script>';
        } else if($line["type"] == "signature") {
            echo "\t<label>".$line["prompt"]."</label>";
            
            echo '<canvas id="sig'.$line["name"].'" style="border:1px solid #000000;" ></canvas></div>';
            echo '<script>
                var canvas = document.querySelector("#sig'.$line["name"].'");
                canvas.width  = window.innerWidth * .9;
                canvas.height = window.innerHeight * .6;

                var signaturePad = new SignaturePad(canvas);

                function resizeCanvas() {
                    canvas.width  = window.innerWidth * .9;
                    canvas.height = window.innerHeight * .6;
                    signaturePad.clear(); // otherwise isEmpty() might return incorrect value
                }

                window.addEventListener("resize", resizeCanvas);
                resizeCanvas();
                </script>';
        } else if($line["type"] == "conditionLine") {
            echo "\t<div class=\"ui-field-contain\">";
            echo "\t<label for=\"".$line["name"]."\">".$line["prompt"]."<input id=\"".$line["name"]."\" type=\"checkbox\" name=\"".$line["name"]."\" value=\"\" ></label></div>\n";
            
            echo '<div id="hideMeExp'.$line["name"].'">';
            echo "\t<div class=\"ui-field-contain\"><label for=\"exp".$line["name"]."\">Please explain:</label>";
            echo "\t<input type=\"text\" id=\"\" name=\"exp".$line["name"]."\" value=\"\"  data-clear-btn=\"true\"></div>\n";
            echo '</div>';
            
            echo '<script>            
                $(document).ready(function(){
                    $("#hideMeExp'.$line["name"].'").hide();
                   
                    $("#'.$line["name"].'").click(function(){
                    
                        if( $("#'.$line["name"].'").is(\':checked\')) {
                            $("#hideMeExp'.$line["name"].'").show(500);
                        } else {
                            $("#hideMeExp'.$line["name"].'").hide(500);
                        }                        
                    });
                });
                    </script>';
        } else if($line["type"] == "askConditions") {
            echo "<hr><h4>Please check if you have any of the following conditions:</h4>";
        } else if($line["type"] == "dayChoose") {
            echo "\t<div class=\"ui-field-contain\"><label for=\"".$line["name"]."\">".$line["prompt"].":</label>";
            
            echo '<fieldset data-role="controlgroup" data-type="horizontal">
                    <input type="checkbox" name="mon'.$line["name"].'" id="mon'.$line["name"].'"><label for="mon'.$line["name"].'">Monday</label>
                    <input type="checkbox" name="tue'.$line["name"].'" id="tue'.$line["name"].'"><label for="tue'.$line["name"].'">Tuesday</label>
                    <input type="checkbox" name="wed'.$line["name"].'" id="wed'.$line["name"].'"><label for="wed'.$line["name"].'">Wednesday</label>
                    <input type="checkbox" name="thurs'.$line["name"].'" id="thurs'.$line["name"].'"><label for="thurs'.$line["name"].'">Thursday</label>
                    <input type="checkbox" name="fri'.$line["name"].'" id="fri'.$line["name"].'"><label for="fri'.$line["name"].'">Friday</label>
                    <input type="checkbox" name="sat'.$line["name"].'" id="sat'.$line["name"].'"><label for="sat'.$line["name"].'">Saturday</label>
                    
                    </fieldset></div>';
            
        }
    }
    
    if($hasCut) {
        $hasCut = false;
        echo "</div>"; //end of "hideme" for the rest of the page div
    }
    
    echo "<a href=\"#page".($pageCounter+1)."\" data-role=\"button\" data-inline=\"true\" data-transition=\"flow\" id=\"nextBut".$cutName."\" data-icon=\"carat-r\" data-iconpos=\"right\">Next Page</a>";
    echo "</div></div>\n";
    $pageCounter++;
}
?>



    
        </form>
    </body>
</html>

And here is the current JSON file:

[  
  [
    {"name":"intro", "type":"header","prompt":"Basic information"},
    {"name":"firstName", "type":"lineText","prompt":"First Name"},
    {"name":"middleName", "type":"lineText","prompt":"Middle Name"},
    {"name":"lastName", "type":"lineText","prompt":"Last Name"},
    {"name":"dob", "type":"date","prompt":"Date of Birth"},
    {"name":"sex", "type":"choose","prompt":"Sex", "options":["Male","Female"]},
    {"name":"gender", "type":"lineText","prompt":"Gender (if different)"},
    {"name":"race", "type":"chooseLine","prompt":"Race (optional)", "options":["I choose not to answer","American Indian or Alaska native","Asian", "Black or African American", "Polynesian","White","Other"]},
    {"name":"ethnicity", "type":"chooseLine","prompt":"Ethnicity (optional)", "options":["I choose not to answer","Hispanic Or Latino", "Not Hispanic or Latino"]},
    {"name":"martialStatus", "type":"choose","prompt":"Martial Status", "options":["Single", "Married"]},
    {"name":"addrStreet", "type":"lineText","prompt":"Address"},
    {"name":"addrCity", "type":"lineText","prompt":"City"},
    {"name":"addrState", "type":"usState","prompt":"State"},
    {"name":"addrZip", "type":"number","prompt":"Zip code"},
    {"name":"homePhone", "type":"phone","prompt":"Home Phone number"},
    {"name":"cellPhone", "type":"phone","prompt":"Cell Phone Number"},
    {"name":"email", "type":"lineText","prompt":"Email Address"},
    {"name":"workLoc", "type":"lineText","prompt":"Employer or School"},
    {"name":"workPhone", "type":"phone","prompt":"Work Phone number"},
    {"name":"referral", "type":"lineText","prompt":"How were you referred to our practice?"},
    {"name":"contactPref", "type":"choose","prompt":"How would you prefer we to contact you?", "options":["Home Phone","Call cell phone", "Text Phone", "Email"]}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Financial Responsibility"},
    {"name":"isOtherRes", "type":"cutoffQuestion","prompt":"Is somebody other than the patient listed responsible for payment?"},
    {"name":"otherResName", "type":"lineText","prompt":"Name of person responsible"},
    {"name":"otherResAddr", "type":"lineText","prompt":"Address of person responsible"},
    {"name":"otherResCity", "type":"lineText","prompt":"City of person responsible"},
    {"name":"otherResState", "type":"usState","prompt":"State of person responsible"}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Dental Plan Information"},
    {"name":"has1ins", "type":"cutoffQuestion","prompt":"Do you have a dental plan or dental insurance?"},
    {"name":"insCompany", "type":"lineText","prompt":"Dental Plan/Insurance Company"},
    {"name":"insPhone", "type":"phone","prompt":"Phone Number for Plan"},
    {"name":"subName", "type":"lineText","prompt":"Subscriber's Name"},
    {"name":"insDob", "type":"date","prompt":"Date of Birth"},
    {"name":"insSex", "type":"choose","prompt":"Sex", "options":["Male","Female"]}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Secondary Dental Plan Information"},
    {"name":"has2ins", "type":"cutoffQuestion","prompt":"Do you have a secondary dental plan or dental insurance?"},
    {"name":"insCompany2", "type":"lineText","prompt":"Secondary Dental Plan/Insurance Company"},
    {"name":"insPhone2", "type":"phone","prompt":"Phone Number for Secondary  Plan"},
    {"name":"subName2", "type":"lineText","prompt":"Subscriber's Name"},
    {"name":"insDob2", "type":"date","prompt":"Date of Birth"},
    {"name":"insSex2", "type":"choose","prompt":"Sex", "options":["Male","Female"]}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Please sign the following"},
    {"name":"voluntaryCome", "type":"signature","prompt":"I have voluntarily come to the Tamworth Dental Center seeking dental services including examinations, diagnostic tests and treatment"}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Please sign the following"},
    {"name":"alltrue", "type":"signature","prompt":"This is to certify that all information on this form is true and complete. I understand that if I deliberately give false information related to my sitation, now or in the future that I am liable for prosecution for fraud."}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Please sign the following"},
    {"name":"finanicallyResp", "type":"signature","prompt":"I understand that I am finanically responsible for all charges incurred that are not covered by my insurance company."}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Please sign the following"},
    {"name":"privHealthInformation", "type":"signature","prompt":"We are required by law to maintain the privacy of your health information and to provide you with the Notice of Privacy Practices."}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Please sign the following"},
    {"name":"shareTriCap", "type":"signature","prompt":"If applicable, I understand that the Tamworth Dental Center and the Fuel / Electric Assistance Program are both projects of Tri-County CAP. I hereby authorize Tamworth Dental Center staff to review and verify my household income as previously disclosed to the Fuel / Electric Assistance Program."}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Cardiovascular Conditions"},
    {"name":"anyHeartConditions", "type":"cutoffQuestion","prompt":"Do you have any heart or cardiovascular conditions?"},
    {"name":"na", "type":"askConditions","prompt":"na"},
    {"name":"hypertension", "type":"conditionLine","prompt":"Hypertension (high blood pressure)"},
    {"name":"hypotension", "type":"conditionLine","prompt":"Hypotension (low blood pressure)"},
    {"name":"endocarditis", "type":"conditionLine","prompt":"History of endocarditis"}
  ],
  
  [
    {"name":"intro", "type":"header","prompt":"Preferences"},
    {"name":"appointPref", "type":"dayChoose","prompt":"Which day(s) of the week works best for you?"}
  
  ]
  
  
]