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?"} ] ]