Search the OSCAR Documentation
< All Topics
Print

eForm From Scratch/Tweaking eForm Programming Tips

Share this

Documentation Copyright © 2023 by Adrian Starzynski under the Creative Commons Attribution-Share Alike 3.0 Unported License

The purpose of this article is to give you a “copy and paste” tool to make your own eForms the advanced manual method (the easier and method is to use OSCAR’s built-in eForm generator). If you want to learn more advanced stuff, check out online tutorials such as W3 Schools.

Basics

eForms are programmed using html and javascript. There are countless online resources for ways to tweak your eForms.

Here’s the basic skeleton of a webpage:

<html>
<head>
<title> </title>

</head>
<body>

</body>
</html>

Copy and paste the above into a text editor such as Visual Studio Coded (the author of this article recommends this program).

Save the file as “filename.html”. Make sure you select “all files” under the “save as type”.

Everything is enclosed between an “opening tag” that look like <tag> and a “closing tag” that looks like </tag>.

The <html></html> tells the browser that it’s an html file, aka a webpage.

The <head></head> contains extra information that is useful for displaying the page

You can put in a title between the <title></title>, and it’ll show up in the title bar

All the code inside the <body></body> are the actual contents that you get to see in the browser.

Make sure you don’t overlap different opening and closing tags. For example,
<tag1> <tag2></tag2> </tag1> is ok, but
<tag1> <tag2> </tag1> </tag2> is not ok.

Inserting the eForm image file

The best way to get the eForm image file is to get it in electronic form – .docx, pdf, png, or jpg/jpeg. It is very bad to scan a paper copy and use that for your eForm – that will have the paper’s fold marks/shading visible on print/fax, will waste more printer ink and will be less visible. 90% of the time a quick Google search for the form you are converting into an eForm will result in a PDF file of the organization. For example, most hospitals and larger have a referral forms directory on their websites which will provide you with a PDF of the form. If you have a Word document file of the referral form, it can easily be exported to PDF.

This PDF needs to be converted to a png or jpg file for it to be used in an OSCAR eForm. There are many ways to convert PDF to image file but I personally use https://pdf2jpg.net/ which is quick and doesn’t require any complex converter software download. Here is an older presentation on preparing eForm image files which may come in handy.

After you’ve converted your PDF to image file, you need to reference it in the eForm like this:

Now, it’s time to put in the image file:

<div style="position: absolute; left: 10px; top: 10px;" >
	<img src="${oscar_image_path}imagename.png" width="750">
</div>
<!-- You can remove ${oscar_image_path} as you develop the eForm, but make sure you put it back before uploading to OSCAR otherwise the image wouldn't show. -->
<!-- Also note: the image filename IS CASE SENSITIVE INCLUDING THE EXTENSION. It may work otherwise in Windows, but not in OSCAR because it's based on a Linux platform -->

Copy the above and paste between the <body> and </body>

Make sure you put the image file and the html file in the same folder while you’re editing the eForm

Temporarily delete the ${oscar_image_path} inside the <img> tag if you’re editing the file locally. You’ll need to put it back in after you upload it onto OSCAR.

Note: I find that having an image with a width of 750 pixels fits a letter-sized paper the best. I usually prepare the image file so that it’s 1500 pixels wide, so that it scales down by 50% in the browser.

Inserting the ‘form’ element

<form method="post" action="" name="FormName">
<!--  put all the form inputs here-->


<div class="DoNotPrint" style="position: absolute; top: 1000px; left: 10px;">
<table>
	<tr>
		<td>
			Subject: <input name="subject" size="40" type="text">
			<input value="Submit" name="SubmitButton" type="submit">
			<input value="Reset" name="ResetButton" type="reset">
			<input value="Print" name="PrintButton" type="button" onclick="window.print()">
		</td>
	</tr>
</table>
</div>
</form>

Copy the above and paste between the <body> and </body>

You can customize the position of the submit buttons by changing the numbers in blue

Install the tools to help with placement of the input boxes

Copy above and paste between <head></head>

This script will give you the mouse coordinates in the titlebar, so you can find out where to put the input boxes

I simply delete the above script when I’m done with putting in the input boxes.

<!-- SCRIPT GIVES THE MOUSE COORDINATES - Hold SHIFT and click two points for distance between -->
<script type="text/javascript" language="javascript">
var isIE = document.all?true:false;
if (!isIE) document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = getMousePosition;
document.onclick = captureposition;
var capX = 0;
var capY = 0;
var sy = 0;
var sx = 0;

function getMousePosition(e) {
var _x;
var _y;
if (!isIE) {
_x = e.pageX;
_y = e.pageY;
}
  document.title = _x + " " + _y;
  return true;
}
function captureposition(e) {

  if (e.shiftKey) {
     if ((capX == 0) && (capY == 0)) {
        capX = e.pageX;
        capY = e.pageY;
     } else {
        var diffX = e.pageX-capX;
        var diffY = e.pageY-capY;
        if (Math.abs(diffX) > Math.abs(diffY)) {
            alert('X-coordinate distance: ' + diffX + 'px');
        } else {
            alert('Y-coordinate distance: ' + diffY + 'px');
        }
        capX = 0;
        capY = 0;
     }
   }
}
</script>
<!-- ----------End coordinate script--------------------------------------------------------- -->

Manual Field Alignment Refresh

If you add the following code <meta http-equiv=”refresh” content=”3″> near the top of your eForm, you will force the page to auto-refresh every 3 seconds. Now you can manually tweak the left and top pixel values, save the changes and view the result in a few seconds. Make sure you remove the line after you finish making your changes.

The Inputs

Rules:

  • Each input needs a name. If not, the contents of the input won’t be saved and/or won’t display on print!
  • Each input name has to be unique
  • The input name cannot contain spaces or symbols

Single-line text input

<div style="position: absolute; left: 100px; top: 100px;"> 
	<input name="SingleLineInputName" type="text" class="noborder" style="width: 100px;">
</div>

Copy above and paste under the <!– put all the form inputs here–> inside the <form></form>.

Move your mouse to the top left corner of the form input box and note the x and y coordinate. Substitute these numbers into the “left: Xpx” and the “top: Ypx;”.

Move your mouse to the left edge of the form input box, press-and-hold the shift key, click on the left edge then click on the right edge of the input box. A pop-up box will come up showing you the width of the box. Input this number into the “width: Wpx;”.

Multi-line text input

<div style="position: absolute; left: 100px; top:100px;"> 
	<textarea name="MultiLineInputName" class="noborder" style="width:100px; height:100px;"></textarea>
</div>

Again, you’ll have to customize the “left:”, “top:”, “width:”, and “height:” numbers to the form.

Checkboxes

<div style="position: absolute; left: 100px; top: 100px;">
        <input name="CheckboxName" type="checkbox">
</div>

The actual X and Y coordinates of the checkboxes are somehow about 4 pixels less than the indicated numbers

X-Box

The X-Box is a replacement for the checkbox. Instead of a checkmark, we use a black outline with an X. If your xBox has 2 exclusive choices, such as [ ] Yes or [ ] No, you can use the following code to only allow a single choice:

<input name="FldNameY" id="FldNameY" type="text" class="Xbox" style="position:absolute; left:382px; top:580px; width:12px; height:12px;" onkeypress="javascript:return displayKeyCode(event,this.id);" onClick="document.FormName.FldNameN.value='';">
<input name="FldNameN" id="FldNameN" type="text" class="Xbox" style="position:absolute; left:435px; top:580px; width:12px; height:12px;" onkeypress="javascript:return displayKeyCode(event,this.id);" onClick="document.FormName.FldNameY.value='';">

Radio Buttons

<div style="position: absolute; left: 100px; top: 100px;">
        <input name="RadioName" type="radio" value="value1">
</div>
<div style="position: absolute; left: 100px; top: 110px;">
        <input name="RadioName" type="radio" value="value2">
</div>

The actual X and Y coordinates of the checkboxes are somehow about 4 pixels less than the indicated numbers

Auto-populating input fields from the OSCAR database

A list of database info that you can auto-populate into eForms can be found here.

To use these, just put the oscarDB=xxxx inside the input tag. I usually put it right before the closing “>”.

For Example, the following will auto-populate the textarea with the clinic label.

<div style="position: absolute; left: 100px; top:100px;"> 
	<textarea name="MultiLineInputName" class="noborder" style="width:100px; height:100px;" oscarDB=clinic_label></textarea>
</div>

Please note that you DON’T need the quotes around the oscarDB database tag.

Some of the things you’ll need to do to make the eForm print properly

You probably don’t want to print out some of the things on the screen such as the border around the input boxes and the submit/print buttons at the bottom.

To take these away:

1. Copy the following and paste it into the between the <head> and </head>

<style type="text/css" media="print">
<!-- CSS Script that removes the whole division when printing -->
.DoNotPrint {
	display: none;
}
<!-- CSS Script that removes textarea and textbox borders when printing -->
.noborder {
	border : 0px;
	background: transparent;
	scrollbar-3dlight-color: transparent;
	scrollbar-3dlight-color: transparent;
	scrollbar-arrow-color: transparent;
	scrollbar-base-color: transparent;
	scrollbar-darkshadow-color: transparent;
	scrollbar-face-color: transparent;
	scrollbar-highlight-color: transparent;
	scrollbar-shadow-color: transparent;
	scrollbar-track-color: transparent;
	background: transparent;
	overflow: hidden;
}
</style>

2. To remove a whole division (i.e. everything between a <DIV> and </DIV>) when printing, add class=”DoNotPrint” as an attribute in the opening tag of <div>. For example:

<form method="post" action="" name="FormName">
<!--  put all the form inputs under here-->


<div class="DoNotPrint" style="position: absolute; top: 1000px; left: 10px;">
<table>
	<tr>
		<td>
			Subject: <input name="subject" size="40" type="text">
			<input value="Submit" name="SubmitButton" type="submit">
			<input value="Reset" name="ResetButton" type="reset">
			<input value="Print" name="PrintButton" type="button" onclick="window.print()">
			<input value="Print and Submit" name="PrintSubmitButton" type="button" onClick="window.print(); document.FormName.submit()">
			</td>
	</tr>
</table>
</div>
</form>

3. To remove the outline of an input box when printing, add class=”noborder” as an attribute in the <input>. For example:

<div style="position: absolute; left: 100px; top: 100px;"> 
	<input name="SingleLineInputName" type="text" class="noborder" style="width: 100px;">
</div>

Pre-filling an input box with your customized value

Single-line text input

<div style="position: absolute; left: 100px; top: 100px;"> 
	<input name="SingleLineInputName" type="text" class="noborder" style="width: 100px;" value="Substitute your pre-filled text here" >
</div>

Multi-line text input

<div style="position: absolute; left: 100px; top:100px;"> 
	<textarea name="MultiLineInputName" class="noborder" style="width:100px; height:100px;"> Substitute your pre-filled text here </textarea>
</div>

Checkboxes

<div style="position: absolute; left: 100px; top: 100px;">
        <input name="CheckboxName" type="checkbox" checked>
</div>

Radio Buttons

<div style="position: absolute; left: 100px; top: 100px;">
        <input name="RadioName" type="radio" value="value1" checked >
</div>
<div style="position: absolute; left: 100px; top: 110px;">
        <input name="RadioName" type="radio" value="value2">
</div>

Pre-checking the gender checkboxes in some eForms

This one is a bit tricky, you’ll have to do a few different things

1. Put the following in between <head> and </head>

<!-- Pre-checking Gender script -->
<script type="text/javascript" language="javascript">
function checkGender(){
	if (document.getElementById('PatientGender').value == 'M'){
		document.getElementById('Male').checked = true;
	}else if (document.getElementById('PatientGender').value == 'F'){
		document.getElementById('Female').checked = true;
	}
}
</script>

2. Put onload=”checkGender();” within the opening <body> tag

<body onload="checkGender();">

3. Put the following with the other input boxes within the <form></form>

<div style="position:absolute; left:100px; top: 100px;">
	<input name="Male" id="Male" type="checkbox" class="noborder">
</div>
<div style="position:absolute; left:110px; top: 100px;">
	<input name="Female" id="Female" type="checkbox" class="noborder">
</div>
<input name="PatientGender" id="PatientGender" type="hidden" oscarDB=sex >

Calendar/Date Selection in eForms

When you add an input through the eForm generator and have the option “Add calendar date picker for fields labeled date or day”, a calendar date picker will appear. The default date format is YYYY-MM-DD, for example 2023-01-31.

If you want to customize the date picker, so that a selected date is displayed any another format such as MMM/DD/YY (Jan/01/2023), then you can see this video on date calendar customization for eForms. Video is also shown below (by John Robertson):

Here is the code to add to <head> for calendars:

<!-- main calendar program -->
<script src="../share/calendar/calendar.js"></script>
<script src="../share/calendar/lang/calendar-en.js"></script>
<script src="../share/calendar/calendar-setup.js"></script>
<link rel="stylesheet" type="text/css" media="all" href="../share/calendar/calendar.css" title="win2k-cold-1" />

And add this after </form> but before </body> (the element ID goes instead of “today” if you have it different, and for multiple date selection fields copy the line and change the element ID):

<!-- Define Date Calendars -->
<script>
Calendar.setup( { inputField : "today", ifFormat : "%Y-%m-%d", button : "today" } );
</script>

Only One Check

If you want to have several checkboxes but only one can be checked, like this:

You must add this to the <head> of the eForm:

<script>
$(document).ready(function() {
	$('[class^="child-"]').hide();
	$('.parent-field').click(function() {
		$('[class^="child-"]').hide();
		$('.parent-field').each(function() {
			if ( $(this).is('input:checkbox') ){
				if(this.checked){
					$('.child-' +  $(this).prop('id')).show();
				}else{
				$('.child-' + $(this).val()).show();
				}
			}
			if ( $(this).is('input:text') ){
				if($(this).val()=='X'){
					$('.child-' +  $(this).prop('id')).show();
				}else{
				$('.child-' + $(this).val()).show();
				}
			}
		});
	});
	$('[class^="only-one-"]').click(function() {
		if ( $(this).is('input:checkbox') ){
			$('.'+$(this).attr('class')).prop('checked', false);
			$(this).prop('checked', true);
		}

		if ( $(this).is('input:text') ){
			$('.'+$(this).attr('class')).val('');
			$( this ).val('X');
		}
	});
});
</script>

Make sure you have some version of jQuery loaded as well

<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>

Then follow this pattern for the input checkboxes:

<input name="severe_condition" id="severe_condition" class="only-one-condition" type="checkbox" style="position:absolute; left:53px; top:321px; ">
<input name="serious_condition" id="serious_condition" class="only-one-condition" type="checkbox" style="position:absolute; left:53px; top:360px; ">
<input name="moderate_condition" id="moderate_condition" class="only-one-condition" type="checkbox" style="position:absolute; left:53px; top:408px; ">
<input name="mild_condition" id="mild_condition" class="only-one-condition" type="checkbox" style="position:absolute; left:53px; top:455px; ">
<input name="negligible_condition" id="negligible_condition" class="only-one-condition" type="checkbox" style="position:absolute; left:53px; top:491px; ">
  • Name/ID should be “X_Y” where X is whatever you want and Y is constant value which will be the same for the rest of the checkboxes for only one check.
  • Class needs to be “only-one-X” where X is the constant value as above

To maximize the eForm window when it opens

(How to make the eForm open full-screen by default)

Put the following between the <head> and </head>

<script language="JavaScript">
  top.window.moveTo(0,0);
  top.window.resizeTo(screen.availWidth,screen.availHeight);
</script>

To hide headers and footers on print

By default when you print a page, it will include the page’s “headers and footers”, and browsers will print the web address of the page you printed.
For example:

There are several reasons why you wouldn’t want headers and footers to show on the eForms you print.
For example, that prints your OSCAR’s link/IP address on the page, which isn’t normally something you’d want the public to know of.

To have your printed eForms not show the headers and footers by default, add the following between the <head></head>

*NOTE: This snippet currently works fine on Chrome and Firefox. Other browsers ignore these settings and still print headers/footers and malforms the page. Chrome and Firefox are the recommended browsers for using OSCAR because others sometimes don’t display certain elements correctly (e.g. certain icons and css).
If you find that an extra page is being added to print, you may want to adjust the padding-top and padding-bottom settings below as necessary.

<style type="text/css" media="print">
@media print {
    @page {
        margin-top: 0;
        margin-bottom: 0;
    }
    body {
        padding-top: 36px;
        padding-bottom: 36px;
    }
}
</style>

Automatic Signatures

This shows image of the current user’s signature based on placement of the image alignment…

In order for this to work, the user has to have a signature image file set.

Add the following to <head> of the eForm:

<script language="javascript">
function SignForm() {
var provNum = $('#current_user_id').val();
document.getElementById('signature').src = "../eform/displayImage.do?imagefile=consult_sig_"+provNum+".png";
$('#signature').attr(onerror, "this.style.display='none'");
document.getElementById('signature').alt= provNum;
}
</script>

Then add the function to body onload (note – if you’re experiencing problems like the signature not showing on a specific eForm, try moving the SignForm(); function to be the first function in onload):

<body onload="SignForm();">

And then add this after the image reference in the eForm:

This will show the image of the current user’s signature where the position of this image is…

<img id="signature" name="signature" src="${oscar_image_path}BNK.png" width="150" height="25" style="position: absolute; left: 49px; top: 721px; z-index: 20">
<input type="hidden" id="current_user_id" name="current_user_id" oscardb=current_user_id>

You can change the width/height and position of where the signature image gets inserted by changing the bolded values.

If you have an eForm that requires multiple spots for the signature, just copy the function and change the name and then add that into onload and also add the below again but with the second function’s name in the ID and name.

e.g.:

<script language="javascript">
function SignForm() {
var provNum = $('#current_user_id').val();
document.getElementById('signature').src = "../eform/displayImage.do?imagefile=consult_sig_"+provNum+".png";
$('#signature').attr(onerror, "this.style.display='none'");
document.getElementById('signature').alt= provNum;
}
</script>
<script language="javascript">
function SignForm2() {
var provNum = $('#current_user_id').val();
document.getElementById('signature2').src = "../eform/displayImage.do?imagefile=consult_sig_"+provNum+".png";
$('#signature2').attr(onerror, "this.style.display='none'");
document.getElementById('signature2').alt= provNum;
}
</script>
<body onload="SignForm();SignForm2();">
<img id="signature" name="signature" src="${oscar_image_path}BNK.png" width="150" height="25"  style="position: absolute; left: 49px; top: 721px;z-index: 20">
<img id="signature2" name="signature2" src="${oscar_image_path}BNK.png" width="150" height="25"  style="position: absolute; left: 49px; top: 721px;z-index: 20">
<input type="hidden" id="current_user_id" name="current_user_id" oscardb=current_user_id>

Wet Signatures or Drawing Pad for Circling Affected Area

If you need a “wet” signature option that displays correctly on faxing and PDF, I have code for one that works but it involves a bit more work. I also used this for an MRI referral checklist that required the doctor to circle affects areas, and I modified this wet signature box to be superimposed on the eForm’s image and be transparent to allow drawing.

This version simply encodes the signature pad’s canvas as .png and stores the encoded value in a hidden input. Then on eForm display it gets decoded. This sticks on PDF and fax because the functions correctly make the image decode before it is generated into fax or PDF thus making it stay.

I have created eForms with several of these signature boxes each for either wet sign use or for drawing over an eForm image. Just use different element ID’s for the imagestore and canvases etc. i.e. “gen_signatureData1”, “gen_signatureData2”…

In the below example of this used as a drawing pad, the doctor wanted the drawing pen to show red color so I created a copy of signature_pad.min.js as signature_padRED.min.js and changed that to show the color as red:penColor||”red” and then referenced signature_padRED.min.js in the eForm. It looks like this when superimposed on the eForm image and used as transparent drawing tool/signature pad:

First, upload the signature_pad.min.js file to your eForm images folder.

Next, here is the code you need to add to the eForm:

Add this to <head> of the eForm:

<style type="text/css" media="screen">
  input {
    -moz-box-sizing: content-box;
    -webkit-print-color-adjust: exact;
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
  }
  /* Drawing the 'gripper' for touch-enabled devices */
  html.touch #content {
    float: left;
    width: 92%;
  }
  html.touch #scrollgrabber {
    float: right;
    width: 4%;
    margin-right: 2%;
    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAFCAAAAACh79lDAAAAAXNSR0IArs4c6QAAABJJREFUCB1jmMmQxjCT4T/DfwAPLgOXlrt3IwAAAABJRU5ErkJggg==);
  }
  html.borderradius #scrollgrabber {
    border-radius: 1em;
  }
</style>
<script src="${oscar_image_path}signature_pad.min.js"></script>
<style>
  /* signature pad styling */
  .signaturePad {
    opacity: 0.8;
    width: auto !important;
  }

  .signaturePad canvas {
    position: absolute;
    height: 100%;
  }

  .signaturePad .canvas_frame {
    position: relative;
    width: 210px;
    height: 100%;
    float: left;
    background-color: transparent;
    margin-right: 6px;
  }

  .signaturePad .clearBtn {
    position: relative;
    float: right;
    height: 50px;
    line-height: 50px;
    font-size: 1em;
    font-family: Verdana, Arial, sans-serif;
    text-align: center;
    border: 1px solid #ddd;
    background: #ddd url(images/ui-bg_highlight-soft_60_dddddd_1x100.png) 50%
      50% repeat-x;
    font-weight: normal;
    color: #000;
    padding: 0 1em;
    border-radius: 5px;
    font-size: 20px;
    cursor: pointer;
  }
  .signaturePad .clearBtn:hover,
  .signaturePad .clearBtn:active {
    color: red;
  }

  .signaturePad .signature_image {
    display: inline-block;
    position: absolute;
  }

  /* print only styling */
  @media print {
    .signaturePad {
      background-color: transparent;
      opacity: 1;
    }

    .signaturePad canvas {
      /* always hide canvas for printing. print image instead */
      display: none !important;
    }

    .signature_image {
      /* always show signature image when printing */
      display: inline-block !important;
    }
  }
</style>

<script>
  /** This function is called when the print button is clicked */
  function onEformPrint() {
    if ($(".signature_data").length > 0) {
      for (var i = 0; i < $(".signature_data").length; i++) {
        var $obj = $($(".signature_data")[i]);
        var imgData = $obj.val();
        var imgWidth = $obj.parent().find("canvas").attr("width");
        var imgHeight = $obj.parent().find("canvas").attr("height");
        var imgValue =
          "<img width='" +
          imgWidth +
          "' height='" +
          imgHeight +
          "' src='" +
          imgData +
          "' />";
        $obj.parent().find("canvas").parent().append(imgValue);
      }
    }
    window.print();

    if ($(".signature_data").length > 0) {
      for (var i = 0; i < $(".signature_data").length; i++) {
        $($(".signature_data")[i]).parent().find("img").remove();
      }
    }
  }
  /** This function is called when the eform submit button is clicked */
  function onEformSubmit() {
    for (var i = 0; i < $(".gen_input.radioBox").length; i++) {
      if ($(".gen_input.radioBox")[i].type == "password") {
        $(".gen_input.radioBox")[i].type = "text";
        if ($(".gen_input.radioBox")[i].value.length > 0) {
          $($(".gen_input.radioBox")[i]).attr(
            "value",
            $(".gen_input.radioBox")[i].id +
              "_" +
              $(".gen_input.radioBox")[i].value
          );
        }
      }
    }

    releaseDirtyFlag();
    document.forms[0].submit();
  }
  /** This function is called when the eform print & submit button is clicked */
  function onEformPrintSubmit() {
    onEformPrint();
    releaseDirtyFlag();
    setTimeout("document.forms[0].submit()", 2000);
  }

  /** this function is run on page load to make signature pads work. */
  $(function () {
    $(".signaturePad").each(function () {
      var $this = $(this);
      var $canvasFrame = $this.children(".canvas_frame");
      var $clearBtn = $this.children(".clearBtn");
      var canvas = $canvasFrame.children("canvas").get(0);
      var $data = $canvasFrame.children(".signature_data");
      var src = $data.val();
      // the image is needed even when signature pads are loaded for printing/faxing
      var $img = $("<img>", {
        src: src,
        class: "signature_image",
      });
      if (src && src.length > 0) {
        $img.appendTo($canvasFrame);
      }

      // if signature pad loaded correctly and eform viewed on screen
      /* NOTE: media type does not currently work in wkhtmltopdf
                                                                    See https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1737 */
      if (
        typeof SignaturePad !== "undefined" &&
        window.matchMedia("screen").matches
      ) {
        console.info("editable signature pad initializing ");
        $img.hide();
        var updateSlaveSignature = function (src_canvas, dest_canvas) {
          // write to the destination with image scaling
          var dest_context = dest_canvas.getContext("2d");
          dest_context.clearRect(0, 0, dest_canvas.width, dest_canvas.height);
          dest_context.drawImage(
            src_canvas,
            0,
            0,
            dest_canvas.width,
            dest_canvas.height
          );
        };
        // initialize the signature pad
        var signPad = new SignaturePad(canvas, {
          minWidth: 1,
          maxWidth: 2,
          onEnd: function () {
            $this.trigger("signatureChange");
          },
        });
        // load the image data to the canvas ofter initialization
        if (src != null && src != "") {
          signPad.fromDataURL(src);
        }
        // define a custom update trigger action. this allows the eform to store the signature.
        $this.on("signatureChange", function () {
          $data.val(signPad.toDataURL());
          $img.prop("src", signPad.toDataURL());
          if ($this.attr("slaveSigPad")) {
            var $slavePad = $("#" + $this.attr("slaveSigPad")); // get slave pad by id
            updateSlaveSignature(canvas, $slavePad.find("canvas").get(0));
            $slavePad.trigger("signatureChange"); // be careful of infinite loops
          }
          return false;
        });
        // init the clear button
        $clearBtn.on("click", function () {
          signPad.clear();
          $this.trigger("signatureChange");
          return false;
        });
      }
      // not using the canvas, show signature as an image instead.
      else {
        console.info("static signature pad initializing");
        $img.show();
      }
    });
  });
</script>

Next, add the function to the body onload:

<body onload="onEformLoad();">

In the <body> of the eForm, add this. You can change the bolded values uniformly to where you want the signature canvas to display (i.e. if you want to change the width then change all 3 width values to be the same), and adjust the width/height as necessary:

<canvas id="canvase" style="position:absolute; left:508px; top:705px; width:180px; height:180px;"></canvas>
<div id="gen_widgetId39" class="signaturePad" style="position:absolute; left:508px; top:705px; width:180px; height:180px; z-index: 13;">
<div class="canvas_frame">
<canvas width="180" height="180" style="touch-action: none;">
</canvas>
<input type="hidden" class="signature_data" id="gen_signatureData1" name="gen_signatureData1">
</div>
<button type="button" class="clearBtn DoNotPrint" id="gen_inputId39" name="gen_inputId39">clear</button>
</div>

These are the bottom buttons that call the signature pad functions. You already have these buttons coded in your eForm, so just adjust the onclick function to the bolded values as below, so that they call the functions that save the signature pad image (if you don’t adjust this then the signature image won’t save):

                                <input value="Submit" name="SubmitButton" id="SubmitButton" type="submit" onclick="onEformSubmit();">
                                 <input value="Reset" name="ResetButton" id="ResetButton" type="reset">
                                                <input value="Print" name="PrintButton" id="PrintButton" type="button" onclick="onEformPrint();">
                                                <input value="Print & Submit" name="PrintSubmitButton" id="PrintSubmitButton" type="button" onclick="onEformPrintSubmit();">

Adding fax capability

Your OSCAR must have FAX enabled (via the properties file) and set up to use faxing.

Add the following between the <head></head>
Note: if you already have jQuery added, then you can omit the first 3 lines shown below.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script> window.jQuery || document.write('<script src="../js/jquery-1.7.1.min.js">< \/script>') </script>
<script> window.jQuery || document.write('<script src="jquery-1.7.1.min.js">< \/script>') </script>

<script type="text/javascript" src="${oscar_javascript_path}eforms/faxControl.js"></script>
<script language="javascript" type="text/javascript" src="${oscar_javascript_path}eforms/printControl.js"></script>

This will show the fax controls in the eForm:

Add a one-touch Submit & Fax to destination button

You must already have added the code above (“Adding fax capability”) for the following to work.

If you want to add a button that will submit the eForm and also fax it to a specific fax number, add the code bolded shown below just above the Subject line:

Note: where it says value=”Submit & Fax to Xray Department” you put the name of the place you are faxing to. In the value=’555-555-5555′; you put the fax number where you want the eForm to be faxed once the one-touch Submit & Fax button is pressed.

    <div class="DoNotPrint" style="position: absolute; top: 1000px; left: 10px;">
        <table>
            <tr>
                <td>
        <input type="button" value="Submit & Fax to Xray Department"
        onClick="document.getElementById('otherFaxInput').value='555-555-5555';
        AddOtherFax();submitFaxButtonAjax(true);  ">
        <br>
        <br>
                    Subject: <input name="subject" size="40" type="text">
                    <input value="Submit" name="SubmitButton" type="submit">
                    <input value="Reset" name="ResetButton" type="reset">
                    <input value="Print" name="PrintButton" type="button" onclick="window.print()">
                    <input value="Print and Submit" name="PrintSubmitButton" type="button" onClick="window.print(); document.FormName.submit()">
                    </td>
            </tr>
        </table>
    </div>
</form>

You can also be fancy and add several of these buttons. I have created a MyHealth Centre Requisition eForm that can be one-touch faxed to a specific destination out of a list just by clicking the desired destination’s button.

Example of how this can look:

Simple only 1 one-touch fax option

Example of the code for multiple one-touch fax options:

Several one-touch fax options
<div class="DoNotPrint" id="BottomButtons" style="position: absolute; top:1000px; left:0px;">
      <table><tr><td>
<br>
<input type="button" value="Submit & Fax to LifeLabs General Fax"
onClick="document.getElementById('otherFaxInput').value='905-795-9891';
AddOtherFax();submitFaxButtonAjax(true);  ">
<input type="button" value="Submit & Fax to Dynacare General Fax"
onClick="document.getElementById('otherFaxInput').value='888-333-8044';
AddOtherFax();submitFaxButtonAjax(true);  ">
<input type="button" value="Submit & Fax to Alpha Lab Nixon"
onClick="document.getElementById('otherFaxInput').value='519-668-6428';
AddOtherFax();submitFaxButtonAjax(true);  ">
<br>
<br>
          Subject: <input name="subject" size="40" type="text"> <br>
//the rest of the form goes here... (not shown for simplicity purposes)

Pre-fill the “Other Fax Number” Box

Paste this code into <head> of the eForm.

Change the 5555555555 to the fax number you want pre-filled automatically, and change the Fax To Name to the description if you want this to show up in the “Providers” fax dropdown.

<script language="javascript">
function setFaxNo(){
	setTimeout(function() {
	document.getElementById("otherFaxInput").value="5555555555"
	AddOtherFax();
	return false;
	   },1000);
   
	  setTimeout(function() {
	   $('#otherFaxSelect').prepend('<option value="5555555555">Fax To Name</option>');
	   $('select option[value="5555555555"]').attr("selected",true);
	   return false;
             },500);
} 
</script>

Next, include setFaxNo(); in body onload. For example: <body onload=”setFaxNo();”>

Then the eForm will have the “Other Fax Recipient” field pre-filled, the “Add Other Fax Recipient” button will be pre-clicked automatically, so you can just press “Submit & Fax” to fax and save the eForm.

For example:

Copy to Clipboard Button

If you need to add an element to copy something to clipboard on click, play around with this Javascript code:

<script>
	/****************************
		Copy to Clipboard
	****************************/
	$(document).ready(function() {
		var y = document.getElementsByClassName('copyable');
		$(y).click(function() {
		this.select();
		document.execCommand('copy');
		$(this).css('background', 'transparent').fadeIn("slow");
		})
	})
</script>

Linking to other OSCAR Pages for the Patient

If you need to add links to other pages within OSCAR from the eForm (i.e. button to “Check patient’s labs”, etc.), use the below functions. This is available in a JS file here.

In the button you have to reference the function like this example: <input type=”button” value=”Labs” name=”labs” onclick=”onBodyLoad(); labs();” />

<!-- Script to allow linking to other Oscar pages for active patient -->

function onBodyLoad() {
	var re = new RegExp( "[?&]" + 'demographic_no' + "=([^&$]*)", "i" );
	var offset=window.opener.location.search.search(re);
	if(offset==-1){ 
	re = new RegExp( "[?&]" + 'demographicNo' + "=([^&$]*)", "i" );
	offset=window.opener.location.search.search(re);
  }
}

function doIFrameOnLoad() {
	var re = new RegExp( "[?&]" + 'demographic_no' + "=([^&$]*)", "i" );
	var offset=window.opener.location.search.search(re);
	if(offset==-1){ 
	re = new RegExp( "[?&]" + 'demographicNo' + "=([^&$]*)", "i" );
	offset=window.opener.location.search.search(re);
	}
	var demographic=RegExp.$1;
}

function Rx() {
window.open("../oscarRx/choosePatient.do?providerNo=&demographicNo="+RegExp.$1+"");
}

function allergy() {
window.open("../oscarRx/showAllergy.do?demographicNo="+RegExp.$1+"");
}

function prevention() {
window.open("../oscarPrevention/index.jsp?demographic_no="+RegExp.$1+"");
}

function tickler() {
window.open(" ../tickler/ticklerAdd.jsp?name=&chart_no=&bFirstDisp=false&demographic_no="+RegExp.$1+"&messageID=null&doctor_no=");
}

function diseaseRegistry() {
window.open("../oscarResearch/oscarDxResearch/setupDxResearch.do?demographicNo="+RegExp.$1+"&providerNo=&quickList=");
}

function message() {
window.open("../oscarMessenger/SendDemoMessage.do?demographic_no="+RegExp.$1+"");
}

function consult() {
window.open("../oscarEncounter/oscarConsultationRequest/ConsultationFormRequest.jsp?de="+RegExp.$1+"&teamVar=");
}

function eGFR() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=EGFR");
}

function Weight() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=WT");
}

function Height() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=HT");
}

function BMI() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=BMI");
}

function WC() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=WC");
}

function WAIS() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=WAIS");
}

function HgbA1C() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=A1C");
}

function CholLDL() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=LDL");
}

function ACR() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=ACR");
}

function SMK() {
window.open("../oscarEncounter/oscarMeasurements/SetupDisplayHistory.do?type=SMK");
}

function labGrid() {
window.open("../lab/CumulativeLabValues3.jsp?demographic_no="+RegExp.$1+"");
}

function labRow() {
window.open("../lab/CumulativeLabValues.jsp?demographic_no="+RegExp.$1+"");
}

function labs() {
window.open("../lab/DemographicLab.jsp?demographicNo="+RegExp.$1+"");
}

function HBPFlowsheet() {
window.open("../oscarEncounter/oscarMeasurements/TemplateFlowSheet.jsp?demographic_no="+RegExp.$1+"&template=hyptension");
}

function CHFFlowsheet() {
window.open("../oscarEncounter/oscarMeasurements/TemplateFlowSheet.jsp?demographic_no="+RegExp.$1+"&template=chf");
}

function DMFlowsheet() {
window.open("../oscarEncounter/oscarMeasurements/TemplateFlowSheet.jsp?demographic_no="+RegExp.$1+"&template=diab2");
}

function billing() {
window.open("../billing.do?billRegion=BC&billForm=DA&hotclick=&appointment_no=&demographic_name=&status=c&demographic_no="+RegExp.$1+"&providerview=&user_no=&apptProvider_no=&appointment_date=&start_time=12:0&bNewForm=1");
}

function billingGP() {
window.open("../billing.do?billRegion=BC&billForm=GP&hotclick=&appointment_no=&demographic_name=&status=c&demographic_no="+RegExp.$1+"&providerview=&user_no=&apptProvider_no=&appointment_date=&start_time=12:0&bNewForm=1");
}

function documents_all() {
window.open("../dms/documentReport.jsp?function=demographic&functionid="+RegExp.$1+"&view=all");
}

function documents_consult() {
window.open("../dms/documentReport.jsp?function=demographic&functionid="+RegExp.$1+"&view=consult");
}

Customizing fonts in the input fields

Put the following between the <head></head>

<style type="text/css">
.style1 {
		font-family: arial, sans-serif;
		font-size: 12px;
		font-weight: normal;
	}
</style>

For more styling, check out the css fonts page at W3schools.com

Insert class=”style1″ as an attribute into the <tag> that you want to customize the text. For example:

<div style="position: absolute; left: 100px; top: 100px;"> 
	<input name="SingleLineInputName" type="text" class="style1" style="width: 100px;">
</div>

If you want to apply multiple styles to the same element, just separate the classes by a space. For example:

<div style="position: absolute; left: 100px; top: 100px;"> 
	<input name="SingleLineInputName" type="text" class="noborder style1" style="width: 100px;">
</div>

Uploading it to your OSCAR server

Almost done! Make sure you save the file first.

Upload your eForm image file onto OSCAR first:

  1. Click on “Administration”
  2. Under “Manage eForms”, click on “Upload an Image”
  3. Browse to your image file, and click “Upload”

Now upload your html file:

  1. Under “Manage eForms”, click on “Upload”
  2. Type in the “eForm name”, and “Additional Information”
  3. Click “Choose File”, browse to you eForm html file
  4. Click on “Upload”

Once the html file is uploaded, make sure you add the ${oscar_image_path} back into the <img> tag

<div style="position: absolute; left: 10px; top: 10px;" >
	<img src="${oscar_image_path}imagename.png" width="750">
</div >
<!-- You can remove ${oscar_image_path} as you develop the eForm, but make sure you put it back before uploading to OSCAR otherwise the image wouldn't show. -->
<!-- Also note: the image filename IS CASE SENSITIVE INCLUDING THE EXTENSION. It may work otherwise in Windows, but not in OSCAR because it's based on a Linux platform -->

That’s it! Now you can make your own eForm for your office!

Just a few reminders:

  • Make sure you have a unique name for each input element
  • The filenames and image names are case sensitive
Table of Contents