odkodk-xform

Calculate and updated a score according to selected answer


I am new to ODK and XLSForms.

I have several questions and based on the answers, I need to calculate a score.

I have 17 questions, each time a person answer yes, I need to add 2 points into an integer field.

So I have:

type                name  label           appearnce           required

select_one yes_no1  q1    //question here //appearance quick //required yes

...

select_one yes_no17 q17 ...

And here is the score field:

type      name    label

calculate total   Total

This is my first assignment in my job, and can't figure how to calculate and change value according to selected answer.

EDIT

I added a calculation expression but can't know how to get the result because it didn't worked:

if ((${q8} = 'yes' or ${q9} ='yes' or ${q11}='yes'), 2, 0)

So if question 8, 9 or 11 are answered as yes, add 2 points to current value, but the field didn't appeared at all. And still need to add if question 10, 12, 13 and 14 are answered with yes to add 1 point for each.


Solution

  • The simple but tedious way to do this is to create a calculation for each question with an if() statement that sets the calculated value to either 2 or 0. The final result can be obtained by adding up the calculated items.

    The cool way to do this is to do it all in one XPath expression. Basically you want to create a nodeset that contains all 17 questions, filter these to the ones with value 'yes', count the filtered nodeset and multiply by 2. You can do this in XLSForm, but Im not sure if you can use the ${node} shorthand.

    You'd have to put all your question in a group (doesn't need a group label) after which you can do something like:

    count(${grp}/*[text() = 'yes']) * 2

    or without ${node} shortcut (check the XForm for the correct path):

    count(/myform/grp/*[text() = 'yes']) * 2

    I'm not sure if the use of text() will pass ODK Validate though. If not there is probably an expression that will pass and does the same. (However, the above syntax would work in Enketo).