Skip to main content
Known Participant
March 8, 2018
Answered

JavaScript question re: calculating BMI

  • March 8, 2018
  • 6 replies
  • 924 views

I am by no means a programmer but I've been fooling around with JavaScript a little and had enough success to whet my appetite. So I thought this would be a fairly simple problem.

I have a couple of text entry boxes, one of which has a variable, v_Ht and the other which has a variable, v_Wt associated with it. When a slide enters, I want the BMI to appear in a text caption. Here is the JavaScript I've attached to On Enter for that slide:

Height = window.cpAPIInterface.getVariableValue('v_Ht');

Weight = window.cpAPIInterface.getVariableValue('v_Wt');

Kiloweight = Weight * 0.45;

HeightMeters = Height * 0.025;

HeightMetersSquared = HeightMeters * HeightMeters;

BMI = Kiloweight / HeightMetersSquared;

window.cpAPIInterface.setVariableValue('v_BMI', BMI); 

I have created a Captivate variable for BMI as well (v_BMI). What's appearing in the text caption is NaN, which I believe means that the result is not a number. I'm really puzzled as to why I'm getting this result when I followed a similar procedure (successfully) to calculate tax and a discount on a product.

This topic has been closed for replies.
Correct answer sabre123

Your entry box text is a string object by default.

You've got [at least] two options:

Cast your v_Ht and vWt variables as Number datatypes:

Height = Number(window.cpAPIInterface.getVariableValue('v_Ht'));

Weight = Number(window.cpAPIInterface.getVariableValue('v_Wt'));

or

Change your entry box to use numbers:

Style>More Options>Numbers option

6 replies

sabre123
Participating Frequently
March 12, 2018

    var yourString = "120/80";

    var stringBP = yourString.split("/");

    var systolic = stringBP[0];

    var diastolic = stringBP[1];

of course, yourString, in your case would be the user entry variable.

Known Participant
March 13, 2018

Thanks so much - it works! I wasn't aware of the split function, because, strangely, it wasn't mentioned in the JS manual I was referring to, but it sure does make life simple for situations like this one.

One odd thing I noticed with the TE field (and this was by accident): in the window that appears when you click on More options I had Auto Submit checked (for my blood pressure Captivate variable - v_bloodPressure), even though that checkbox was greyed out. So, on a whim, I unchecked it, because my Captivate variables weren't displaying on the entry of the slide comprising your JS code. Lo and behold it worked!

This has been a very educational experience for me and once again thanks for all your help.

sabre123
Participating Frequently
March 12, 2018

I would split on the "/" character and not use hard numbers then. You'll get an array of whatever is ahead of the slash and whatever is at the end.

Known Participant
March 12, 2018

I'm not sure what that means - do you mean find the / character and assign the characters to the left and right to 2 variables in some way? How is that done?

sabre123
Participating Frequently
March 12, 2018

I have a typo:

var myBp setBp(v_BPSystolic, v_BPDiastolic);

should be:

var myBp = setBp(v_BPSystolic, v_BPDiastolic);

You would have a textbox with $$myBp$$ to show the results on screen.

sabre123
Participating Frequently
March 12, 2018

I used your code and created a two slide test, and I am not getting a zero result for either value. Having said that, it's probably not the best approach for a couple of reasons. For instance, if I have low BP, and input 99/80, you'll get NaN for systolic because you're including the slash in BPSystolic var. Also, 190/100 will truncate the diastolic number.

I don't know if this is for your own knowledge or an actual project, but I think a more efficient way to handle this is by using a function and passing two variables. One for systolic and one for diastolic. As it is, you're depending on the user to format the string properly with no absolutely no validation. You could again setup two TEBs, restrict to numbers (or cast as number), and do something like this in JS:

function setBp(systolic, diastolic)

{

    numSystolic = systolic;

    numDiastolic = diastolic;

    return("Your blood pressure is: " + numSystolic + " / " + numDiastolic);

}

After the user enters their numbers, you store the results in a variable:

var myBp setBp(v_BPSystolic, v_BPDiastolic);

user enters 120 for systolic, 80 for diastolic result:

// Your blood pressure is: 120 / 80

Not sure if this helps or hurts, but it's a lot more efficient.

Known Participant
March 12, 2018

Thanks - I'm just using the project to get a better idea of how to use JS with Captivate and to educate myself. You are no doubt right - I forgot about the two possibilities you mentioned. Your solution makes a lot of sense, but not in this case, because the user has to enter both the systolic and diastolic values in one TEB. But it's a good first lesson in using functions. Once again, thanks for taking the time to help a JS neophyte, with the emphasis on neo.

sabre123
sabre123Correct answer
Participating Frequently
March 8, 2018

Your entry box text is a string object by default.

You've got [at least] two options:

Cast your v_Ht and vWt variables as Number datatypes:

Height = Number(window.cpAPIInterface.getVariableValue('v_Ht'));

Weight = Number(window.cpAPIInterface.getVariableValue('v_Wt'));

or

Change your entry box to use numbers:

Style>More Options>Numbers option

sabre123
Participating Frequently
March 8, 2018

I crossed paths with Lieve's answer...I did a test with what I had done prior to posting and it worked.

Lilybiri
Legend
March 8, 2018

I am not at all a JS expert, but I believe you have to convert the value of the variable which you get from Captivate's TEB's to a number with the function number(). By default any entry in the TEB is a string.

Known Participant
March 8, 2018

Thanks for you quick response. You know I thought that might be the case (although I didn't do that when calculating sales tax and a discount on a product previously and it still worked). But I thought I'd try it again, and assuming I did this correctly (I added these two lines after the first two lines and made sure to change the variable names on the subsequent two lines):

NHeight = Number(Height);

NWeight = Number(Weight);

It still didn't work. It's really weird because I definitely had this working in a previous, similar scenario and I can't figure out what's different here.