Skip to content
idelcano edited this page Dec 21, 2016 · 23 revisions

Kinds of questions and relations

Kinds of tabs

Kinds of question output

Navigation engine


Before start to modify the csv files:

  • In reference to the IDE: Currently the "instant run" does not update the Assets folder so the changes in the csv will not be reflected when reinstalling the application.

Since it takes a long time in clean and build it may be better to disable it for tasks in which csv are modified.

  • In reference to the application: It is necessary to delete the database and restart the application to update the database from the csv.

We have several types of special questions that are identified by the operation of your QuestionRelation, are: Reminders, warnings, counters.

In addition there are two types of parent-child relationship with the same type of operation (1). They are the parent child relationships within the same header within a multiquestion tab, that is invisible to the navigation enigne, and parent-child relationships between questions that the navigation enigne uses.

The Parent-child relationships are explained in database section

Do not confuse with the "id_parent" field of the questions that are not being used.

And remember, the options for a question are related from the answer table. The QuestionOptions table is only used for the question relations.

New kinds of questions:

Name Description
Reminders Reminder relationships are reminders to the user, they do not save any value and you can advance to the next question.
Warnings Warning type relationships alert the user from a wrong option and prevent the user from moving forward, and minValue and maxValue are limited in the QuestionThresholds table.
Counters The counter type relationships are questions that count the number of times the user selects them, exists the possibility of going back without counting the pulsation and can only be advanced if the limit is exceeded. They are limited by the factor field, if this is 0 the limit is infinite.

How create these relations

Counter:

They are built with the following relationships:

QuestionOption table:

Id_question id_option id_match
1 1 1
1 1 2

Match table:

id_match id_question_relation
1 1
2 2

QuestionRelation table:

id_question_relation operation id_question
1 2 2
1 1 2

The Question 2 is the counter question ( with the image, text, and invalid or go back buttons). The Question 1 and option 1 is the parent of the Counter. We have an example of this in the question Invalid, and it is explained with the commented diagram of the initial csv of myanmar. Myanmar initial diagram

  • The counter screen (with invalid or return buttons) needs be a child of the "Question + option".
  • The counter screen should has a Counter relationship with their parent.
  • The counter can be finish a survey if the factor of the parent option is more than 0.

Reminder

We have an example of this in laos.

In the Question(id 2, reason) with each of its option activates the Question (id 14 reminderNotTested) or in case of choosing the option pv + pf or pv in the Question (id 5, result ) it activates (id 12 ReminderHospital).

They are built with the following relationships:

QuestionOption table:

Id_question id_option id_match
1 1 1

Match table:

id_match id_question_relation
1 1

QuestionRelation table:

id_question_relation operation id_question
1 4 2

The id question 1 and option 1 activates the question id 2 type (4, type reminder). Note: The reminder should be the next question in the navigation flow, for example could be a child of Q1 and O1, or a question with higher order position.

Warning

The warning option is a bit different. The warning relation is created in the QuestionThresholds table, and create a limit between the minValue and the maxValue for a QuestionThresholds id_question. The id_question in question_relation is the Warning question.

QuestionThresholds table:

id_question_relation id_question id_match minValue maxValue
1 4 1 10 20

Match table:

id_match id_question_relation
1 1

QuestionRelation table:

id_question_relation operation id_question
1 8 3

This is a example from real laos csv

The question id 4 is age question, if you enter a value between 10 and 20, it will show the question warning id 8 that we found in the QuestionRelation.

Name Description
DROPDOWN_LIST It is a dropdown controlled by a spinner. Require options
INT It is a numeric input controlled by an editext
LONG_TEXT It is a text edittext input controlled by an editext
SHORT_TEXT It is a text input controlled by an editext
DATE It is not implemented
POSITIVE_INT It is a positive numeric input controlled by an editext
NO_ANSWER It is a question without answer(not used?)
RADIO_GROUP_HORIZONTAL It is not implemented
RADIO_GROUP_VERTICAL It is not implemented
DROPDOWN_LIST_DISABLED It is not implemented
IMAGES_2 It is a question with two options represented as images in w horizontal row
IMAGES_4 It is a question with four options represented as images in two rows
IMAGES_6 it is a question with six options represented as images in three rows
PHONE It is a numeric input controlled by an editext, it use the phonemask to filter the numbers
IMAGES_3 It is a question with three options represented in vertical as images
IMAGES_5 It is a question with five options represented as images, two in the first row, two in the second row, and one in the last row
COUNTER It is type of question used as counter. its needs three options, the first is the counter information, code and name are two texts that inform about the counter question. In Laos and Cambodia only code is used but Myanmar is also using name. The second is the counter button text. And the third is the incorrect button text
WARNING It is type of question used as warning when some value was wrong. Needs two options, the first contains the warning information, code and name are two texts that inform about the warning. In Laos and Cambodia only code is used but Myanmar is also using name. The second option contains the option text
REMINDER It is type of question used as reminder when some value was selected. Needs two options, the first contains the reminder information, code and name are two texts that inform about the reminder. In Laos and Cambodia only code is used but Myanmar is also using name. The second contains the option text
DROPDOWN_OU_LIST It is a dropdown controlled by a spinner. The options will be populated from the sdk organisation units
IMAGE_3_NO_DATAELEMENT It is the same of IMAGES_3 but without dataelement
HIDDEN It is a hidden question, their value depending of the matcher question option
SWITCH_BUTTON Its a switch button with two options. One of the two options should be the default option. The default option is a optionAttribute attribute
QUESTION_LABEL It is a question without dataelement, and without options. The question is represented by its image and its Form name
IMAGE_RADIO_GROUP It is a questions with options represented as radio button with image
IMAGE_RADIO_GROUP_NO_DATAELEMENT It is the same of IMAGE_RADIO_GROUP but without dataelement

myanmar initial diagram

or download html and image as zip


Currently the questions are grouped by tab and each tab represents a page or screen.

In the database the questions are grouped by headers, which are grouped by tabs.

Currently we use two types of tab, TAB_DYNAMIC_AUTOMATIC_TAB that is used to represent a single question, and TAB_MULTI_QUESTION that will represent all the questions within the same tab.

A page with many questions will contain many questions with the same header and same tab, being the tab of the type TAB_MULTI_QUESTION. Its parent layout have scroll.

The pages with only One question occupying the entire screen should be a TAB_DYNAMIC_AUTOMATIC_TAB. Its parent layout haven't scroll.


What is the navigation engine?

Is a engine used to navigates a graph constructed by question nodes.

The engine constructs a graph starting from questions and builds all the connections between the questions. It which links the questions to each other according to or according to their order (which determines their siblings) and their parent-child relationships.

Its function is to allow us to navigate from an node to the next or the previous node.

The engine annotate all the especial questions and controls when shown or hidden this nodes.

How works

(graph generated with Code iris)

Class Description
DynamicTabAdapter The DynamicTabAdapter controls the navigation engine using the navigationController.
NavigationController Controller in charge of moving next, previous according to the answers and state of questions.
QuestionCounter POJO that represents a counter question, is never shown but its value is increased with every repetition of a given question + option.
QuestionNode POJO that represents a node in the graph that tells where to go next or back
StatusChecker Base class that helps a QuestionNode to decide whether isEnabled (visitable) or can be seen during a previous/review action.
ReminderStatusChecker Checker that helps to decide if a node is visible or not according to the current survey values. This policy will be attached to those nodes with a Reminder relationship.
WarningStatusChecker Checker that helps to decide if a node is visible or not according to the current survey values. This policy will be attached to those nodes with a Reminder relationship.

When a survey fragment starts, the DynamicTabAdapter creates the NavigationController using the NavigationBuilder buildController method.

  • NavigationBuilder

The NavigationBuilder is in charge of constructing the graph, starting from a questionRoot that is the lowest order question without parents.

Starting from the questionRoot creates all the QuestionNodes executing buildNode() method,

That method: Annotates all the warnings in a map. Subscribes all the question nodes who have warnings Builds the children recursively. Builds the siblings recursively Builds the counters

  • QuestionNode

The QuestionNode constructor builds the status checker and save the StatusChecker for a normal questions, the WarningStatusChecker for the warning questions, and the ReminderStatusChecker for the reminders.

The QuestionNode have some private variables: question(the node question), warnings(list of associated warnings), counters(list of associated warnings), StatusChecker, navigation list (children questions, next).

Question node have parentNode, sibling, and previousSibling too.

Relevant methods: previous() returns find the previousSibling enabled recursively, or the parent if don't have previous sibling or the previous siblings are not enabled.

next(Option) returns the next questionNode active, searching first by question+option(child) and later the nextBySibling next() returns the next sibling, if is not enabled move to the next(null) recursively.

  • NavigationController

After the navigationController was created by the NavigationBuilder, the in charged of the navigationController is the DynamicTabAdapter. The navigationController looks into the questionNodes for find the next QuestionNode or the previous questionNode, or for knows the type of QuestioNode (warning, reminder, counter...) or other information like the StatusChecker.

  • QuestionCounter

The question Counter is used to increase the counter, show the number, or finish the counter if the limit was exceeded.

  • StatusChecker

It's used to know if the questionNode is enabled (to show or ignore that questionNode), and if is visible in review mode.

  • ReminderStatusChecker

Its extends StatusChecer, and overwrite some methods like isEnabled() to know if the Reminder is enabled.

  • WarningStatusChecker

Its extends StatusChecker, and overwrite some methods like isEnabled() to know if the warning is enabled.

Navigation Engine workflow

Question workflow

The graph path starts from a questionRoot, the first level is a group of questions without parent ordered by order field. The questionRoot is the lowest question.

  • The order:

The following questionNode for a questionNode is chosen in this order:

First, the children. If the questionNode have children (if the combination of question+option exists with "parent-child" operation, its have children), the next question node is, the questionNode child with the lowest order.

The exception of this is in the questionRoot questionNode because the questionRoot haven't parents.

Second, the sibling, if the questionNode have more QuestionNodes in the same level (same parent, or without parent in the first level), the sibling is the questionNode with the lowest order starting from the actual questionNode order).

When the questionNode don't have more siblings or children, the selected path into the graph is finished.

The follow JavaDoc contains more information

Navigation Engine Javadoc

Navigation Engine Javadoc

Navigation Engine Uml

(graph generated with simpleUML)