Lose the Tedium - Automate VGR Variable Initiation (Revisited)

One of the most popular posts from this blog has consistently been the Lose the Tedium - Automate VGR Variable Initiation post in which I showed how I've used a snippet of code to generate my "INIT" section for my VGR. This has been always been helpful to me when initially building forms, especially long ones (it gives a certain peace of mind even on short ones).

The only "problem" with that code is that it relies on jQuery for much of its functionality. I've gotten the request more than once to rewrite it using "native" JavaScript (ie. no additional required libraries).

/*
* vgr_init_js() - Automation to build VGR initialization code
* http://heo-iforms.blogger.com/
*
* Version: 1.0
* Copyright 2014 Scott Morris - http://heo-iforms.blogger.com/
*
* Dual licensed under MIT or GPLv2 licenses
*   http://en.wikipedia.org/wiki/MIT_License
*   http://en.wikipedia.org/wiki/GNU_General_Public_License
*
*/
function vgr_init_js() {
  var txt = {}, chk = {}, rad = {}, cbo = {}, btn = {}, output = '', obj;

  var sels = document.getElementsByTagName('SELECT');
  var inputs = document.getElementsByTagName('INPUT');

  for (var i=0; i < inputs.length; i++) {
    switch (inputs[i].type) {
      case 'text':
        txt[inputs[i].name] = inputs[i].value;
        break;

      case 'checkbox':
        chk[inputs[i].name] = (inputs[i].checked) ? inputs[i].value : '';
        break;

      case 'submit':
        btn[inputs[i].name] = inputs[i].value;
        break;

      case 'radio':
        if (rad.hasOwnProperty(inputs[i].name)) {
          rad[inputs[i].name] = (inputs[i].checked) ? inputs[i].value : rad[inputs[i].name];
        } else {
          rad[inputs[i].name] = (inputs[i].checked) ? inputs[i].value : '';
        }
        break;
    }
  }

  for (var i=0; i < sels.length; i++) {
    cbo[sels[i].name] = sels[i].value;
  }

  // Checkboxes
  output += '# Checkboxes ' + Array(86).join('-') + '\n';
  for (obj in chk) {
    output += 'INIT,SET,CHECKBOX,' + obj + ',TO,"' + chk[obj] + '"\n';
  }

  // Text Boxes
  output += '\n# Text Boxes ' + Array(86).join('-') + '\n';
  for (obj in txt) {
    output += 'INIT,SET,TEXT,' + obj + ',TO,"' + txt[obj] + '"\n';
  }

  // Drop Down Boxes
  output += '\n# Drop Down Boxes ' + Array(81).join('-') + '\n';
  for (obj in cbo) {
    output += 'INIT,SET,SELECT,' + obj + ',TO,"' + cbo[obj] + '"\n';
  }

  // Radio Buttons
  output += '\n# Radio Buttons ' + Array(83).join('-') + '\n';
  for (obj in rad) {
    output += 'INIT,SET,RADIO,' + obj + ',TO,"' + rad[obj] + '"\n';
  }

  // Buttons
  output += '\n# Buttons ' + Array(89).join('-') + '\n';
  for (obj in btn) {
    output += 'INIT,SET,HIDDEN,' + obj + ',TO,"' + btn[obj] + '"\n';
  }

  output = '<' + 'pre>' + output + '<' + '/pre>';


  myWindow=window.open('','','width=650,height=600,location=no,menubar=no,status=no,left=10,top=10');
  myWindow.title = "VGR Init Code";
  myWindow.document.write(output);
  myWindow.focus();
}

You can trigger this code in any number of ways. As I mentioned in an earlier post, you can "tie" it to clicking a picture while holding Shift+Ctrl. If you'd like more information on how to do that or to throw other ideas around, feel free to reach out to me.

Scott Morris is available for training, mentoring, troubleshooting, and iForms consulting. Find out more at www.thinkiforms.com

The AND_NOT and OR_NOT connectors

UPDATE:

Upon further testing and asking around, it looks like my initial reading of the AND_NOT logical connector was based on an older version of the documentation. It turns out that the AND_NOT logical connector is broken and is not recognized by the VGR parser. It seems that the OR_NOT operator works, but I still need to do some testing to confirm it. I've made some notations to this article where needed.

Original Post

When reading the VGR documentation and putting together my VGR Cheat Sheet, I found that, in addition to the familiar logical connectors {AND, OR, THEN}, there are also the AND_NOT and OR_NOT connectors. If you're not sure what I'm talking about when I say logical connectors, this is how the VGR Handbook defines them:

Connector: A logical connector for linking multiline VGR rules. This only applies to IF statements with multiple conditions, and IF statements where there are multiple commands in the THEN clause.

That's to say, that seventh piece of your VGR code that:

  • Connects multiple IF statements: IF ... AND ... AND ... THEN
  • Connects multiple lines after the IF: IF ... THEN ... AND ...

If you look at the Logical Connectors section of my VGR Cheat Sheet, you'll see four entries: AND, AND_NOT, OR, and OR_NOT. Just as you might expect, the AND returns true if both IF statements evaluate to true and the OR returns true if either IF statements evaluate to true.

So what about the AND_NOT and OR_NOT logical connectors? They are a little more specific. The AND_NOT returns true if the first IF evaluates to true and the second IF evaluates to false. Similarly, the OR_NOT evaluates to true if the first IF evaluates to true or the second IF evaluates to false

Show / Hide Elements based on a Checkbox

One of the best ways to save space on a busy iForm and make it easier to read is to only show certain pieces of information when they are relevant. For instance, if you have an order with prompts that need to be filled in, you can hide the supporting prompts until the order is selected and in most iForms, that means checking a checkbox.

So today, we'll look at how to hide and show an element on your iForm based on when a checkbox is checked / unchecked. Up until this point on the blog, I've mainly focused on how to get things done using the jQuery JavaScript framework, but today I've decided to be more inclusive and include the instructions on how to do this using "native JavaScript" as well. For each method, I've included two examples: one example of showing / hiding an inline prompt and one example of showing / hiding whole orders.

Clinical Decision Support - Using Lab Dates in JavaScript

This blog post was inspired by a question raised by Scantron (Michael) on the HEO iForms Google Group. He writes:

Hello all,

I was wondering if anyone is working with dates in java script? I have some criteria to order a CBC if one has not been completed in the past 24 hours. I can get it to subtract the dates and order the tests when I hard code the dates, but when using the @@patient.lab_result.Plt.date@@, the value brings in a carriage return symbol, and I get an unterminated string constant error. anyone have a solution for this?

My js:

var dt1 = new Date(Date.parse("@@patient.lab_result.Plt.date@@"));
var one_day=1000*60*60*24;
var time_diff1 = (parseInt(dt1.getTime()-dt2.getTime())/(one_day));

if (time_diff1 > 1 || isNaN(time_diff1)){
 $('#PtInr').val(1);
}

What comes in:

var dt1 = new Date(Date.parse("03/13/2013 09:46 AM
"));

InSight Conference 2013

I just got confirmation that I will be co-presenting at this year's InSight user group conference again this year with Dr. Mark Pratt and Bonnie McGuire. I co-presented on two sessions with them last year; it was a great time and a great opportunity to share ideas and meet other people that work with McKesson products. This year, the two educational sessions that we're presenting in are on Friday morning, so make sure that you get an afternoon or evening flight home.

If you have not had the opportunity to check out this conference yet, I highly recommend it. It's a great opportunity to see what's coming up, to hear how some other hospitals have faced (and overcome) the same issues that you may be experiencing, to meet other folks and share ideas, and to even hear directly from McKesson about what they think about all of these things.

If you are going to be able to attend this year, I'd love to meet you. I have such a good time geeking out about this stuff and talking about new and interesting ways to use the system.